Index: .gitignore
===================================================================
--- .gitignore	(revision c878693123930f0906703462cf2807430679517e)
+++ .gitignore	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -24,4 +24,5 @@
 autotool/
 boot/arch/arm32/_link.ld
+boot/arch/arm64/_link.ld
 boot/arch/ia64/_link.ld
 boot/arch/mips32/_link.ld
@@ -49,4 +50,5 @@
 kernel/arch/amd64/_link.ld
 kernel/arch/arm32/_link.ld
+kernel/arch/arm64/_link.ld
 kernel/arch/ia32/_link.ld
 kernel/arch/ia64/_link.ld
@@ -90,5 +92,4 @@
 uspace/app/bithenge/bithenge
 uspace/app/blkdump/blkdump
-uspace/app/bnchmark/bnchmark
 uspace/app/contacts/contacts
 uspace/app/corecfg/corecfg
@@ -107,7 +108,9 @@
 uspace/app/getterm/getterm
 uspace/app/gunzip/gunzip
+uspace/app/hbench/hbench
 uspace/app/inet/inet
 uspace/app/init/init
 uspace/app/init/init.gz
+uspace/app/lprint/lprint
 uspace/app/kill/kill
 uspace/app/killall/killall
@@ -129,10 +132,8 @@
 uspace/app/nic/nic
 uspace/app/nterm/nterm
-uspace/app/perf/perf
+uspace/app/pci/pci
 uspace/app/ping/ping
 uspace/app/ping6/ping6
 uspace/app/pkg/pkg
-uspace/app/rcubench/rcubench
-uspace/app/rcutest/rcutest
 uspace/app/redir/redir
 uspace/app/sbi/sbi
@@ -173,5 +174,4 @@
 uspace/dist/app/bithenge
 uspace/dist/app/blkdump
-uspace/dist/app/bnchmark
 uspace/dist/app/corecfg
 uspace/dist/app/cpptest
@@ -211,6 +211,4 @@
 uspace/dist/app/ping6
 uspace/dist/app/pkg
-uspace/dist/app/rcubench
-uspace/dist/app/rcutest
 uspace/dist/app/redir
 uspace/dist/app/sbi
@@ -314,4 +312,6 @@
 uspace/drv/char/msim-con/msim-con
 uspace/drv/char/ns8250/ns8250
+uspace/drv/char/pc-lpt/pc-lpt
+uspace/drv/char/pl011/pl011
 uspace/drv/char/pl050/pl050
 uspace/drv/char/ps2mouse/ps2mouse
@@ -327,4 +327,5 @@
 uspace/drv/hid/xtkbd/xtkbd
 uspace/drv/intctl/apic/apic
+uspace/drv/intctl/gicv2/gicv2
 uspace/drv/intctl/i8259/i8259
 uspace/drv/intctl/icp-ic/icp-ic
@@ -337,4 +338,5 @@
 uspace/drv/nic/virtio-net/virtio-net
 uspace/drv/platform/amdm37x/amdm37x
+uspace/drv/platform/arm64virt/arm64virt
 uspace/drv/platform/icp/icp
 uspace/drv/platform/mac/mac
@@ -352,40 +354,4 @@
 uspace/drv/time/cmos-rtc/cmos-rtc
 uspace/export
-uspace/lib/c/arch/abs32le/_link-dlexe.ld
-uspace/lib/c/arch/abs32le/_link-loader.ld
-uspace/lib/c/arch/abs32le/_link-shlib.ld
-uspace/lib/c/arch/abs32le/_link.ld
-uspace/lib/c/arch/amd64/_link-dlexe.ld
-uspace/lib/c/arch/amd64/_link-loader.ld
-uspace/lib/c/arch/amd64/_link-shlib.ld
-uspace/lib/c/arch/amd64/_link.ld
-uspace/lib/c/arch/arm32/_link-dlexe.ld
-uspace/lib/c/arch/arm32/_link-loader.ld
-uspace/lib/c/arch/arm32/_link-shlib.ld
-uspace/lib/c/arch/arm32/_link.ld
-uspace/lib/c/arch/ia32/_link-dlexe.ld
-uspace/lib/c/arch/ia32/_link-loader.ld
-uspace/lib/c/arch/ia32/_link-shlib.ld
-uspace/lib/c/arch/ia32/_link.ld
-uspace/lib/c/arch/ia64/_link-dlexe.ld
-uspace/lib/c/arch/ia64/_link-loader.ld
-uspace/lib/c/arch/ia64/_link-shlib.ld
-uspace/lib/c/arch/ia64/_link.ld
-uspace/lib/c/arch/mips32/_link-dlexe.ld
-uspace/lib/c/arch/mips32/_link-loader.ld
-uspace/lib/c/arch/mips32/_link-shlib.ld
-uspace/lib/c/arch/mips32/_link.ld
-uspace/lib/c/arch/mips32eb/_link-dlexe.ld
-uspace/lib/c/arch/mips32eb/_link-loader.ld
-uspace/lib/c/arch/mips32eb/_link-shlib.ld
-uspace/lib/c/arch/mips32eb/_link.ld
-uspace/lib/c/arch/ppc32/_link-dlexe.ld
-uspace/lib/c/arch/ppc32/_link-loader.ld
-uspace/lib/c/arch/ppc32/_link-shlib.ld
-uspace/lib/c/arch/ppc32/_link.ld
-uspace/lib/c/arch/sparc64/_link-dlexe.ld
-uspace/lib/c/arch/sparc64/_link-loader.ld
-uspace/lib/c/arch/sparc64/_link-shlib.ld
-uspace/lib/c/arch/sparc64/_link.ld
 uspace/lib/c/test-libc
 uspace/lib/label/test-liblabel
Index: .travis.yml
===================================================================
--- .travis.yml	(revision c878693123930f0906703462cf2807430679517e)
+++ .travis.yml	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,5 +35,5 @@
 
 language: c
-dist: trusty
+dist: xenial
 sudo: required
 env:
Index: HelenOS.config
===================================================================
--- HelenOS.config	(revision c878693123930f0906703462cf2807430679517e)
+++ HelenOS.config	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,4 +34,5 @@
 @ "amd64" AMD64/EM64T 64-bit (PC)
 @ "arm32" ARM 32-bit
+@ "arm64" ARM 64-bit (AArch64)
 @ "ia32" IA-32 32-bit (PC)
 @ "ia64" IA-64 64-bit
@@ -65,4 +66,8 @@
 ! [PLATFORM=arm32] MACHINE (choice)
 
+% Machine type
+@ "virt" QEMU virt
+! [PLATFORM=arm64] MACHINE (choice)
+
 % CPU type
 @ "pentium4" Pentium 4
@@ -160,4 +165,8 @@
 
 % Kernel architecture
+@ "arm64"
+! [PLATFORM=arm64] KARCH (choice)
+
+% Kernel architecture
 @ "ia32"
 ! [PLATFORM=ia32] KARCH (choice)
@@ -207,4 +216,8 @@
 
 % User space architecture
+@ "arm64"
+! [PLATFORM=arm64] UARCH (choice)
+
+% User space architecture
 @ "ia32"
 ! [PLATFORM=ia32|PLATFORM=ia32xen] UARCH (choice)
@@ -252,4 +265,8 @@
 @ "arm32"
 ! [PLATFORM=arm32] BARCH (choice)
+
+% Boot architecture
+@ "arm64"
+! [PLATFORM=arm64] BARCH (choice)
 
 % Boot architecture
@@ -334,5 +351,5 @@
 
 % IOMAP dummy support
-! [PLATFORM=abs32le|PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=riscv64|PLATFORM=sparc64] CONFIG_IOMAP_DUMMY (y)
+! [PLATFORM=abs32le|PLATFORM=arm32|PLATFORM=arm64|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=riscv64|PLATFORM=sparc64] CONFIG_IOMAP_DUMMY (y)
 
 % ACPI support
@@ -340,5 +357,5 @@
 
 % Hierarchical page tables support
-! [PLATFORM=abs32le|PLATFORM=ia32|PLATFORM=amd64|PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=riscv64] CONFIG_PAGE_PT (y)
+! [PLATFORM=abs32le|PLATFORM=ia32|PLATFORM=amd64|PLATFORM=arm32|PLATFORM=arm64|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=riscv64] CONFIG_PAGE_PT (y)
 
 % Page hash table support
@@ -349,8 +366,8 @@
 
 % ASID support
-! [PLATFORM=ia64|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_ASID (y)
+! [PLATFORM=arm64|PLATFORM=ia64|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_ASID (y)
 
 % ASID FIFO support
-! [PLATFORM=ia64|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_ASID_FIFO (y)
+! [PLATFORM=arm64|PLATFORM=ia64|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_ASID_FIFO (y)
 
 % OpenFirmware tree support
@@ -364,5 +381,5 @@
 
 % FPU support
-! [PLATFORM=ia32|PLATFORM=amd64|PLATFORM=ia64|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_FPU (y)
+! [PLATFORM=ia32|PLATFORM=amd64|PLATFORM=arm64|PLATFORM=ia64|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_FPU (y)
 
 ## ARMv7 made FPU hardware compulsory
@@ -377,5 +394,5 @@
 
 % Support for SMP
-! [(PLATFORM=ia32&PROCESSOR!=athlon_xp)|PLATFORM=amd64|PLATFORM=sparc64|PLATFORM=ia64|(PLATFORM=mips32&MACHINE=msim)|PLATFORM=abs32le] CONFIG_SMP (y/n)
+! [(PLATFORM=ia32&PROCESSOR!=athlon_xp)|PLATFORM=amd64|PLATFORM=arm64|PLATFORM=sparc64|PLATFORM=ia64|(PLATFORM=mips32&MACHINE=msim)|PLATFORM=abs32le] CONFIG_SMP (y/n)
 
 % Debug build
@@ -406,4 +423,7 @@
 ! [PLATFORM=ia64&MACHINE!=ski] CONFIG_IOSAPIC (y/n)
 
+% Support for Intel i8259 PIC
+! [PLATFORM=ia32|PLATFORM=amd64|(PLATFORM=mips32&MACHINE=bmalta)|(PLATFORM=mips32&MACHINE=lmalta)] CONFIG_I8259 (y)
+
 % Virtually indexed D-cache support
 ! [PLATFORM=sparc64] CONFIG_VIRT_IDX_DCACHE (y/n)
@@ -439,5 +459,5 @@
 % Input device class
 @ "generic" Keyboard or serial line
-! [PLATFORM=arm32&MACHINE=integratorcp] CONFIG_HID_IN (choice)
+! [(PLATFORM=arm32&MACHINE=integratorcp)|PLATFORM=arm64] CONFIG_HID_IN (choice)
 
 % Input device class
@@ -455,5 +475,5 @@
 % Output device class
 @ "generic" Monitor or serial line
-! [PLATFORM=arm32&(MACHINE=gta02|MACHINE=integratorcp|MACHINE=beagleboardxm|MACHINE=beaglebone|MACHINE=raspberrypi)] CONFIG_HID_OUT (choice)
+! [(PLATFORM=arm32&(MACHINE=gta02|MACHINE=integratorcp|MACHINE=beagleboardxm|MACHINE=beaglebone|MACHINE=raspberrypi))|PLATFORM=arm64] CONFIG_HID_OUT (choice)
 
 % Output device class
@@ -486,6 +506,12 @@
 ! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=serial)&PLATFORM=ia64&MACHINE=i460GX] CONFIG_NS16550 (y/n)
 
+% Support for NS16550 controller
+! [CONFIG_HID_IN=generic&PLATFORM=mips32&(MACHINE=lmalta|MACHINE=bmalta)] CONFIG_NS16550 (y)
+
 % Support for PL011 UART
-! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&PLATFORM=arm32&(MACHINE=integratorcp|MACHINE=raspberrypi)] CONFIG_PL011_UART (y/n)
+! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&(PLATFORM=arm32&(MACHINE=integratorcp|MACHINE=raspberrypi))] CONFIG_PL011_UART (y/n)
+
+% Support for PL011 UART
+! [CONFIG_HID_OUT=generic|(PLATFORM=arm64&MACHINE=virt)] CONFIG_PL011_UART (y)
 
 % Support for NS16550 controller (kernel console)
@@ -498,4 +524,7 @@
 ! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&(PLATFORM=ia32|PLATFORM=amd64)&CONFIG_NS16550_KCON=y] CONFIG_NS16550_OUT (y)
 
+% Use NS16550 controller as dummy serial output (kernel console)
+! [CONFIG_HID_OUT=generic&PLATFORM=mips32&(MACHINE=lmalta|MACHINE=bmalta)] CONFIG_NS16550_OUT (y)
+
 % Support for Samsung S3C24XX on-chip UART
 ! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&PLATFORM=arm32&MACHINE=gta02] CONFIG_S3C24XX_UART (y/n)
@@ -513,4 +542,7 @@
 ! [PLATFORM=arm32&MACHINE=raspberrypi] CONFIG_BCM2835_MAILBOX (y/n)
 
+% Support for ARM GICv2
+! [PLATFORM=arm64&MACHINE=virt] CONFIG_GICV2 (y)
+
 % Support for i8042 controller
 ! [CONFIG_PC_KBD=y] CONFIG_I8042 (y)
@@ -522,4 +554,7 @@
 ! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&PLATFORM=sparc64&MACHINE=generic&CONFIG_NS16550=y] CONFIG_SUN_KBD (y)
 
+% Sun serial console support
+! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&PLATFORM=sparc64&MACHINE=generic&CONFIG_NS16550=y] CONFIG_SUN_TTY (y)
+
 % Macintosh ADB keyboard support
 ! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&PLATFORM=ppc32&(CONFIG_VIA_CUDA=y)] CONFIG_MAC_KBD (y)
@@ -532,5 +567,8 @@
 
 % Serial line input module
-! [CONFIG_DSRLNIN=y|(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)|(PLATFORM=ia32&CONFIG_NS16550=y)|(PLATFORM=amd64&CONFIG_NS16550=y)] CONFIG_SRLN (y)
+! [CONFIG_DSRLNIN=y|(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=arm64&CONFIG_PL011_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)|(PLATFORM=ia32&CONFIG_NS16550=y)|(PLATFORM=amd64&CONFIG_NS16550=y)|(PLATFORM=mips32&CONFIG_NS16550=y)|(PLATFORM=sparc64&CONFIG_SUN_TTY=y)] CONFIG_SRLN (y)
+
+% L4Re uvmm print hypercall support
+! [PLATFORM=amd64] CONFIG_L4RE_UVMM_EARLY_PRINT (n/y)
 
 % EGA support
@@ -578,6 +616,6 @@
 
 % Dynamic linking support
-! [PLATFORM=ia32] CONFIG_RTLD (n/y)
-! [PLATFORM=abs32le|PLATFORM=amd64|PLATFORM=arm32|PLATFORM=ia64|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=riscv64|PLATFORM=sparc64] CONFIG_RTLD (n)
+! [PLATFORM=amd64|PLATFORM=arm32|PLATFORM=ia32|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_RTLD (y/n)
+! [PLATFORM=abs32le|PLATFORM=arm64|PLATFORM=ia64|PLATFORM=mips32|PLATFORM=riscv64] CONFIG_RTLD (n)
 
 % Build shared libraries
@@ -642,4 +680,8 @@
 ! [PLATFORM=ia32|PLATFORM=amd64] GRUB_ARCH (choice)
 
+% GRUB boot loader architecture
+@ "efi" GRUB for UEFI
+! [PLATFORM=arm64&MACHINE=virt] GRUB_ARCH (choice)
+
 % uImage OS type
 @ "2" NetBSD stage 2 boot loader
Index: README.md
===================================================================
--- README.md	(revision c878693123930f0906703462cf2807430679517e)
+++ README.md	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -9,4 +9,6 @@
 directly harm others. HelenOS is therefore flexible, modular,
 extensible, fault tolerant and easy to understand.
+
+![screenshot](http://www.helenos.org/raw-attachment/wiki/Screenshots/screenshot.png "Screenshot")
 
 HelenOS aims to be compatible with the C11 and C++14 standards, but does not
@@ -24,5 +26,5 @@
 ## Portability
 
-HelenOS runs on seven different processor architectures and machines ranging
+HelenOS runs on eight different processor architectures and machines ranging
 from embedded ARM devices and single-board computers through multicore 32-bit
 and 64-bit desktop PCs to 64-bit Itanium and SPARC rack-mount servers.
@@ -52,5 +54,5 @@
 
 ```
-$ sudo apt-get install build-essential libgmp-dev libmpfr-dev ppl-dev libmpc-dev zlib1g-dev texinfo libtinfo-dev xutils-dev
+$ sudo apt-get install build-essential libgmp-dev libmpfr-dev ppl-dev libmpc-dev zlib1g-dev texinfo libtinfo-dev xutils-dev flex bison
 ```
 
@@ -59,5 +61,5 @@
 ```
 # sudo dnf group install 'Development Tools'
-# sudo dnf install wget texinfo libmpc-devel mpfr-devel gmp-devel PyYAML genisoimage
+# sudo dnf install wget texinfo libmpc-devel mpfr-devel gmp-devel PyYAML genisoimage flex bison
 ```
 In case the toolchain script won't work no matter how hard you try, let us know.
Index: abi/arch/abs32le/include/abi/arch/elf.h
===================================================================
--- abi/arch/abs32le/include/abi/arch/elf.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/arch/abs32le/include/abi/arch/elf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef ABI_abs32le_ELF_H_
-#define ABI_abs32le_ELF_H_
+#ifndef _ABI_abs32le_ELF_H_
+#define _ABI_abs32le_ELF_H_
 
 #define ELF_MACHINE        EM_NO
Index: abi/arch/amd64/include/abi/arch/elf.h
===================================================================
--- abi/arch/amd64/include/abi/arch/elf.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/arch/amd64/include/abi/arch/elf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef ABI_amd64_ELF_H_
-#define ABI_amd64_ELF_H_
+#ifndef _ABI_amd64_ELF_H_
+#define _ABI_amd64_ELF_H_
 
 #define ELF_MACHINE        EM_X86_64
Index: abi/arch/arm32/include/abi/arch/elf.h
===================================================================
--- abi/arch/arm32/include/abi/arch/elf.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/arch/arm32/include/abi/arch/elf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef ABI_arm32_ELF_H_
-#define ABI_arm32_ELF_H_
+#ifndef _ABI_arm32_ELF_H_
+#define _ABI_arm32_ELF_H_
 
 #define ELF_MACHINE  EM_ARM
Index: abi/arch/arm64/include/abi/arch/elf.h
===================================================================
--- abi/arch/arm64/include/abi/arch/elf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ abi/arch/arm64/include/abi/arch/elf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 abi_arm64
+ * @{
+ */
+/** @file
+ * @brief ARM64 ELF constants.
+ */
+
+#ifndef _ABI_arm64_ELF_H_
+#define _ABI_arm64_ELF_H_
+
+#define ELF_MACHINE        EM_AARCH64
+#define ELF_DATA_ENCODING  ELFDATA2LSB
+#define ELF_CLASS          ELFCLASS64
+
+#define R_AARCH64_RELATIVE  1027
+
+#endif
+
+/** @}
+ */
Index: abi/arch/ia32/include/abi/arch/elf.h
===================================================================
--- abi/arch/ia32/include/abi/arch/elf.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/arch/ia32/include/abi/arch/elf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef ABI_ia32_ELF_H_
-#define ABI_ia32_ELF_H_
+#ifndef _ABI_ia32_ELF_H_
+#define _ABI_ia32_ELF_H_
 
 #define ELF_MACHINE        EM_386
Index: abi/arch/ia64/include/abi/arch/elf.h
===================================================================
--- abi/arch/ia64/include/abi/arch/elf.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/arch/ia64/include/abi/arch/elf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef ABI_ia64_ELF_H_
-#define ABI_ia64_ELF_H_
+#ifndef _ABI_ia64_ELF_H_
+#define _ABI_ia64_ELF_H_
 
 #define ELF_MACHINE        EM_IA_64
Index: abi/arch/mips32/include/abi/arch/elf.h
===================================================================
--- abi/arch/mips32/include/abi/arch/elf.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/arch/mips32/include/abi/arch/elf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef ABI_mips32_ELF_H_
-#define ABI_mips32_ELF_H_
+#ifndef _ABI_mips32_ELF_H_
+#define _ABI_mips32_ELF_H_
 
 #define ELF_MACHINE  EM_MIPS
Index: abi/arch/ppc32/include/abi/arch/elf.h
===================================================================
--- abi/arch/ppc32/include/abi/arch/elf.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/arch/ppc32/include/abi/arch/elf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef ABI_ppc32_ELF_H_
-#define ABI_ppc32_ELF_H_
+#ifndef _ABI_ppc32_ELF_H_
+#define _ABI_ppc32_ELF_H_
 
 #define ELF_MACHINE        EM_PPC
Index: abi/arch/riscv64/include/abi/arch/elf.h
===================================================================
--- abi/arch/riscv64/include/abi/arch/elf.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/arch/riscv64/include/abi/arch/elf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef ABI_riscv64_ELF_H_
-#define ABI_riscv64_ELF_H_
+#ifndef _ABI_riscv64_ELF_H_
+#define _ABI_riscv64_ELF_H_
 
 #define ELF_MACHINE        EM_RISCV
Index: abi/arch/sparc64/include/abi/arch/elf.h
===================================================================
--- abi/arch/sparc64/include/abi/arch/elf.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/arch/sparc64/include/abi/arch/elf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef ABI_sparc64_ELF_H_
-#define ABI_sparc64_ELF_H_
+#ifndef _ABI_sparc64_ELF_H_
+#define _ABI_sparc64_ELF_H_
 
 #define ELF_MACHINE        EM_SPARCV9
Index: abi/doc/doxygroups.h
===================================================================
--- abi/doc/doxygroups.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/doc/doxygroups.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,4 +30,9 @@
 
 /**
+ * @defgroup abi_arm64 arm64
+ * @ingroup abi
+ */
+
+/**
  * @defgroup abi_ia32 ia32
  * @ingroup abi
@@ -50,5 +55,5 @@
 
 /**
- * @defgroup abi_riscv5 riscv5
+ * @defgroup abi_riscv64 riscv64
  * @ingroup abi
  */
Index: abi/include/_bits/NULL.h
===================================================================
--- abi/include/_bits/NULL.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/_bits/NULL.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,8 +37,4 @@
 /** @file
  * Definition of constant NULL.
- *
- * This definition is designed to work in both C and C++, and use
- * the special constant `nullptr` in C++11 and above.
- * Including this file is preferrable to defining the constant separately.
  */
 
@@ -46,15 +42,6 @@
 #define _BITS_NULL_H_
 
-#ifndef NULL
-
-#if __cplusplus >= 201103L
-#define NULL  nullptr
-#elif defined(__cplusplus)
-#define NULL  0L
-#else
-#define NULL  ((void *) 0)
-#endif
-
-#endif
+#define __need_NULL
+#include <stddef.h>
 
 #endif
Index: abi/include/_bits/__opaque_handle.h
===================================================================
--- abi/include/_bits/__opaque_handle.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ abi/include/_bits/__opaque_handle.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017 CZ.NIC, z.s.p.o.
+ * 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.
+ */
+
+/*
+ * Authors:
+ *	Jiří Zárevúcky (jzr) <zarevucky.jiri@gmail.com>
+ */
+
+/** @addtogroup bits
+ * @{
+ */
+
+#ifndef _BITS_OPAQUE_HANDLE_H_
+#define _BITS_OPAQUE_HANDLE_H_
+
+#define __opaque_handle(__name) typedef struct __opaque_##__name *__name
+
+#endif
+
+/** @}
+ */
Index: abi/include/_bits/decls.h
===================================================================
--- abi/include/_bits/decls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ abi/include/_bits/decls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2019 Jiří Zárevúcky
+ * 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 bits
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _BITS_DECLS_H_
+#define _BITS_DECLS_H_
+
+#ifdef __cplusplus
+
+#define __HELENOS_DECLS_BEGIN \
+	namespace helenos { \
+	extern "C" {
+
+#define __HELENOS_DECLS_END \
+	} \
+	}
+
+#define __C_DECLS_BEGIN \
+	extern "C" {
+
+#define __C_DECLS_END \
+	}
+
+#else  /* !__cplusplus */
+
+#define __HELENOS_DECLS_BEGIN
+#define __HELENOS_DECLS_END
+#define __C_DECLS_BEGIN
+#define __C_DECLS_END
+
+#endif  /* __cplusplus */
+
+#endif
+
+/** @}
+ */
Index: abi/include/_bits/errno.h
===================================================================
--- abi/include/_bits/errno.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/_bits/errno.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -41,14 +41,20 @@
 #define _BITS_ERRNO_H_
 
+#include <_bits/native.h>
+#include <_bits/decls.h>
+
 #ifdef __OPAQUE_ERRNO__
-#include <_bits/opaque_handle.h>
+#include <_bits/__opaque_handle.h>
 
-opaque_handle(errno_t);
+__HELENOS_DECLS_BEGIN;
+__opaque_handle(errno_t);
 typedef errno_t sys_errno_t;
+__HELENOS_DECLS_END;
+
 #define __errno_t(val) ((errno_t) val)
 
 #else
 
-#include <_bits/native.h>
+__HELENOS_DECLS_BEGIN;
 
 /**
@@ -65,4 +71,6 @@
 typedef sysarg_t sys_errno_t;
 
+__HELENOS_DECLS_END;
+
 /**
  * A C++-style "cast" to `errno_t`.
Index: abi/include/_bits/native.h
===================================================================
--- abi/include/_bits/native.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/_bits/native.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -47,4 +47,7 @@
 
 #include <inttypes.h>
+#include <_bits/decls.h>
+
+__HELENOS_DECLS_BEGIN;
 
 typedef uintptr_t pfn_t;
@@ -53,7 +56,5 @@
 typedef intptr_t  native_t;
 
-#define PRIdn  PRIdPTR  /**< Format for native_t. */
-#define PRIun  PRIuPTR  /**< Format for sysarg_t. */
-#define PRIxn  PRIxPTR  /**< Format for hexadecimal sysarg_t. */
+__HELENOS_DECLS_END;
 
 #endif
Index: abi/include/_bits/off64_t.h
===================================================================
--- abi/include/_bits/off64_t.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ abi/include/_bits/off64_t.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019 Jiří Zárevúcky
+ * 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 bits
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _BITS_OFF64_T_H_
+#define _BITS_OFF64_T_H_
+
+#include <stdint.h>
+#include <_bits/decls.h>
+
+__C_DECLS_BEGIN;
+typedef int64_t off64_t;
+__C_DECLS_END;
+
+#endif
+
+/** @}
+ */
Index: i/include/_bits/opaque_handle.h
===================================================================
--- abi/include/_bits/opaque_handle.h	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,46 +1,0 @@
-/*
- * Copyright (c) 2017 CZ.NIC, z.s.p.o.
- * 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.
- */
-
-/*
- * Authors:
- *	Jiří Zárevúcky (jzr) <zarevucky.jiri@gmail.com>
- */
-
-/** @addtogroup bits
- * @{
- */
-
-#ifndef _BITS_OPAQUE_HANDLE_H_
-#define _BITS_OPAQUE_HANDLE_H_
-
-#define opaque_handle(__name) typedef struct __opaque_##__name *__name
-
-#endif
-
-/** @}
- */
Index: abi/include/_bits/ssize_t.h
===================================================================
--- abi/include/_bits/ssize_t.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/_bits/ssize_t.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -42,9 +42,9 @@
 
 #include <stdint.h>
+#include <_bits/decls.h>
 
+__C_DECLS_BEGIN;
 typedef intptr_t ssize_t;
-
-#define SSIZE_MIN  INTPTR_MIN
-#define SSIZE_MAX  INTPTR_MAX
+__C_DECLS_END;
 
 #endif
Index: abi/include/abi/asmtool.h
===================================================================
--- abi/include/abi/asmtool.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/abi/asmtool.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef ABI_ASMTOOL_H_
-#define ABI_ASMTOOL_H_
+#ifndef _ABI_ASMTOOL_H_
+#define _ABI_ASMTOOL_H_
 
 #define SYMBOL(sym) \
@@ -56,4 +56,10 @@
 	SYMBOL_END(func)
 
+#ifdef __PIC__
+#define FUNCTION_REF(func) func@PLT
+#else
+#define FUNCTION_REF(func) func
+#endif
+
 #endif
 
Index: abi/include/abi/cap.h
===================================================================
--- abi/include/abi/cap.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/abi/cap.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,11 +33,13 @@
  */
 
-#ifndef ABI_CAP_H_
-#define ABI_CAP_H_
+#ifndef _ABI_CAP_H_
+#define _ABI_CAP_H_
 
-#define CAP_NIL  0
+#include <stdbool.h>
+#include <stdint.h>
 
-#define CAP_HANDLE_VALID(handle)  ((handle) != CAP_NIL)
-#define CAP_HANDLE_RAW(handle)    ((intptr_t) (handle))
+enum {
+	CAP_NIL = 0,
+};
 
 typedef void *cap_handle_t;
@@ -55,4 +57,14 @@
 } *cap_waitq_handle_t;
 
+static inline bool cap_handle_valid(cap_handle_t handle)
+{
+	return handle != CAP_NIL;
+}
+
+static inline intptr_t cap_handle_raw(cap_handle_t handle)
+{
+	return (intptr_t) handle;
+}
+
 #endif
 
Index: abi/include/abi/ddi/arg.h
===================================================================
--- abi/include/abi/ddi/arg.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/abi/ddi/arg.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,10 +33,12 @@
  */
 
-#ifndef ABI_DDI_ARG_H_
-#define ABI_DDI_ARG_H_
+#ifndef _ABI_DDI_ARG_H_
+#define _ABI_DDI_ARG_H_
 
 #include <stdint.h>
 
-#define DMAMEM_FLAGS_ANONYMOUS  0x01
+enum {
+	DMAMEM_FLAGS_ANONYMOUS = 0x01,
+};
 
 /** Structure encapsulating arguments for SYS_PHYSMEM_MAP syscall. */
Index: abi/include/abi/ddi/irq.h
===================================================================
--- abi/include/abi/ddi/irq.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/abi/ddi/irq.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef ABI_DDI_IRQ_H_
-#define ABI_DDI_IRQ_H_
+#ifndef _ABI_DDI_IRQ_H_
+#define _ABI_DDI_IRQ_H_
 
 #include <stdint.h>
Index: abi/include/abi/elf.h
===================================================================
--- abi/include/abi/elf.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/abi/elf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef ABI_ELF_H_
-#define ABI_ELF_H_
+#ifndef _ABI_ELF_H_
+#define _ABI_ELF_H_
 
 #include <stdint.h>
@@ -42,152 +42,259 @@
  * Current ELF version
  */
-#define EV_CURRENT  1
+enum {
+	EV_CURRENT = 1,
+};
 
 /**
  * ELF types
  */
-#define ET_NONE    0       /* No type */
-#define ET_REL     1       /* Relocatable file */
-#define ET_EXEC    2       /* Executable */
-#define ET_DYN     3       /* Shared object */
-#define ET_CORE    4       /* Core */
-#define ET_LOPROC  0xff00  /* Processor specific */
-#define ET_HIPROC  0xffff  /* Processor specific */
+enum elf_type {
+	ET_NONE   = 0,       /* No type */
+	ET_REL    = 1,       /* Relocatable file */
+	ET_EXEC   = 2,       /* Executable */
+	ET_DYN    = 3,       /* Shared object */
+	ET_CORE   = 4,       /* Core */
+};
+
+enum {
+	ET_LOPROC = 0xff00,  /* Lowest processor specific */
+	ET_HIPROC = 0xffff,  /* Highest processor specific */
+};
 
 /**
  * ELF machine types
  */
-#define EM_NO           0    /* No machine */
-#define EM_SPARC        2    /* SPARC */
-#define EM_386          3    /* i386 */
-#define EM_MIPS         8    /* MIPS RS3000 */
-#define EM_MIPS_RS3_LE  10   /* MIPS RS3000 LE */
-#define EM_PPC          20   /* PPC32 */
-#define EM_PPC64        21   /* PPC64 */
-#define EM_ARM          40   /* ARM */
-#define EM_SPARCV9      43   /* SPARC64 */
-#define EM_IA_64        50   /* IA-64 */
-#define EM_X86_64       62   /* AMD64/EMT64 */
-#define EM_RISCV        243  /* RISC-V */
+enum elf_machine {
+	EM_NO          = 0,    /* No machine */
+	EM_SPARC       = 2,    /* SPARC */
+	EM_386         = 3,    /* i386 */
+	EM_MIPS        = 8,    /* MIPS RS3000 */
+	EM_MIPS_RS3_LE = 10,   /* MIPS RS3000 LE */
+	EM_PPC         = 20,   /* PPC32 */
+	EM_PPC64       = 21,   /* PPC64 */
+	EM_ARM         = 40,   /* ARM */
+	EM_SPARCV9     = 43,   /* SPARC64 */
+	EM_IA_64       = 50,   /* IA-64 */
+	EM_X86_64      = 62,   /* AMD64/EMT64 */
+	EM_AARCH64     = 183,  /* ARM 64-bit architecture */
+	EM_RISCV       = 243,  /* RISC-V */
+};
 
 /**
  * ELF identification indexes
  */
-#define EI_MAG0        0
-#define EI_MAG1        1
-#define EI_MAG2        2
-#define EI_MAG3        3
-#define EI_CLASS       4   /* File class */
-#define EI_DATA        5   /* Data encoding */
-#define EI_VERSION     6   /* File version */
-#define EI_OSABI       7
-#define EI_ABIVERSION  8
-#define EI_PAD         9   /* Start of padding bytes */
-#define EI_NIDENT      16  /* ELF identification table size */
+enum {
+	EI_MAG0       = 0,
+	EI_MAG1       = 1,
+	EI_MAG2       = 2,
+	EI_MAG3       = 3,
+	EI_CLASS      = 4,   /* File class */
+	EI_DATA       = 5,   /* Data encoding */
+	EI_VERSION    = 6,   /* File version */
+	EI_OSABI      = 7,
+	EI_ABIVERSION = 8,
+	EI_PAD        = 9,   /* Start of padding bytes */
+	EI_NIDENT     = 16,  /* ELF identification table size */
+};
 
 /**
  * ELF magic number
  */
-#define ELFMAG0  0x7f
-#define ELFMAG1  'E'
-#define ELFMAG2  'L'
-#define ELFMAG3  'F'
+enum {
+	ELFMAG0 = 0x7f,
+	ELFMAG1 = 'E',
+	ELFMAG2 = 'L',
+	ELFMAG3 = 'F',
+};
 
 /**
  * ELF file classes
  */
-#define ELFCLASSNONE  0
-#define ELFCLASS32    1
-#define ELFCLASS64    2
+enum elf_class {
+	ELFCLASSNONE = 0,
+	ELFCLASS32   = 1,
+	ELFCLASS64   = 2,
+};
 
 /**
  * ELF data encoding types
  */
-#define ELFDATANONE  0
-#define ELFDATA2LSB  1  /* Least significant byte first (little endian) */
-#define ELFDATA2MSB  2  /* Most signigicant byte first (big endian) */
+enum elf_data_encoding {
+	ELFDATANONE = 0,
+	ELFDATA2LSB = 1,  /* Least significant byte first (little endian) */
+	ELFDATA2MSB = 2,  /* Most signigicant byte first (big endian) */
+};
 
 /**
  * ELF section types
  */
-#define SHT_NULL      0
-#define SHT_PROGBITS  1
-#define SHT_SYMTAB    2
-#define SHT_STRTAB    3
-#define SHT_RELA      4
-#define SHT_HASH      5
-#define SHT_DYNAMIC   6
-#define SHT_NOTE      7
-#define SHT_NOBITS    8
-#define SHT_REL       9
-#define SHT_SHLIB     10
-#define SHT_DYNSYM    11
-#define SHT_LOOS      0x60000000
-#define SHT_HIOS      0x6fffffff
-#define SHT_LOPROC    0x70000000
-#define SHT_HIPROC    0x7fffffff
-#define SHT_LOUSER    0x80000000
-#define SHT_HIUSER    0xffffffff
+enum elf_section_type {
+	SHT_NULL     = 0,
+	SHT_PROGBITS = 1,
+	SHT_SYMTAB   = 2,
+	SHT_STRTAB   = 3,
+	SHT_RELA     = 4,
+	SHT_HASH     = 5,
+	SHT_DYNAMIC  = 6,
+	SHT_NOTE     = 7,
+	SHT_NOBITS   = 8,
+	SHT_REL      = 9,
+	SHT_SHLIB    = 10,
+	SHT_DYNSYM   = 11,
+};
+
+enum {
+	SHT_LOOS     = 0x60000000,
+	SHT_HIOS     = 0x6fffffff,
+	SHT_LOPROC   = 0x70000000,
+	SHT_HIPROC   = 0x7fffffff,
+	SHT_LOUSER   = 0x80000000,
+	SHT_HIUSER   = 0xffffffff,
+};
 
 /**
  * ELF section flags
  */
-#define SHF_WRITE      0x1
-#define SHF_ALLOC      0x2
-#define SHF_EXECINSTR  0x4
-#define SHF_TLS        0x400
-#define SHF_MASKPROC   0xf0000000
-
-/** Macros for decomposing elf_symbol.st_info into binging and type */
-#define ELF_ST_BIND(i)     ((i) >> 4)
-#define ELF_ST_TYPE(i)     ((i) & 0x0f)
-#define ELF_ST_INFO(b, t)  (((b) << 4) + ((t) & 0x0f))
+enum {
+	SHF_WRITE     = 0x1,
+	SHF_ALLOC     = 0x2,
+	SHF_EXECINSTR = 0x4,
+	SHF_TLS       = 0x400,
+	SHF_MASKPROC  = 0xf0000000,
+};
+
+/** Functions for decomposing elf_symbol.st_info into binding and type */
+static inline uint8_t elf_st_bind(uint8_t info)
+{
+	return info >> 4;
+}
+
+static inline uint8_t elf_st_type(uint8_t info)
+{
+	return info & 0x0f;
+}
+
+static inline uint8_t elf_st_info(uint8_t bind, uint8_t type)
+{
+	return (bind << 4) | (type & 0x0f);
+}
 
 /**
  * Symbol binding
  */
-#define STB_LOCAL   0
-#define STB_GLOBAL  1
-#define STB_WEAK    2
-#define STB_LOPROC  13
-#define STB_HIPROC  15
+enum elf_symbol_binding {
+	STB_LOCAL  = 0,
+	STB_GLOBAL = 1,
+	STB_WEAK   = 2,
+};
+
+enum {
+	STB_LOPROC = 13,
+	STB_HIPROC = 15,
+};
 
 /**
  * Symbol types
  */
-#define STT_NOTYPE   0
-#define STT_OBJECT   1
-#define STT_FUNC     2
-#define STT_SECTION  3
-#define STT_FILE     4
-#define STT_TLS      6
-#define STT_LOPROC   13
-#define STT_HIPROC   15
+enum elf_symbol_type {
+	STT_NOTYPE  = 0,
+	STT_OBJECT  = 1,
+	STT_FUNC    = 2,
+	STT_SECTION = 3,
+	STT_FILE    = 4,
+	STT_TLS     = 6,
+};
+
+enum {
+	STT_LOPROC  = 13,
+	STT_HIPROC  = 15,
+};
 
 /**
  * Program segment types
  */
-#define PT_NULL          0
-#define PT_LOAD          1
-#define PT_DYNAMIC       2
-#define PT_INTERP        3
-#define PT_NOTE          4
-#define PT_SHLIB         5
-#define PT_PHDR          6
-#define PT_TLS           7
-#define PT_LOOS          0x60000000
-#define PT_GNU_EH_FRAME  0x6474e550
-#define PT_GNU_STACK     0x6474e551
-#define PT_GNU_RELRO     0x6474e552
-#define PT_HIOS          0x6fffffff
-#define PT_LOPROC        0x70000000
-#define PT_HIPROC        0x7fffffff
+enum elf_segment_type {
+	PT_NULL         = 0,
+	PT_LOAD         = 1,
+	PT_DYNAMIC      = 2,
+	PT_INTERP       = 3,
+	PT_NOTE         = 4,
+	PT_SHLIB        = 5,
+	PT_PHDR         = 6,
+	PT_TLS          = 7,
+
+	PT_GNU_EH_FRAME = 0x6474e550,
+	PT_GNU_STACK    = 0x6474e551,
+	PT_GNU_RELRO    = 0x6474e552,
+};
+
+enum {
+	PT_LOOS   = 0x60000000,
+	PT_HIOS   = 0x6fffffff,
+	PT_LOPROC = 0x70000000,
+	PT_HIPROC = 0x7fffffff,
+};
 
 /**
  * Program segment attributes.
  */
-#define PF_X  1
-#define PF_W  2
-#define PF_R  4
+enum elf_segment_access {
+	PF_X = 1,
+	PF_W = 2,
+	PF_R = 4,
+};
+
+/**
+ * Dynamic array tags
+ */
+enum elf_dynamic_tag {
+	DT_NULL     = 0,
+	DT_NEEDED   = 1,
+	DT_PLTRELSZ = 2,
+	DT_PLTGOT   = 3,
+	DT_HASH     = 4,
+	DT_STRTAB   = 5,
+	DT_SYMTAB   = 6,
+	DT_RELA     = 7,
+	DT_RELASZ   = 8,
+	DT_RELAENT  = 9,
+	DT_STRSZ    = 10,
+	DT_SYMENT   = 11,
+	DT_INIT     = 12,
+	DT_FINI     = 13,
+	DT_SONAME   = 14,
+	DT_RPATH    = 15,
+	DT_SYMBOLIC = 16,
+	DT_REL      = 17,
+	DT_RELSZ    = 18,
+	DT_RELENT   = 19,
+	DT_PLTREL   = 20,
+	DT_DEBUG    = 21,
+	DT_TEXTREL  = 22,
+	DT_JMPREL   = 23,
+	DT_BIND_NOW = 24,
+	DT_LOPROC   = 0x70000000,
+	DT_HIPROC   = 0x7fffffff,
+};
+
+/**
+ * Special section indexes
+ */
+enum {
+	SHN_UNDEF     = 0,
+	SHN_LORESERVE = 0xff00,
+	SHN_LOPROC    = 0xff00,
+	SHN_HIPROC    = 0xff1f,
+	SHN_ABS       = 0xfff1,
+	SHN_COMMON    = 0xfff2,
+	SHN_HIRESERVE = 0xffff,
+};
+
+/**
+ * Special symbol table index
+ */
+enum {
+	STN_UNDEF = 0,
+};
 
 /**
@@ -353,4 +460,51 @@
 };
 
+/**
+ * Dynamic structure
+ */
+struct elf32_dyn {
+	elf_sword d_tag;
+	union {
+		elf_word d_val;
+		elf32_addr d_ptr;
+	} d_un;
+};
+
+struct elf64_dyn {
+	elf_sxword d_tag;
+	union {
+		elf_xword d_val;
+		elf64_addr d_ptr;
+	} d_un;
+};
+
+struct elf32_rel {
+	elf32_addr r_offset;
+	elf_word r_info;
+};
+
+struct elf32_rela {
+	elf32_addr r_offset;
+	elf_word r_info;
+	elf_sword r_addend;
+};
+
+struct elf64_rel {
+	elf64_addr r_offset;
+	elf_xword r_info;
+};
+
+struct elf64_rela {
+	elf64_addr r_offset;
+	elf_xword r_info;
+	elf_sxword r_addend;
+};
+
+#define ELF32_R_SYM(i) ((i) >> 8)
+#define ELF32_R_TYPE(i) ((unsigned char)(i))
+
+#define ELF64_R_SYM(i) ((i) >> 32)
+#define ELF64_R_TYPE(i) ((i) & 0xffffffffL)
+
 #ifdef __32_BITS__
 typedef struct elf32_header elf_header_t;
@@ -359,4 +513,8 @@
 typedef struct elf32_symbol elf_symbol_t;
 typedef struct elf32_note elf_note_t;
+typedef struct elf32_dyn elf_dyn_t;
+typedef struct elf32_rel elf_rel_t;
+typedef struct elf32_rela elf_rela_t;
+#define ELF_R_TYPE(i)  ELF32_R_TYPE(i)
 #endif
 
@@ -367,4 +525,8 @@
 typedef struct elf64_symbol elf_symbol_t;
 typedef struct elf64_note elf_note_t;
+typedef struct elf64_dyn elf_dyn_t;
+typedef struct elf64_rel elf_rel_t;
+typedef struct elf64_rela elf_rela_t;
+#define ELF_R_TYPE(i)  ELF64_R_TYPE(i)
 #endif
 
Index: abi/include/abi/fb/visuals.h
===================================================================
--- abi/include/abi/fb/visuals.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/abi/fb/visuals.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef ABI_VISUALS_H_
-#define ABI_VISUALS_H_
+#ifndef _ABI_VISUALS_H_
+#define _ABI_VISUALS_H_
 
 typedef enum {
Index: abi/include/abi/fourcc.h
===================================================================
--- abi/include/abi/fourcc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/abi/fourcc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef ABI_FOURCC_H_
-#define ABI_FOURCC_H_
+#ifndef _ABI_FOURCC_H_
+#define _ABI_FOURCC_H_
 
 #include <stdint.h>
Index: abi/include/abi/ipc/event.h
===================================================================
--- abi/include/abi/ipc/event.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/abi/ipc/event.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef ABI_IPC_EVENT_H_
-#define ABI_IPC_EVENT_H_
+#ifndef _ABI_IPC_EVENT_H_
+#define _ABI_IPC_EVENT_H_
 
 /** Global events */
Index: abi/include/abi/ipc/interfaces.h
===================================================================
--- abi/include/abi/ipc/interfaces.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/abi/ipc/interfaces.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,11 +35,13 @@
  */
 
-#ifndef ABI_IPC_INTERFACES_H_
-#define ABI_IPC_INTERFACES_H_
+#ifndef _ABI_IPC_INTERFACES_H_
+#define _ABI_IPC_INTERFACES_H_
 
 #include <abi/fourcc.h>
 
-#define IFACE_EXCHANGE_MASK  0x03
-#define IFACE_MOD_MASK       0x04
+enum {
+	IFACE_EXCHANGE_MASK = 0x03,
+	IFACE_MOD_MASK      = 0x04,
+};
 
 /** Interface exchange management style
@@ -183,5 +185,7 @@
 	    FOURCC_COMPACT('v', 'b', 'd', ' ') | IFACE_EXCHANGE_SERIALIZE,
 	INTERFACE_IPC_TEST =
-	    FOURCC_COMPACT('i', 'p', 'c', 't') | IFACE_EXCHANGE_SERIALIZE
+	    FOURCC_COMPACT('i', 'p', 'c', 't') | IFACE_EXCHANGE_SERIALIZE,
+	INTERFACE_PCI =
+	    FOURCC_COMPACT('p', 'c', 'i', ' ') | IFACE_EXCHANGE_SERIALIZE
 } iface_t;
 
Index: abi/include/abi/ipc/ipc.h
===================================================================
--- abi/include/abi/ipc/ipc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/abi/ipc/ipc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,81 +33,76 @@
  */
 
-#ifndef ABI_IPC_IPC_H_
-#define ABI_IPC_IPC_H_
+#ifndef _ABI_IPC_IPC_H_
+#define _ABI_IPC_IPC_H_
 
+#include <stdint.h>
 #include <abi/proc/task.h>
 #include <abi/cap.h>
+#include <_bits/errno.h>
 
-/** Length of data being transferred with IPC call
- *
- * The uspace may not be able to utilize the full length
- *
- */
-#define IPC_CALL_LEN  6
+/* Miscellaneous constants */
+enum {
+	/** Length of data being transferred with IPC call
+	 *
+	 * The uspace may not be able to utilize the full length
+	 *
+	 */
+	IPC_CALL_LEN = 6,
 
-/** Maximum active async calls per phone */
-#define IPC_MAX_ASYNC_CALLS  64
+	/** Maximum active async calls per phone */
+	IPC_MAX_ASYNC_CALLS = 64,
+
+	/**
+	 * Maximum buffer size allowed for IPC_M_DATA_WRITE and
+	 * IPC_M_DATA_READ requests.
+	 */
+	DATA_XFER_LIMIT = 64 * 1024,
+};
 
 /* Flags for calls */
+enum {
+	/** This is answer to a call */
+	IPC_CALL_ANSWERED       = 1 << 0,
 
-/** This is answer to a call */
-#define IPC_CALL_ANSWERED        (1 << 0)
+	/** Answer will not be passed to userspace, will be discarded */
+	IPC_CALL_DISCARD_ANSWER = 1 << 1,
 
-/** Answer will not be passed to userspace, will be discarded */
-#define IPC_CALL_DISCARD_ANSWER  (1 << 1)
+	/** Call was forwarded */
+	IPC_CALL_FORWARDED      = 1 << 2,
 
-/** Call was forwarded */
-#define IPC_CALL_FORWARDED       (1 << 2)
+	/** Interrupt notification */
+	IPC_CALL_NOTIF          = 1 << 3,
 
-/** Interrupt notification */
-#define IPC_CALL_NOTIF           (1 << 3)
-
-/** The call was automatically answered by the kernel due to error */
-#define IPC_CALL_AUTO_REPLY      (1 << 4)
-
-/**
- * Maximum buffer size allowed for IPC_M_DATA_WRITE and
- * IPC_M_DATA_READ requests.
- */
-#define DATA_XFER_LIMIT  (64 * 1024)
-
-/* Macros for manipulating calling data */
-#define IPC_SET_RETVAL(data, retval)  ((data).args[0] = (sysarg_t) (retval))
-#define IPC_SET_IMETHOD(data, val)    ((data).args[0] = (val))
-#define IPC_SET_ARG1(data, val)       ((data).args[1] = (val))
-#define IPC_SET_ARG2(data, val)       ((data).args[2] = (val))
-#define IPC_SET_ARG3(data, val)       ((data).args[3] = (val))
-#define IPC_SET_ARG4(data, val)       ((data).args[4] = (val))
-#define IPC_SET_ARG5(data, val)       ((data).args[5] = (val))
-
-#define IPC_GET_IMETHOD(data)  ((data).args[0])
-#define IPC_GET_RETVAL(data)   ((errno_t) (data).args[0])
-
-#define IPC_GET_ARG1(data)  ((data).args[1])
-#define IPC_GET_ARG2(data)  ((data).args[2])
-#define IPC_GET_ARG3(data)  ((data).args[3])
-#define IPC_GET_ARG4(data)  ((data).args[4])
-#define IPC_GET_ARG5(data)  ((data).args[5])
+	/** The call was automatically answered by the kernel due to error */
+	IPC_CALL_AUTO_REPLY     = 1 << 4,
+};
 
 /* Forwarding flags. */
-#define IPC_FF_NONE  0
+enum {
+	IPC_FF_NONE = 0,
 
-/**
- * The call will be routed as though it was initially sent via the phone used to
- * forward it. This feature is intended to support the situation in which the
- * forwarded call needs to be handled by the same connection fibril as any other
- * calls that were initially sent by the forwarder to the same destination. This
- * flag has no imapct on routing replies.
- */
-#define IPC_FF_ROUTE_FROM_ME  (1 << 0)
+	/**
+	 * The call will be routed as though it was initially sent via the phone
+	 * used to forward it. This feature is intended to support the situation
+	 * in which the forwarded call needs to be handled by the same
+	 * connection fibril as any other calls that were initially sent by
+	 * the forwarder to the same destination.
+	 * This flag has no imapct on routing replies.
+	 */
+	IPC_FF_ROUTE_FROM_ME = 1 << 0,
+};
 
 /* Data transfer flags. */
-#define IPC_XF_NONE  0
+enum {
+	IPC_XF_NONE = 0,
 
-/** Restrict the transfer size if necessary. */
-#define IPC_XF_RESTRICT  (1 << 0)
+	/** Restrict the transfer size if necessary. */
+	IPC_XF_RESTRICT = 1 << 0,
+};
 
 /** User-defined IPC methods */
-#define IPC_FIRST_USER_METHOD  1024
+enum {
+	IPC_FIRST_USER_METHOD = 1024,
+};
 
 typedef struct {
@@ -128,4 +123,75 @@
 } ipc_data_t;
 
+/* Functions for manipulating calling data */
+
+static inline void ipc_set_retval(ipc_data_t *data, errno_t retval)
+{
+	data->args[0] = (sysarg_t) retval;
+}
+
+static inline void ipc_set_imethod(ipc_data_t *data, sysarg_t val)
+{
+	data->args[0] = val;
+}
+
+static inline void ipc_set_arg1(ipc_data_t *data, sysarg_t val)
+{
+	data->args[1] = val;
+}
+
+static inline void ipc_set_arg2(ipc_data_t *data, sysarg_t val)
+{
+	data->args[2] = val;
+}
+
+static inline void ipc_set_arg3(ipc_data_t *data, sysarg_t val)
+{
+	data->args[3] = val;
+}
+
+static inline void ipc_set_arg4(ipc_data_t *data, sysarg_t val)
+{
+	data->args[4] = val;
+}
+
+static inline void ipc_set_arg5(ipc_data_t *data, sysarg_t val)
+{
+	data->args[5] = val;
+}
+
+static inline sysarg_t ipc_get_imethod(ipc_data_t *data)
+{
+	return data->args[0];
+}
+static inline errno_t ipc_get_retval(ipc_data_t *data)
+{
+	return (errno_t) data->args[0];
+}
+
+static inline sysarg_t ipc_get_arg1(ipc_data_t *data)
+{
+	return data->args[1];
+}
+
+static inline sysarg_t ipc_get_arg2(ipc_data_t *data)
+{
+	return data->args[2];
+}
+
+static inline sysarg_t ipc_get_arg3(ipc_data_t *data)
+{
+	return data->args[3];
+}
+
+static inline sysarg_t ipc_get_arg4(ipc_data_t *data)
+{
+	return data->args[4];
+}
+
+static inline sysarg_t ipc_get_arg5(ipc_data_t *data)
+{
+	return data->args[5];
+}
+
 #endif
 
Index: abi/include/abi/ipc/methods.h
===================================================================
--- abi/include/abi/ipc/methods.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/abi/ipc/methods.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,16 +33,18 @@
  */
 
-#ifndef ABI_IPC_METHODS_H_
-#define ABI_IPC_METHODS_H_
+#ifndef _ABI_IPC_METHODS_H_
+#define _ABI_IPC_METHODS_H_
 
 #include <abi/cap.h>
 
 /* Well known phone descriptors */
-#define PHONE_NS  ((cap_phone_handle_t) (CAP_NIL + 1))
+static cap_phone_handle_t const PHONE_NS = (cap_phone_handle_t) (CAP_NIL + 1);
 
 /** Kernel IPC interfaces
  *
  */
-#define IPC_IF_KERNEL  0
+enum {
+	IPC_IF_KERNEL = 0,
+};
 
 /** System-specific IPC methods
@@ -52,5 +54,4 @@
  *
  */
-
 enum {
 	/** This message is sent to answerbox when the phone is hung up
@@ -152,5 +153,5 @@
 	 *
 	 * - ARG1 - dst as_area lower bound
-	 * - ARG2 - dst as_area base adress pointer
+	 * - ARG2 - dst as_area base address pointer
 	 *          (filled automatically by the kernel)
 	 */
@@ -217,5 +218,7 @@
 
 /** Last system IPC method */
-#define IPC_M_LAST_SYSTEM  511
+enum {
+	IPC_M_LAST_SYSTEM = 511,
+};
 
 #endif
Index: abi/include/abi/kio.h
===================================================================
--- abi/include/abi/kio.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/abi/kio.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,9 +33,9 @@
  */
 
-#ifndef ABI_KIO_H_
-#define ABI_KIO_H_
+#ifndef _ABI_KIO_H_
+#define _ABI_KIO_H_
 
 enum {
-	KIO_UNKNOW,
+	KIO_UNKNOWN,
 	KIO_WRITE,
 	KIO_UPDATE,
Index: abi/include/abi/klog.h
===================================================================
--- abi/include/abi/klog.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/abi/klog.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef ABI_KLOG_H_
-#define ABI_KLOG_H_
+#ifndef _ABI_KLOG_H_
+#define _ABI_KLOG_H_
 
 typedef enum {
Index: abi/include/abi/log.h
===================================================================
--- abi/include/abi/log.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/abi/log.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,6 +35,6 @@
  */
 
-#ifndef ABI_LOG_H_
-#define ABI_LOG_H_
+#ifndef _ABI_LOG_H_
+#define _ABI_LOG_H_
 
 /** Log message level. */
Index: abi/include/abi/mm/as.h
===================================================================
--- abi/include/abi/mm/as.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/abi/mm/as.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,21 +33,22 @@
  */
 
-#ifndef ABI_AS_H_
-#define ABI_AS_H_
+#ifndef _ABI_AS_H_
+#define _ABI_AS_H_
 
 #include <abi/cap.h>
 
 /** Address space area flags. */
-#define AS_AREA_READ         0x01
-#define AS_AREA_WRITE        0x02
-#define AS_AREA_EXEC         0x04
-#define AS_AREA_CACHEABLE    0x08
-#define AS_AREA_GUARD        0x10
-#define AS_AREA_LATE_RESERVE 0x20
+enum {
+	AS_AREA_READ         = 0x01,
+	AS_AREA_WRITE        = 0x02,
+	AS_AREA_EXEC         = 0x04,
+	AS_AREA_CACHEABLE    = 0x08,
+	AS_AREA_GUARD        = 0x10,
+	AS_AREA_LATE_RESERVE = 0x20,
+};
 
-#define AS_AREA_ANY    ((void *) -1)
-#define AS_MAP_FAILED  ((void *) -1)
-
-#define AS_AREA_UNPAGED NULL
+static void *const AS_AREA_ANY = (void *) -1;
+static void *const AS_MAP_FAILED = (void *) -1;
+static void *const AS_AREA_UNPAGED = NULL;
 
 /** Address space area info exported to uspace. */
Index: abi/include/abi/proc/task.h
===================================================================
--- abi/include/abi/proc/task.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/abi/proc/task.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef ABI_PROC_TASK_H_
-#define ABI_PROC_TASK_H_
+#ifndef _ABI_PROC_TASK_H_
+#define _ABI_PROC_TASK_H_
 
 #include <stdint.h>
Index: abi/include/abi/proc/thread.h
===================================================================
--- abi/include/abi/proc/thread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/abi/proc/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef ABI_PROC_THREAD_H_
-#define ABI_PROC_THREAD_H_
+#ifndef _ABI_PROC_THREAD_H_
+#define _ABI_PROC_THREAD_H_
 
 #include <stdint.h>
Index: abi/include/abi/proc/uarg.h
===================================================================
--- abi/include/abi/proc/uarg.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/abi/proc/uarg.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef ABI_PROC_UARG_H_
-#define ABI_PROC_UARG_H_
+#ifndef _ABI_PROC_UARG_H_
+#define _ABI_PROC_UARG_H_
 
 #include <stddef.h>
Index: abi/include/abi/synch.h
===================================================================
--- abi/include/abi/synch.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/abi/synch.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,18 +33,22 @@
  */
 
-#ifndef ABI_SYNCH_H_
-#define ABI_SYNCH_H_
+#ifndef _ABI_SYNCH_H_
+#define _ABI_SYNCH_H_
 
-/** Request with no timeout. */
-#define SYNCH_NO_TIMEOUT  0
+enum {
+	/** Request with no timeout. */
+	SYNCH_NO_TIMEOUT = 0,
+};
 
-/** No flags specified. */
-#define SYNCH_FLAGS_NONE           0
-/** Non-blocking operation request. */
-#define SYNCH_FLAGS_NON_BLOCKING   (1 << 0)
-/** Interruptible operation. */
-#define SYNCH_FLAGS_INTERRUPTIBLE  (1 << 1)
-/** Futex operation (makes sleep with timeout composable). */
-#define SYNCH_FLAGS_FUTEX          (1 << 2)
+enum {
+	/** No flags specified. */
+	SYNCH_FLAGS_NONE          = 0,
+	/** Non-blocking operation request. */
+	SYNCH_FLAGS_NON_BLOCKING  = 1 << 0,
+	/** Interruptible operation. */
+	SYNCH_FLAGS_INTERRUPTIBLE = 1 << 1,
+	/** Futex operation (makes sleep with timeout composable). */
+	SYNCH_FLAGS_FUTEX         = 1 << 2,
+};
 
 #endif
Index: abi/include/abi/syscall.h
===================================================================
--- abi/include/abi/syscall.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/abi/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef ABI_SYSCALL_H_
-#define ABI_SYSCALL_H_
+#ifndef _ABI_SYSCALL_H_
+#define _ABI_SYSCALL_H_
 
 typedef enum {
Index: abi/include/abi/sysinfo.h
===================================================================
--- abi/include/abi/sysinfo.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/abi/sysinfo.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef ABI_SYSINFO_H_
-#define ABI_SYSINFO_H_
+#ifndef _ABI_SYSINFO_H_
+#define _ABI_SYSINFO_H_
 
 #include <stdbool.h>
@@ -42,10 +42,12 @@
 #include <stdint.h>
 
-/** Number of load components */
-#define LOAD_STEPS  3
+enum {
+	/** Number of load components */
+	LOAD_STEPS = 3,
 
-/** Maximum name sizes */
-#define TASK_NAME_BUFLEN  64
-#define EXC_NAME_BUFLEN   20
+	/** Maximum name sizes */
+	TASK_NAME_BUFLEN = 64,
+	EXC_NAME_BUFLEN  = 20,
+};
 
 /** Item value type
Index: abi/include/abi/udebug.h
===================================================================
--- abi/include/abi/udebug.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/abi/udebug.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef ABI_UDEBUG_H_
-#define ABI_UDEBUG_H_
+#ifndef _ABI_UDEBUG_H_
+#define _ABI_UDEBUG_H_
 
 #define UDEBUG_EVMASK(event)  (1 << ((event) - 1))
Index: abi/include/inttypes.h
===================================================================
--- abi/include/inttypes.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/inttypes.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -43,4 +43,5 @@
 #include <stdint.h>
 #include <_bits/wchar_t.h>
+#include <_bits/decls.h>
 
 /*
@@ -311,11 +312,4 @@
 #endif
 
-#ifdef _HELENOS_SOURCE
-#define UINT8_MIN   0
-#define UINT16_MIN  0
-#define UINT32_MIN  0
-#define UINT64_MIN  0
-#endif
-
 #define PRIdMAX  "lld"
 #define PRIiMAX  "lli"
@@ -330,7 +324,11 @@
 #define SCNxMAX  "llx"
 
-#ifdef __cplusplus
-extern "C" {
+#if defined(_HELENOS_SOURCE) && !defined(__cplusplus)
+#define PRIdn  PRIdPTR  /**< Format for native_t. */
+#define PRIun  PRIuPTR  /**< Format for sysarg_t. */
+#define PRIxn  PRIxPTR  /**< Format for hexadecimal sysarg_t. */
 #endif
+
+__C_DECLS_BEGIN;
 
 typedef struct {
@@ -343,11 +341,11 @@
 intmax_t strtoimax(const char *__restrict__, char **__restrict__, int);
 uintmax_t strtoumax(const char *__restrict__, char **__restrict__, int);
-
-#ifdef __cplusplus
-}
+intmax_t wcstoimax(const wchar_t *__restrict__, wchar_t **__restrict__, int);
+uintmax_t wcstoumax(const wchar_t *__restrict__, wchar_t **__restrict__, int);
+
+__C_DECLS_END;
+
 #endif
 
-#endif
-
 /** @}
  */
Index: abi/include/limits.h
===================================================================
--- abi/include/limits.h	(revision c878693123930f0906703462cf2807430679517e)
+++ abi/include/limits.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_LIMITS_H_
-#define LIBC_LIMITS_H_
+#ifndef _LIBC_LIMITS_H_
+#define _LIBC_LIMITS_H_
 
 #ifdef __GNUC__
@@ -84,4 +84,5 @@
 #define MB_LEN_MAX 4
 
+#ifdef _HELENOS_SOURCE
 #define UCHAR_MIN   0
 #define USHRT_MIN   0
@@ -89,4 +90,19 @@
 #define ULONG_MIN   (0ul)
 #define ULLONG_MIN  (0ull)
+#define SSIZE_MIN   INTPTR_MIN
+#define UINT8_MIN   0
+#define UINT16_MIN  0
+#define UINT32_MIN  0
+#define UINT64_MIN  0
+#endif
+
+#if defined(_HELENOS_SOURCE) || defined(_POSIX_SOURCE) || \
+    defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \
+    defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define SSIZE_MAX  INTPTR_MAX
+#define NAME_MAX   255
+
+#endif
 
 /* GCC's <limits.h> doesn't define these for C++11, even though it should. */
Index: boot/Makefile.build
===================================================================
--- boot/Makefile.build	(revision c878693123930f0906703462cf2807430679517e)
+++ boot/Makefile.build	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,5 +37,5 @@
 
 AFLAGS = --fatal-warnings
-LDFLAGS = -Wl,--fatal-warnings,--warn-common
+LDFLAGS = -Wl,--fatal-warnings,--warn-common $(EXTRA_LDFLAGS)
 
 COMMON_CFLAGS = $(INCLUDES) -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
@@ -103,5 +103,5 @@
 
 %.gz: %
-	gzip -n -k -f $<
+	gzip -n -k -9 -f $<
 
 $(COMPS).tar: $(COMPONENTS)
Index: boot/Makefile.common
===================================================================
--- boot/Makefile.common	(revision c878693123930f0906703462cf2807430679517e)
+++ boot/Makefile.common	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -94,6 +94,10 @@
 	devman \
 	fs/locfs \
-	hid/compositor \
 	klog
+
+ifeq ($(CONFIG_FB), y)
+	RD_SRVS_ESSENTIAL += \
+		hid/compositor
+endif
 
 RD_SRVS_NON_ESSENTIAL = \
@@ -141,5 +145,6 @@
 	nic/ar9271 \
 	nic/virtio-net \
-	block/ahci
+	block/ahci \
+	block/virtio-blk
 
 RD_DRV_CFG =
@@ -162,5 +167,14 @@
 endif
 
-RD_APPS_ESSENTIAL = bdsh getterm kio vlaunch vterm
+RD_APPS_ESSENTIAL = \
+	bdsh \
+	getterm \
+	kio
+
+ifeq ($(CONFIG_FB), y)
+	RD_APPS_ESSENTIAL += \
+		vlaunch \
+		vterm
+endif
 
 RD_APPS_NON_ESSENTIAL = \
@@ -168,5 +182,4 @@
 	bithenge \
 	blkdump \
-	bnchmark \
 	contacts \
 	corecfg \
@@ -179,8 +192,10 @@
 	fdisk \
 	gunzip \
+	hbench \
 	inet \
 	kill \
 	killall \
 	loc \
+	lprint \
 	mixerctl \
 	modplay \
@@ -191,7 +206,4 @@
 	mkmfs \
 	nic \
-	perf \
-	rcutest \
-	rcubench \
 	sbi \
 	sportdmp \
@@ -207,4 +219,5 @@
 	netecho \
 	nterm \
+	pci \
 	ping \
 	pkg \
Index: boot/Makefile.grub
===================================================================
--- boot/Makefile.grub	(revision c878693123930f0906703462cf2807430679517e)
+++ boot/Makefile.grub	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,5 +31,5 @@
 include Makefile.common
 
-GRUB = grub.$(GRUB_ARCH)
+GRUB = grub/$(BARCH)-$(GRUB_ARCH)
 BOOT = $(DISTROOT)/boot
 BOOT_CONFIG = $(BOOT)/grub/grub.cfg
@@ -64,7 +64,12 @@
 endif
 
+ifeq ($(GRUB_LOADER),multiboot)
 	for module in $(COMPONENTS) ; do \
 		cp "$$module" $(BOOT)/ ; \
 	done
+endif
+ifeq ($(GRUB_LOADER),chainloader)
+	cp "$(BOOT_OUTPUT)" $(BOOT)/
+endif
 
 	echo "set default=0" > $(BOOT_CONFIG)
@@ -83,4 +88,5 @@
 
 	echo "menuentry 'HelenOS $(RELEASE)' --class helenos --class os {" >> $(BOOT_CONFIG)
+ifeq ($(GRUB_LOADER),multiboot)
 	for module in $(MODULES) ; do \
 		echo "	echo 'Loading $$module'" >> $(BOOT_CONFIG) ; \
@@ -91,4 +97,10 @@
 		fi \
 	done
+endif
+ifeq ($(GRUB_LOADER),chainloader)
+	echo "	echo 'Loading $(BOOT_OUTPUT)'" >> $(BOOT_CONFIG)
+	echo "	chainloader /boot/$(BOOT_OUTPUT)" >> $(BOOT_CONFIG)
+	echo "	boot" >> $(BOOT_CONFIG)
+endif
 	echo "}" >> $(BOOT_CONFIG)
 
Index: boot/arch/amd64/Makefile.inc
===================================================================
--- boot/arch/amd64/Makefile.inc	(revision c878693123930f0906703462cf2807430679517e)
+++ boot/arch/amd64/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -46,4 +46,5 @@
 	audio/hdaudio \
 	char/ns8250 \
+	char/pc-lpt \
 	time/cmos-rtc \
 	bus/usb/ehci\
@@ -73,2 +74,3 @@
 BUILD = Makefile.empty
 POSTBUILD = Makefile.grub
+GRUB_LOADER = multiboot
Index: boot/arch/arm32/src/mm.c
===================================================================
--- boot/arch/arm32/src/mm.c	(revision c878693123930f0906703462cf2807430679517e)
+++ boot/arch/arm32/src/mm.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -99,5 +99,4 @@
  *
  * Memory areas used for I/O are excluded from caching.
- * At the moment caching is enabled only on GTA02.
  *
  * @param section	The section number.
@@ -171,14 +170,36 @@
 {
 	/*
-	 * Create 1:1 virtual-physical mapping.
-	 * Physical memory on BBxM a BBone starts at 2GB
-	 * boundary, icp has a memory mirror at 2GB.
-	 * (ARM Integrator Core Module User guide ch. 6.3,  p. 6-7)
-	 * gta02 somehow works (probably due to limited address size),
-	 * s3c2442b manual ch. 5, p.5-1:
-	 * "Address space: 128Mbytes per bank (total 1GB/8 banks)"
-	 */
-	for (pfn_t page = 0; page < PTL0_ENTRIES; ++page)
-		init_ptl0_section(&boot_pt[page], page);
+	 * Our goal is to create page tables that serve two purposes:
+	 *
+	 * 1. Allow the loader to run in identity-mapped virtual memory and use
+	 *    I/O devices (e.g. an UART for logging).
+	 * 2. Allow the kernel to start running in virtual memory from addresses
+	 *    above 2G.
+	 *
+	 * The matters are slightly complicated by the different locations of
+	 * physical memory and I/O devices on the various boards that we
+	 * support. We see two cases (but other are still possible):
+	 *
+	 * a) Both RAM and I/O is in memory below 2G
+	 *    For instance, this is the case of GTA02, Integrator/CP
+	 *    and RaspberryPi
+	 * b) RAM starts at 2G and I/O devices are below 2G
+	 *    For example, this is the case of BeagleBone and BeagleBoard XM
+	 *
+	 * This leads to two possible setups of boot page tables:
+	 *
+	 * A) To arrange for a), split the virtual address space into two
+	 *    halves, both identity-mapping the first 2G of physical address
+	 *    space.
+	 * B) To accommodate b), create one larger virtual address space
+	 *    identity-mapping the entire physical address space.
+	 */
+
+	for (pfn_t page = 0; page < PTL0_ENTRIES; page++) {
+		pfn_t frame = page;
+		if (BOOT_BASE < 0x80000000UL && page >= PTL0_ENTRIES / 2)
+			frame -= PTL0_ENTRIES / 2;
+		init_ptl0_section(&boot_pt[page], frame);
+	}
 
 	/*
Index: boot/arch/arm64/Makefile.inc
===================================================================
--- boot/arch/arm64/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/arch/arm64/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,79 @@
+#
+# Copyright (c) 2015 Petr Pavlu
+# 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.
+#
+
+BOOT_OUTPUT = image.boot
+POST_OUTPUT = $(ROOT_PATH)/image.iso
+POSTBUILD = Makefile.grub
+GRUB_LOADER = chainloader
+
+BFD_NAME = elf64-littleaarch64
+# Request binary BFD output. The ARM64 port manually prepares the .text
+# section to look as a PE file than can be loaded on EFI systems.
+BFD_OUTPUT = binary
+BFD_ARCH = aarch64
+
+BITS = 64
+ENDIANESS = LE
+
+# UEFI binaries should be relocatable, the EFI boot service LoadImage() will
+# rebase the boot file using the .reloc information in the image if it cannot
+# load the binary at its preferred address. The ARM64 port does not provide this
+# information in its PE file (that would require manually creating it) but
+# instead the boot code is compiled with the -fpic option and the bootloader
+# relocates itself at runtime.
+#
+# N.B. The UEFI guarantees for AArch64 that during boot time the primary
+# processor is in the execution mode that has unaligned access enabled. The
+# -mstrict-align option is therefore not needed.
+EXTRA_CFLAGS = -fpic -fvisibility=hidden
+EXTRA_LDFLAGS = -Wl,-shared
+
+ifeq ($(MACHINE), virt)
+	RD_DRVS_ESSENTIAL += \
+		char/pl011 \
+		intctl/gicv2 \
+		platform/arm64virt
+endif
+
+SOURCES = \
+	arch/$(BARCH)/src/asm.S \
+	arch/$(BARCH)/src/main.c \
+	arch/$(BARCH)/src/relocate.c \
+	$(COMPS).o \
+	genarch/src/efi.c \
+	generic/src/gzip.c \
+	generic/src/inflate.c \
+	generic/src/kernel.c \
+	generic/src/memstr.c \
+	generic/src/payload.c \
+	generic/src/printf.c \
+	generic/src/printf_core.c \
+	generic/src/str.c \
+	generic/src/tar.c \
+	generic/src/version.c \
+	generic/src/vprintf.c
Index: boot/arch/arm64/_link.ld.in
===================================================================
--- boot/arch/arm64/_link.ld.in	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/arch/arm64/_link.ld.in	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,33 @@
+#include <arch/arch.h>
+
+ENTRY(start)
+
+SECTIONS {
+	. = 0x0;
+	.text : {
+		HIDDEN(loader_start = .);
+		*(BOOTSTRAP);
+		*(.text);
+	}
+	.dynamic : { *(.dynamic); }
+	.rela.got : { *(.rela.got); }
+	.hash : { *(.hash); }
+	.dynsym : { *(.dynsym); }
+	.dynstr : { *(.dynstr); }
+	. = 0x8000;
+	.data : {
+		*(.data*);      /* initialized data */
+		*(.rodata*);
+		*(.bss);        /* uninitialized static variables */
+		*(COMMON);      /* global variables */
+		*(.got .got.plt);
+		HIDDEN(loader_end = .);
+		HIDDEN(payload_start = .);
+		*(.payload);
+		HIDDEN(payload_end = .);
+	}
+
+	/DISCARD/ : {
+		*(*);
+	}
+}
Index: boot/arch/arm64/include/arch/arch.h
===================================================================
--- boot/arch/arm64/include/arch/arch.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/arch/arm64/include/arch/arch.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 boot_arm64
+ * @{
+ */
+/** @file
+ * @brief Various ARM64-specific macros.
+ */
+
+#ifndef BOOT_arm64_ARCH_H
+#define BOOT_arm64_ARCH_H
+
+#define PAGE_WIDTH  12
+#define PAGE_SIZE   (1 << PAGE_WIDTH)
+
+#define BOOT_OFFSET  0x80000
+#ifndef __ASSEMBLER__
+#define KA2PA(x)  (((uintptr_t) (x)) - UINT64_C(0xffffffff80000000))
+#endif
+
+#endif
+
+/** @}
+ */
Index: boot/arch/arm64/include/arch/asm.h
===================================================================
--- boot/arch/arm64/include/arch/asm.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/arch/arm64/include/arch/asm.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 boot_arm64
+ * @{
+ */
+/** @file
+ * @brief Functions implemented in assembly.
+ */
+
+#ifndef BOOT_arm64_ASM_H
+#define BOOT_arm64_ASM_H
+
+/** Jump to the kernel entry point.
+ *
+ * @param entry    Kernel entry point.
+ * @param bootinfo Structure holding information about loaded tasks.
+ */
+extern void jump_to_kernel(void *entry, void *bootinfo)
+    __attribute__((noreturn));
+
+#endif
+
+/** @}
+ */
Index: boot/arch/arm64/include/arch/barrier.h
===================================================================
--- boot/arch/arm64/include/arch/barrier.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/arch/arm64/include/arch/barrier.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+../../../../../kernel/arch/arm64/include/arch/barrier.h
Index: boot/arch/arm64/include/arch/boot.h
===================================================================
--- boot/arch/arm64/include/arch/boot.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/arch/arm64/include/arch/boot.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+../../../../../kernel/arch/arm64/include/arch/boot/boot.h
Index: boot/arch/arm64/include/arch/main.h
===================================================================
--- boot/arch/arm64/include/arch/main.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/arch/arm64/include/arch/main.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 boot_arm64
+ * @{
+ */
+/** @file
+ * @brief Boot related declarations.
+ */
+
+#ifndef BOOT_arm64_MAIN_H
+#define BOOT_arm64_MAIN_H
+
+#include <genarch/efi.h>
+
+extern efi_status_t bootstrap(void *efi_handle_in,
+    efi_system_table_t *efi_system_table_in, void *load_address);
+
+#endif
+
+/** @}
+ */
Index: boot/arch/arm64/include/arch/regutils.h
===================================================================
--- boot/arch/arm64/include/arch/regutils.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/arch/arm64/include/arch/regutils.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+../../../../../kernel/arch/arm64/include/arch/regutils.h
Index: boot/arch/arm64/include/arch/relocate.h
===================================================================
--- boot/arch/arm64/include/arch/relocate.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/arch/arm64/include/arch/relocate.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019 Petr Pavlu
+ * 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 boot_arm64
+ * @{
+ */
+/** @file
+ * @brief Image self-relocation support.
+ */
+
+#ifndef BOOT_arm64_RELOCATE_H
+#define BOOT_arm64_RELOCATE_H
+
+#include <abi/elf.h>
+#include <genarch/efi.h>
+#include <stdint.h>
+
+extern efi_status_t self_relocate(uintptr_t base, const elf_dyn_t *dyn);
+
+#endif
+
+/** @}
+ */
Index: boot/arch/arm64/include/arch/types.h
===================================================================
--- boot/arch/arm64/include/arch/types.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/arch/arm64/include/arch/types.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 boot_arm64
+ * @{
+ */
+/** @file
+ * @brief Definitions of basic types like #uintptr_t.
+ */
+
+#ifndef BOOT_arm64_TYPES_H
+#define BOOT_arm64_TYPES_H
+
+#include <_bits/all.h>
+
+#include <arch/boot.h>
+#define task_t utask_t
+
+#endif
+
+/** @}
+ */
Index: boot/arch/arm64/src/asm.S
===================================================================
--- boot/arch/arm64/src/asm.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/arch/arm64/src/asm.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 <abi/asmtool.h>
+#include <arch/arch.h>
+#include <arch/regutils.h>
+
+.section BOOTSTRAP
+
+/* MS-DOS stub */
+msdos_stub:
+	.ascii "MZ"                     /* MS-DOS signature */
+	.space 0x3a                     /* Ignore fields up to byte at 0x3c */
+	.long pe_header - msdos_stub    /* Offset to the PE header */
+
+/* Portable Executable header */
+pe_header:
+	/* PE signature */
+	.ascii "PE\x0\x0"
+
+	/* COFF File Header */
+	.short 0xaa64                   /* Machine = IMAGE_FILE_MACHINE_ARM64 */
+	.short 1                        /* Number of sections */
+	.long 0                         /* Time date stamp */
+	.long 0                         /* Pointer to symbol table */
+	.long 0                         /* Number of symbols */
+	.short sec_table - opt_header   /* Size of optional header */
+	/* Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE |
+	 *   IMAGE_FILE_LARGE_ADDRESS_AWARE */
+	.short 0x22
+
+	/* Optional header standard fields */
+opt_header:
+	.short 0x20b                    /* Magic = PE32+ */
+	.byte 0                         /* Major linker version */
+	.byte 0                         /* Minor linker version */
+	.long payload_end - msdos_stub  /* Size of code */
+	.long 0                         /* Size of initialized data */
+	.long 0                         /* Size of uninitialized data */
+	.long start - msdos_stub        /* Address of entry point */
+	.long start - msdos_stub        /* Base of code */
+
+	/* Optional header Windows-specific fields */
+	.quad 0                         /* Image base */
+	.long 4                         /* Section alignment */
+	.long 4                         /* File alignment */
+	.short 0                        /* Major operating system version */
+	.short 0                        /* Minor operating system version */
+	.short 0                        /* Major image version */
+	.short 0                        /* Minor image version */
+	.short 0                        /* Major subsystem version */
+	.short 0                        /* Minor subsystem version */
+	.long 0                         /* Win32 version value */
+	.long payload_end - msdos_stub  /* Size of image */
+	.long start - msdos_stub        /* Size of headers */
+	.long 0                         /* Checksum */
+	.short 10                       /* Subsystem = EFI application */
+	.short 0                        /* DLL characteristics */
+	.quad 0                         /* Size of stack reserve */
+	.quad 0                         /* Size of stack commit */
+	.quad 0                         /* Size of heap reserve */
+	.quad 0                         /* Size of heap commit */
+	.long 0                         /* Loader flags */
+	.long 0                         /* Number of RVA and sizes */
+
+sec_table:
+        .ascii ".text\x0\x0\x0"         /* Name */
+	.long payload_end - start       /* Virtual size */
+	.long start - msdos_stub        /* Virtual address */
+	.long payload_end - start       /* Size of raw data */
+	.long start - msdos_stub        /* Pointer to raw data */
+	.long 0                         /* Pointer to relocations */
+	.long 0                         /* Pointer to line numbers */
+	.short 0                        /* Number of relocations */
+	.short 0                        /* Number of line numbers */
+	/* Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE |
+	 *   IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE */
+	.long 0xe0000020
+
+SYMBOL(start)
+	.hidden start
+
+	/*
+	 * Parameters:
+	 * x0 is the image handle.
+	 * x1 is a pointer to the UEFI system table.
+	 */
+
+	/*
+	 * Stay on the UEFI stack. Its size is at least 128 kB, plenty for this
+	 * boot loader.
+	 */
+	stp x29, x30, [sp, #-32]!
+	mov x29, sp
+	stp x0, x1, [sp, #16]
+
+	/*
+	 * Self-relocate the image. Pass a load address of the image (x0) and a
+	 * pointer to the dynamic array (x1).
+	 */
+	adr x0, msdos_stub
+	adrp x1, _DYNAMIC
+	add x1, x1, #:lo12:_DYNAMIC
+	bl self_relocate
+	cbnz x0, 0f
+
+	/*
+	 * Pass the image handle (x0), a pointer to the UEFI system table (x1),
+	 * and the image load address (x2) to the boostrap function.
+	 */
+	ldp x0, x1, [sp, #16]
+	adr x2, msdos_stub
+	bl bootstrap
+
+0:
+	ldp x29, x30, [sp], #32
+	ret
+
+FUNCTION_BEGIN(halt)
+	.hidden halt
+
+	b halt
+FUNCTION_END(halt)
+
+FUNCTION_BEGIN(jump_to_kernel)
+	.hidden jump_to_kernel
+
+	/*
+	 * Parameters:
+	 * x0 is kernel entry point.
+	 * x1 is pointer to the bootinfo structure.
+	 */
+
+	/* Disable MMU (removes the identity mapping provided by UEFI). */
+	mrs x2, sctlr_el1
+	bic x2, x2, #SCTLR_M_FLAG
+	msr sctlr_el1, x2
+	isb
+
+	br x0
+FUNCTION_END(jump_to_kernel)
Index: boot/arch/arm64/src/main.c
===================================================================
--- boot/arch/arm64/src/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/arch/arm64/src/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 boot_arm64
+ * @{
+ */
+/** @file
+ * @brief Bootstrap.
+ */
+
+#include <stddef.h>
+#include <align.h>
+#include <arch/arch.h>
+#include <arch/asm.h>
+#include <arch/barrier.h>
+#include <arch/main.h>
+#include <arch/regutils.h>
+#include <arch/types.h>
+#include <errno.h>
+#include <inflate.h>
+#include <kernel.h>
+#include <macros.h>
+#include <memstr.h>
+#include <payload.h>
+#include <printf.h>
+#include <putchar.h>
+#include <str.h>
+#include <version.h>
+
+static efi_system_table_t *efi_system_table;
+
+/** Translate given UEFI memory type to the bootinfo memory type.
+ *
+ * @param type UEFI memory type.
+ */
+static memtype_t get_memtype(uint32_t type)
+{
+	switch (type) {
+	case EFI_RESERVED:
+	case EFI_RUNTIME_SERVICES_CODE:
+	case EFI_RUNTIME_SERVICES_DATA:
+	case EFI_UNUSABLE_MEMORY:
+	case EFI_ACPI_MEMORY_NVS:
+	case EFI_MEMORY_MAPPED_IO:
+	case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+	case EFI_PAL_CODE:
+		return MEMTYPE_UNUSABLE;
+	case EFI_LOADER_CODE:
+	case EFI_LOADER_DATA:
+	case EFI_BOOT_SERVICES_CODE:
+	case EFI_BOOT_SERVICES_DATA:
+	case EFI_CONVENTIONAL_MEMORY:
+	case EFI_PERSISTENT_MEMORY:
+		return MEMTYPE_AVAILABLE;
+	case EFI_ACPI_RECLAIM_MEMORY:
+		return MEMTYPE_ACPI_RECLAIM;
+	}
+
+	return MEMTYPE_UNUSABLE;
+}
+
+/** Send a byte to the UEFI console output.
+ *
+ * @param byte Byte to send.
+ */
+static void scons_sendb(uint8_t byte)
+{
+	int16_t out[2] = { byte, '\0' };
+	efi_system_table->cons_out->output_string(efi_system_table->cons_out,
+	    out);
+}
+
+/** Display a character.
+ *
+ * @param ch Character to display.
+ */
+void putwchar(wchar_t ch)
+{
+	if (ch == '\n')
+		scons_sendb('\r');
+
+	if (ascii_check(ch))
+		scons_sendb((uint8_t) ch);
+	else
+		scons_sendb('?');
+}
+
+efi_status_t bootstrap(void *efi_handle_in,
+    efi_system_table_t *efi_system_table_in, void *load_address)
+{
+	efi_status_t status;
+	uint64_t current_el;
+	uint64_t memmap = 0;
+	sysarg_t memmap_size;
+	sysarg_t memmap_key;
+	sysarg_t memmap_descriptor_size;
+	uint32_t memmap_descriptor_version;
+	uint64_t alloc_addr = 0;
+	sysarg_t alloc_pages = 0;
+
+	/*
+	 * Bootinfo structure is dynamically allocated in the ARM64 port. It is
+	 * placed directly after the inflated components. This assures that if
+	 * the kernel identity maps the first gigabyte of the main memory in the
+	 * kernel/upper address space then it can access the bootinfo because
+	 * the inflated components and bootinfo can always fit in this area.
+	 */
+	bootinfo_t *bootinfo;
+
+	efi_system_table = efi_system_table_in;
+
+	version_print();
+
+	printf("Boot loader: %p -> %p\n", loader_start, loader_end);
+	printf("\nMemory statistics\n");
+	printf(" %p|%p: loader\n", load_address, load_address);
+	printf(" %p|%p: UEFI system table\n", efi_system_table_in,
+	    efi_system_table_in);
+
+	/* Validate the exception level. */
+	current_el = CurrentEL_read();
+	if (current_el != CURRENT_EL_EL1) {
+		printf("Error: Unexpected CurrentEL value %0#18" PRIx64 ".\n",
+		    current_el);
+		status = EFI_UNSUPPORTED;
+		goto fail;
+	}
+
+	/* Obtain memory map. */
+	status = efi_get_memory_map(efi_system_table, &memmap_size,
+	    (efi_v1_memdesc_t **) &memmap, &memmap_key, &memmap_descriptor_size,
+	    &memmap_descriptor_version);
+	if (status != EFI_SUCCESS) {
+		printf("Error: Unable to obtain initial memory map, status "
+		    "code: %" PRIx64 ".\n", status);
+		goto fail;
+	}
+
+	/* Find start of usable RAM. */
+	uint64_t memory_base = (uint64_t) -1;
+	for (sysarg_t i = 0; i < memmap_size / memmap_descriptor_size; i++) {
+		efi_v1_memdesc_t *desc = (void *) memmap +
+		    (i * memmap_descriptor_size);
+		if (get_memtype(desc->type) != MEMTYPE_AVAILABLE ||
+		    !(desc->attribute & EFI_MEMORY_WB))
+			continue;
+
+		if (desc->phys_start < memory_base)
+			memory_base = desc->phys_start;
+	}
+
+	/* Deallocate memory holding the map. */
+	efi_system_table->boot_services->free_pool((void *) memmap);
+	memmap = 0;
+
+	if (memory_base == (uint64_t) -1) {
+		printf("Error: Memory map does not contain any usable RAM.\n");
+		status = EFI_UNSUPPORTED;
+		goto fail;
+	}
+
+	/*
+	 * Check that everything is aligned on a 4kB boundary and the kernel can
+	 * be placed by the decompression code at a correct address.
+	 */
+
+	/* Statically check PAGE_SIZE and BOOT_OFFSET. */
+	_Static_assert(PAGE_SIZE == 4096, "PAGE_SIZE must be equal to 4096");
+	_Static_assert(IS_ALIGNED(BOOT_OFFSET, PAGE_SIZE),
+	    "BOOT_OFFSET must be a multiple of PAGE_SIZE");
+
+	/*
+	 * Dynamically check the memory base. The condition should be always
+	 * true because UEFI guarantees each physical/virtual address in the
+	 * memory map is aligned on a 4kB boundary.
+	 */
+	if (!IS_ALIGNED(memory_base, PAGE_SIZE)) {
+		printf("Error: Start of usable RAM (%p) is not aligned on a "
+		    "4kB boundary.\n", (void *) memory_base);
+		status = EFI_UNSUPPORTED;
+		goto fail;
+	}
+
+	/*
+	 * Calculate where the components (including the kernel) will get
+	 * placed.
+	 */
+	uint64_t decompress_base = memory_base + BOOT_OFFSET;
+	printf(" %p|%p: kernel entry point\n", (void *) decompress_base,
+	    (void *) decompress_base);
+
+	/*
+	 * Allocate memory for the decompressed components and for the bootinfo.
+	 */
+	uint64_t component_pages =
+	    ALIGN_UP(payload_unpacked_size(), EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
+	uint64_t bootinfo_pages = ALIGN_UP(sizeof(*bootinfo), EFI_PAGE_SIZE) /
+	    EFI_PAGE_SIZE;
+	alloc_pages = component_pages + bootinfo_pages;
+	alloc_addr = decompress_base;
+	status = efi_system_table->boot_services->allocate_pages(
+	    EFI_ALLOCATE_ADDRESS, EFI_LOADER_CODE, alloc_pages, &alloc_addr);
+	if (status != EFI_SUCCESS) {
+		printf("Error: Unable to allocate memory for inflated "
+		    "components and bootinfo, status code: %" PRIx64 ".\n",
+		    status);
+		goto fail;
+	}
+
+	bootinfo = (void *) alloc_addr + component_pages * EFI_PAGE_SIZE;
+	printf(" %p|%p: boot info structure\n", bootinfo, bootinfo);
+	memset(bootinfo, 0, sizeof(*bootinfo));
+
+	/* Decompress the components. */
+	uint8_t *kernel_dest = (uint8_t *) alloc_addr;
+	uint8_t *ram_end = kernel_dest + component_pages * EFI_PAGE_SIZE;
+
+	extract_payload(&bootinfo->taskmap, kernel_dest, ram_end,
+	    (uintptr_t) kernel_dest, ensure_visibility);
+
+	/* Get final memory map. */
+	status = efi_get_memory_map(efi_system_table, &memmap_size,
+	    (efi_v1_memdesc_t **) &memmap, &memmap_key, &memmap_descriptor_size,
+	    &memmap_descriptor_version);
+	if (status != EFI_SUCCESS) {
+		printf("Error: Unable to obtain final memory map, status code: "
+		    "%" PRIx64 ".\n", status);
+		goto fail;
+	}
+
+	/* Convert the UEFI memory map to the bootinfo representation. */
+	size_t cnt = 0;
+	memtype_t current_type = MEMTYPE_UNUSABLE;
+	void *current_start = 0;
+	size_t current_size = 0;
+	sysarg_t memmap_items_count = memmap_size / memmap_descriptor_size;
+	for (sysarg_t i = 0; i < memmap_items_count; i++) {
+		efi_v1_memdesc_t *desc = (void *) memmap +
+		    (i * memmap_descriptor_size);
+
+		/* Get type of the new area. */
+		memtype_t type;
+		if (!(desc->attribute & EFI_MEMORY_WB))
+			type = MEMTYPE_UNUSABLE;
+		else
+			type = get_memtype(desc->type);
+
+		/* Try to merge the new area with the previous one. */
+		if (type == current_type &&
+		    (uint64_t)current_start + current_size == desc->phys_start) {
+			current_size += desc->pages * EFI_PAGE_SIZE;
+			if (i != memmap_items_count - 1)
+				continue;
+		}
+
+		/* Record the previous area. */
+		if (current_type != MEMTYPE_UNUSABLE) {
+			if (cnt >= MEMMAP_MAX_RECORDS) {
+				printf("Error: Too many usable memory "
+				    "areas.\n");
+				status = EFI_UNSUPPORTED;
+				goto fail;
+			}
+			bootinfo->memmap.zones[cnt].type = current_type;
+			bootinfo->memmap.zones[cnt].start = current_start;
+			bootinfo->memmap.zones[cnt].size = current_size;
+			cnt++;
+		}
+
+		/* Remember the new area. */
+		current_type = type;
+		current_start = (void *) desc->phys_start;
+		current_size = desc->pages * EFI_PAGE_SIZE;
+	}
+	bootinfo->memmap.cnt = cnt;
+
+	uintptr_t entry = check_kernel_translated((void *) decompress_base,
+	    BOOT_OFFSET);
+
+	printf("Booting the kernel...\n");
+
+	/* Exit boot services. This is a point of no return. */
+	efi_system_table->boot_services->exit_boot_services(efi_handle_in,
+	    memmap_key);
+
+	entry = memory_base + KA2PA(entry);
+	jump_to_kernel((void *) entry, bootinfo);
+
+fail:
+	if (memmap != 0)
+		efi_system_table->boot_services->free_pool((void *) memmap);
+
+	if (alloc_addr != 0)
+		efi_system_table->boot_services->free_pages(alloc_addr,
+		    alloc_pages);
+
+	return status;
+}
+
+/** @}
+ */
Index: boot/arch/arm64/src/relocate.c
===================================================================
--- boot/arch/arm64/src/relocate.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/arch/arm64/src/relocate.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2019 Petr Pavlu
+ * 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 boot_arm64
+ * @{
+ */
+/** @file
+ * @brief Image self-relocation support.
+ */
+
+#include <arch/relocate.h>
+#include <printf.h>
+
+/** Self-relocate the bootloader.
+ *
+ * Note: This code is responsible for self-relocating the bootloader when it is
+ * started. As such, it is required that it is written in a way that it itself
+ * does not need any dynamic relocation.
+ */
+efi_status_t self_relocate(uintptr_t base, const elf_dyn_t *dyn)
+{
+	const elf_rela_t *rela = NULL;
+	uint64_t relasz = 0;
+	uint64_t relaent = 0;
+
+	/* Parse the dynamic array. */
+	while (dyn->d_tag != DT_NULL) {
+		switch (dyn->d_tag) {
+		case DT_RELA:
+			rela = (const elf_rela_t *) (base + dyn->d_un.d_ptr);
+			break;
+		case DT_RELASZ:
+			relasz = dyn->d_un.d_val;
+			break;
+		case DT_RELAENT:
+			relaent = dyn->d_un.d_val;
+			break;
+		}
+		dyn++;
+	}
+
+	/* Validate obtained information. */
+	if (rela == NULL)
+		return EFI_SUCCESS;
+	if (relaent == 0 || relasz % relaent != 0)
+		return EFI_UNSUPPORTED;
+
+	/* Process relocations in the image. */
+	while (relasz > 0) {
+		switch (ELF_R_TYPE(rela->r_info)) {
+		case R_AARCH64_RELATIVE:
+			*(uint64_t *) (base + rela->r_offset) =
+			    base + rela->r_addend;
+			break;
+		default:
+			return EFI_UNSUPPORTED;
+		}
+
+		rela = (const elf_rela_t *) ((const char *) rela + relaent);
+		relasz -= relaent;
+	}
+	return EFI_SUCCESS;
+}
+
+/** @}
+ */
Index: boot/arch/ia64/src/main.c
===================================================================
--- boot/arch/ia64/src/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ boot/arch/ia64/src/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -94,7 +94,20 @@
 		    cur += md_size) {
 			efi_v1_memdesc_t *md = (efi_v1_memdesc_t *) cur;
+			memmap_item_t *o = NULL;
+
+			if (items)
+				o = &memmap[items - 1];
 
 			switch ((efi_memory_type_t) md->type) {
+			case EFI_LOADER_CODE:
+			case EFI_LOADER_DATA:
+			case EFI_BOOT_SERVICES_CODE:
+			case EFI_BOOT_SERVICES_DATA:
 			case EFI_CONVENTIONAL_MEMORY:
+				if (o && o->type == MEMMAP_FREE_MEM &&
+				    o->base + o->size == md->phys_start) {
+					o->size += md->pages * EFI_PAGE_SIZE;
+					continue;
+				}
 				memmap[items].type = MEMMAP_FREE_MEM;
 				break;
Index: boot/arch/mips32/Makefile.inc
===================================================================
--- boot/arch/mips32/Makefile.inc	(revision c878693123930f0906703462cf2807430679517e)
+++ boot/arch/mips32/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -54,8 +54,10 @@
 	RD_DRVS_ESSENTIAL += \
 		platform/malta \
+		intctl/i8259 \
 		block/ata_bd \
 		bus/pci/pciintel \
 		bus/isa \
 		char/i8042 \
+		char/ns8250 \
 		hid/ps2mouse \
 		hid/xtkbd
Index: boot/doc/doxygroups.h
===================================================================
--- boot/doc/doxygroups.h	(revision c878693123930f0906703462cf2807430679517e)
+++ boot/doc/doxygroups.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -11,2 +11,6 @@
  *     @ingroup boot
  */
+
+/**    @addtogroup boot_arm64 arm64
+ *     @ingroup boot
+ */
Index: boot/genarch/include/genarch/efi.h
===================================================================
--- boot/genarch/include/genarch/efi.h	(revision c878693123930f0906703462cf2807430679517e)
+++ boot/genarch/include/genarch/efi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -32,4 +32,12 @@
 #include <arch/types.h>
 
+#define EFI_SUCCESS  0
+#define EFI_ERROR(code) (((sysarg_t) 1 << (sizeof(sysarg_t) * 8 - 1)) | (code))
+#define EFI_LOAD_ERROR  EFI_ERROR(1)
+#define EFI_UNSUPPORTED  EFI_ERROR(3)
+#define EFI_BUFFER_TOO_SMALL  EFI_ERROR(5)
+
+typedef uint64_t efi_status_t;
+
 typedef struct {
 	uint64_t signature;
@@ -56,24 +64,9 @@
 } efi_guid_t;
 
-typedef struct {
-	efi_guid_t guid;
-	void *table;
-} efi_configuration_table_t;
-
-typedef struct {
-	efi_table_header_t hdr;
-	char *fw_vendor;
-	uint32_t fw_revision;
-	void *cons_in_handle;
-	void *cons_in;
-	void *cons_out_handle;
-	void *cons_out;
-	void *cons_err_handle;
-	void *cons_err;
-	void *runtime_services;
-	void *boot_services;
-	sysarg_t conf_table_entries;
-	efi_configuration_table_t *conf_table;
-} efi_system_table_t;
+typedef enum {
+	EFI_ALLOCATE_ANY_PAGES,
+	EFI_ALLOCATE_MAX_ADDRESS,
+	EFI_ALLOCATE_ADDRESS
+} efi_allocate_type_t;
 
 typedef enum {
@@ -91,6 +84,20 @@
 	EFI_MEMORY_MAPPED_IO,
 	EFI_MEMORY_MAPPED_IO_PORT_SPACE,
-	EFI_PAL_CODE
+	EFI_PAL_CODE,
+	EFI_PERSISTENT_MEMORY
 } efi_memory_type_t;
+
+#define EFI_MEMORY_UC             UINT64_C(0x0000000000000001)
+#define EFI_MEMORY_WC             UINT64_C(0x0000000000000002)
+#define EFI_MEMORY_WT             UINT64_C(0x0000000000000004)
+#define EFI_MEMORY_WB             UINT64_C(0x0000000000000008)
+#define EFI_MEMORY_UCE            UINT64_C(0x0000000000000010)
+#define EFI_MEMORY_WP             UINT64_C(0x0000000000001000)
+#define EFI_MEMORY_RP             UINT64_C(0x0000000000002000)
+#define EFI_MEMORY_XP             UINT64_C(0x0000000000004000)
+#define EFI_MEMORY_NV             UINT64_C(0x0000000000008000)
+#define EFI_MEMORY_MORE_RELIABLE  UINT64_C(0x0000000000010000)
+#define EFI_MEMORY_RO             UINT64_C(0x0000000000020000)
+#define EFI_MEMORY_RUNTIME        UINT64_C(0x8000000000000000)
 
 typedef struct {
@@ -102,7 +109,94 @@
 } efi_v1_memdesc_t;
 
+typedef struct {
+	efi_guid_t guid;
+	void *table;
+} efi_configuration_table_t;
+
+typedef struct efi_simple_text_output_protocol {
+	void *reset;
+	efi_status_t (*output_string)(struct efi_simple_text_output_protocol *,
+	    int16_t *);
+	void *test_string;
+	void *query_mode;
+	void *set_mode;
+	void *set_attribute;
+	void *clear_screen;
+	void *set_cursor_position;
+	void *enable_cursor;
+	void *mode;
+} efi_simple_text_output_protocol_t;
+
+typedef struct {
+	efi_table_header_t hdr;
+	void *raise_TPL;
+	void *restore_TPL;
+	efi_status_t (*allocate_pages)(efi_allocate_type_t, efi_memory_type_t,
+	    sysarg_t, uint64_t *);
+	efi_status_t (*free_pages)(uint64_t, sysarg_t);
+	efi_status_t (*get_memory_map)(sysarg_t *, efi_v1_memdesc_t *,
+	    sysarg_t *, sysarg_t *, uint32_t *);
+	efi_status_t (*allocate_pool)(efi_memory_type_t, sysarg_t, void **);
+	efi_status_t (*free_pool)(void *);
+	void *create_event;
+	void *set_timer;
+	void *wait_for_event;
+	void *signal_event;
+	void *close_event;
+	void *check_event;
+	void *install_protocol_interface;
+	void *reinstall_protocol_interface;
+	void *uninstall_protocol_interface;
+	void *handle_protocol;
+	void *reserved;
+	void *register_protocol_notify;
+	void *locate_handle;
+	void *locate_device_path;
+	void *install_configuration_table;
+	void *load_image;
+	void *start_image;
+	void *exit;
+	void *unload_image;
+	efi_status_t (*exit_boot_services)(void *, sysarg_t);
+	void *get_next_monotonic_count;
+	void *stall;
+	void *set_watchdog_timer;
+	void *connect_controller;
+	void *disconnect_controller;
+	void *open_protocol;
+	void *close_protocol;
+	void *open_protocol_information;
+	void *protocols_per_handle;
+	void *locate_handle_buffer;
+	void *locate_protocol;
+	void *install_multiple_protocol_interfaces;
+	void *uninstall_multiple_protocol_intefaces;
+	void *calculate_crc32;
+	void *copy_mem;
+	void *set_mem;
+	void *create_event_ex;
+} efi_boot_services_t;
+
+typedef struct {
+	efi_table_header_t hdr;
+	char *fw_vendor;
+	uint32_t fw_revision;
+	void *cons_in_handle;
+	void *cons_in;
+	void *cons_out_handle;
+	efi_simple_text_output_protocol_t *cons_out;
+	void *cons_err_handle;
+	efi_simple_text_output_protocol_t *cons_err;
+	void *runtime_services;
+	efi_boot_services_t *boot_services;
+	sysarg_t conf_table_entries;
+	efi_configuration_table_t *conf_table;
+} efi_system_table_t;
+
 #define EFI_PAGE_SIZE	4096
 
 extern void *efi_vendor_table_find(efi_system_table_t *, efi_guid_t);
+extern efi_status_t efi_get_memory_map(efi_system_table_t *, sysarg_t *,
+    efi_v1_memdesc_t **, sysarg_t *, sysarg_t *, uint32_t *);
 
 #endif
Index: boot/genarch/src/efi.c
===================================================================
--- boot/genarch/src/efi.c	(revision c878693123930f0906703462cf2807430679517e)
+++ boot/genarch/src/efi.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -42,2 +42,30 @@
 	return NULL;
 }
+
+efi_status_t efi_get_memory_map(efi_system_table_t *st,
+    sysarg_t *memory_map_size, efi_v1_memdesc_t **memory_map, sysarg_t *map_key,
+    sysarg_t *descriptor_size, uint32_t *descriptor_version)
+{
+	efi_status_t status;
+
+	*memory_map_size = 8 * sizeof(**memory_map);
+
+	do {
+		/* Allocate space for the memory map. */
+		status = st->boot_services->allocate_pool(EFI_LOADER_DATA,
+		    *memory_map_size, (void **) memory_map);
+		if (status != EFI_SUCCESS)
+			return status;
+
+		/* Try to obtain the map. */
+		status = st->boot_services->get_memory_map(memory_map_size,
+		    *memory_map, map_key, descriptor_size, descriptor_version);
+		if (status == EFI_SUCCESS)
+			return status;
+
+		/* An error occurred, release the allocated memory. */
+		st->boot_services->free_pool(*memory_map);
+	} while (status == EFI_BUFFER_TOO_SMALL);
+
+	return status;
+}
Index: boot/generic/include/align.h
===================================================================
--- boot/generic/include/align.h	(revision c878693123930f0906703462cf2807430679517e)
+++ boot/generic/include/align.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -49,4 +49,11 @@
 #define ALIGN_UP(s, a)  (((s) + ((a) - 1)) & ~((a) - 1))
 
+/** Check alignment.
+ *
+ * @param s Address or size to be checked for alignment.
+ * @param a Size of alignment, must be a power of 2.
+ */
+#define IS_ALIGNED(s, a)  (ALIGN_UP((s), (a)) == (s))
+
 #endif
 
Index: boot/generic/include/byteorder.h
===================================================================
--- boot/generic/include/byteorder.h	(revision c878693123930f0906703462cf2807430679517e)
+++ boot/generic/include/byteorder.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_BYTEORDER_H_
-#define LIBC_BYTEORDER_H_
+#ifndef _LIBC_BYTEORDER_H_
+#define _LIBC_BYTEORDER_H_
 
 #include <stdint.h>
Index: boot/generic/include/errno.h
===================================================================
--- boot/generic/include/errno.h	(revision c878693123930f0906703462cf2807430679517e)
+++ boot/generic/include/errno.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -40,4 +40,6 @@
 #define EOVERFLOW  -16  /* The result does not fit its size. */
 
+typedef int errno_t;
+
 #endif
 
Index: boot/generic/include/str.h
===================================================================
--- boot/generic/include/str.h	(revision c878693123930f0906703462cf2807430679517e)
+++ boot/generic/include/str.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,6 @@
 /*
- * Copyright (c) 2010 Martin Decky
+ * Copyright (c) 2001-2004 Jakub Jermar
+ * Copyright (c) 2005 Martin Decky
+ * Copyright (c) 2011 Oleg Romanenko
  * All rights reserved.
  *
@@ -33,25 +35,26 @@
 #define BOOT_STR_H_
 
+#include <errno.h>
 #include <stdbool.h>
 #include <stddef.h>
 
-/**< Common Unicode characters */
-#define U_SPECIAL  '?'
+/* Common Unicode characters */
+#define U_SPECIAL      '?'
 
-/**< No size limit constant */
+/** No size limit constant */
 #define STR_NO_LIMIT  ((size_t) -1)
 
-extern wchar_t str_decode(const char *, size_t *, size_t);
-extern int chr_encode(wchar_t, char *, size_t *, size_t);
+extern wchar_t str_decode(const char *str, size_t *offset, size_t sz);
+extern errno_t chr_encode(wchar_t ch, char *str, size_t *offset, size_t sz);
 
-extern size_t str_size(const char *);
-extern size_t str_lsize(const char *, size_t);
-extern size_t str_length(const char *);
+extern size_t str_size(const char *str);
+extern size_t str_lsize(const char *str, size_t max_len);
+extern size_t str_length(const char *str);
 
-extern bool ascii_check(wchar_t);
-extern bool chr_check(wchar_t);
+extern bool ascii_check(wchar_t ch);
+extern bool chr_check(wchar_t ch);
 
-extern int str_cmp(const char *, const char *);
-extern void str_cpy(char *, size_t, const char *);
+extern int str_cmp(const char *s1, const char *s2);
+extern void str_cpy(char *dest, size_t size, const char *src);
 
 #endif
Index: boot/generic/src/str.c
===================================================================
--- boot/generic/src/str.c	(revision c878693123930f0906703462cf2807430679517e)
+++ boot/generic/src/str.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,8 @@
 /*
  * Copyright (c) 2001-2004 Jakub Jermar
+ * Copyright (c) 2005 Martin Decky
+ * Copyright (c) 2008 Jiri Svoboda
+ * Copyright (c) 2011 Martin Sucha
+ * Copyright (c) 2011 Oleg Romanenko
  * All rights reserved.
  *
@@ -98,9 +102,10 @@
  */
 
+#include <str.h>
+
 #include <errno.h>
 #include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
-#include <str.h>
 
 /** Check the condition if wchar_t is signed */
@@ -208,5 +213,5 @@
  *         code was invalid.
  */
-int chr_encode(const wchar_t ch, char *str, size_t *offset, size_t size)
+errno_t chr_encode(const wchar_t ch, char *str, size_t *offset, size_t size)
 {
 	if (*offset >= size)
@@ -392,5 +397,5 @@
 			return 1;
 
-		if ((c1 == 0) || (c2 == 0))
+		if (c1 == 0 || c2 == 0)
 			break;
 	}
Index: ot/grub.efi/COPYING
===================================================================
--- boot/grub.efi/COPYING	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,674 +1,0 @@
-                    GNU GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.  We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors.  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-  To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights.  Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received.  You must make sure that they, too, receive
-or can get the source code.  And you must show them these terms so they
-know their rights.
-
-  Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
-  For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software.  For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
-  Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so.  This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software.  The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable.  Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products.  If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
-  Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary.  To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                       TERMS AND CONDITIONS
-
-  0. Definitions.
-
-  "This License" refers to version 3 of the GNU General Public License.
-
-  "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
-  "The Program" refers to any copyrightable work licensed under this
-License.  Each licensee is addressed as "you".  "Licensees" and
-"recipients" may be individuals or organizations.
-
-  To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy.  The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
-  A "covered work" means either the unmodified Program or a work based
-on the Program.
-
-  To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy.  Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-  To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies.  Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
-  An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License.  If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-  1. Source Code.
-
-  The "source code" for a work means the preferred form of the work
-for making modifications to it.  "Object code" means any non-source
-form of a work.
-
-  A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-  The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form.  A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-  The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities.  However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work.  For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-  The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
-  The Corresponding Source for a work in source code form is that
-same work.
-
-  2. Basic Permissions.
-
-  All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met.  This License explicitly affirms your unlimited
-permission to run the unmodified Program.  The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work.  This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-  You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force.  You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright.  Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-  Conveying under any other circumstances is permitted solely under
-the conditions stated below.  Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-  No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-  When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
-  4. Conveying Verbatim Copies.
-
-  You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-  You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-  You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
-    a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
-
-    b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under section
-    7.  This requirement modifies the requirement in section 4 to
-    "keep intact all notices".
-
-    c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy.  This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged.  This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
-
-    d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
-
-  A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit.  Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-  You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
-    a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
-
-    b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the
-    Corresponding Source from a network server at no charge.
-
-    c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source.  This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
-
-    d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge.  You need not require recipients to copy the
-    Corresponding Source along with the object code.  If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source.  Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
-
-    e) Convey the object code using peer-to-peer transmission, provided
-    you inform other peers where the object code and Corresponding
-    Source of the work are being offered to the general public at no
-    charge under subsection 6d.
-
-  A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-  A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling.  In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage.  For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product.  A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
-  "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source.  The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
-  If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information.  But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-  The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed.  Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
-  Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-  7. Additional Terms.
-
-  "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law.  If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-  When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it.  (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.)  You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-  Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
-    a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
-
-    b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
-
-    c) Prohibiting misrepresentation of the origin of that material, or
-    requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
-
-    d) Limiting the use for publicity purposes of names of licensors or
-    authors of the material; or
-
-    e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
-
-    f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions of
-    it) with contractual assumptions of liability to the recipient, for
-    any liability that these contractual assumptions directly impose on
-    those licensors and authors.
-
-  All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10.  If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term.  If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-  If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-  Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
-  8. Termination.
-
-  You may not propagate or modify a covered work except as expressly
-provided under this License.  Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-  However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
-  Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-  Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License.  If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-  You are not required to accept this License in order to receive or
-run a copy of the Program.  Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance.  However,
-nothing other than this License grants you permission to propagate or
-modify any covered work.  These actions infringe copyright if you do
-not accept this License.  Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-  Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License.  You are not responsible
-for enforcing compliance by third parties with this License.
-
-  An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations.  If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-  You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License.  For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-  11. Patents.
-
-  A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based.  The
-work thus licensed is called the contributor's "contributor version".
-
-  A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version.  For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-  In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement).  To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-  If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients.  "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-  If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-  A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License.  You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
-  Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-  If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all.  For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
-  13. Use with the GNU Affero General Public License.
-
-  Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work.  The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
-  14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-  Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation.  If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
-  If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
-  Later license versions may give you additional or different
-permissions.  However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-  15. Disclaimer of Warranty.
-
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-  If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
-    <program>  Copyright (C) <year>  <name of author>
-    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
-  You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
-  The GNU General Public License does not permit incorporating your program
-into proprietary programs.  If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.  But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
Index: ot/grub.efi/README
===================================================================
--- boot/grub.efi/README	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,12 +1,0 @@
-The binary files of GRUB boot loader in this directory have been created
-by compiling GRUB for the 'i386-efi' and 'x86_64-efi' targets. The combined
-32bit and 64bit EFI boot floppy image was created by modifying the
-i386-grub-mkrescue and x86_64-grub-mkrescue scripts to create EFI payloads
-which search for the bootable ISO image with the volume label
-'HelenOS boot ISO'.
-
-For licensing terms of GRUB boot loader see the file COPYING contained
-in this directory. Full version of GRUB, including its source code,
-can be downloaded from GRUB's project page:
-
-http://www.gnu.org/software/grub/
Index: ot/grub.efi/REVISION
===================================================================
--- boot/grub.efi/REVISION	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,1 +1,0 @@
-bc220962e366b1b46769ed6f9fa5be603ba58ab5
Index: ot/grub.efi/i386-efi/command.lst
===================================================================
--- boot/grub.efi/i386-efi/command.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,190 +1,0 @@
-*acpi: acpi
-*all_functional_test: functional_test
-*background_image: gfxterm_background
-*cat: cat
-*cpuid: cpuid
-*crc: hashsum
-*cryptomount: cryptodisk
-*echo: echo
-*extract_syslinux_entries_configfile: syslinuxcfg
-*extract_syslinux_entries_source: syslinuxcfg
-*file: file
-*functional_test: functional_test
-*gettext: gettext
-*hashsum: hashsum
-*hdparm: hdparm
-*hello: hello
-*help: help
-*hexdump: hexdump
-*inb: iorw
-*inl: iorw
-*inw: iorw
-*keystatus: keystatus
-*kfreebsd: bsd
-*knetbsd: bsd
-*kopenbsd: bsd
-*list_env: loadenv
-*load_env: loadenv
-*loopback: loopback
-*ls: ls
-*lsacpi: lsacpi
-*lspci: lspci
-*md5sum: hashsum
-*menuentry: normal
-*pcidump: pcidump
-*probe: probe
-*read_byte: memrw
-*read_dword: memrw
-*read_word: memrw
-*regexp: regexp
-*save_env: loadenv
-*search: search
-*serial: serial
-*setpci: setpci
-*sha1sum: hashsum
-*sha256sum: hashsum
-*sha512sum: hashsum
-*sleep: sleep
-*submenu: normal
-*syslinux_configfile: syslinuxcfg
-*syslinux_source: syslinuxcfg
-*terminfo: terminfo
-*test_blockarg: test_blockarg
-*testspeed: testspeed
-*tr: tr
-*trust: verify
-*verify_detached: verify
-*xnu_splash: xnu
-*zfskey: zfscrypt
-.: configfile
-[: test
-appleloader: appleldr
-authenticate: normal
-background_color: gfxterm_background
-backtrace: backtrace
-badram: mmap
-blocklist: blocklist
-boot: boot
-break: normal
-cat: minicmd
-cbmemc: cbmemc
-chainloader: chain
-clear: normal
-cmp: cmp
-configfile: configfile
-continue: normal
-coreboot_boottime: cbtime
-cutmem: mmap
-date: date
-distrust: verify
-dump: minicmd
-eval: eval
-exit: minicmd
-export: normal
-extract_entries_configfile: configfile
-extract_entries_source: configfile
-extract_legacy_entries_configfile: legacycfg
-extract_legacy_entries_source: legacycfg
-fakebios: loadbios
-false: true
-fix_video: fixvideo
-fwsetup: efifwsetup
-gdbstub: gdb
-gdbstub_break: gdb
-gdbstub_stop: gdb
-gptsync: gptsync
-halt: halt
-help: minicmd
-hexdump_random: random
-initrd16: linux16
-initrd: linux
-keymap: keylayouts
-kfreebsd_loadenv: bsd
-kfreebsd_module: bsd
-kfreebsd_module_elf: bsd
-knetbsd_module: bsd
-knetbsd_module_elf: bsd
-kopenbsd_ramdisk: bsd
-legacy_check_password: legacycfg
-legacy_configfile: legacycfg
-legacy_initrd: legacycfg
-legacy_initrd_nounzip: legacycfg
-legacy_kernel: legacycfg
-legacy_password: legacycfg
-legacy_source: legacycfg
-linux16: linux16
-linux: linux
-list_trusted: verify
-loadbios: loadbios
-loadfont: font
-lscoreboot: cbls
-lsefi: lsefi
-lsefimmap: lsefimmap
-lsefisystab: lsefisystab
-lsfonts: font
-lsmmap: lsmmap
-lsmod: minicmd
-lssal: lssal
-macppcbless: macbless
-mactelbless: macbless
-module2: multiboot2
-module: multiboot
-multiboot2: multiboot2
-multiboot: multiboot
-nativedisk: nativedisk
-net_add_addr: net
-net_add_dns: net
-net_add_route: net
-net_bootp: net
-net_del_addr: net
-net_del_dns: net
-net_del_route: net
-net_get_dhcp_option: net
-net_ipv6_autoconf: net
-net_ls_addr: net
-net_ls_cards: net
-net_ls_dns: net
-net_ls_routes: net
-net_nslookup: net
-normal: normal
-normal_exit: normal
-outb: iorw
-outl: iorw
-outw: iorw
-parttool: parttool
-password: password
-password_pbkdf2: password_pbkdf2
-play: play
-read: read
-reboot: reboot
-return: normal
-rmmod: minicmd
-search.file: search_fs_file
-search.fs_label: search_label
-search.fs_uuid: search_fs_uuid
-setparams: normal
-shift: normal
-source: configfile
-terminal_input: terminal
-terminal_output: terminal
-test: test
-testload: testload
-time: time
-true: true
-usb: usbtest
-videoinfo: videoinfo
-videotest: videotest
-write_byte: memrw
-write_dword: memrw
-write_word: memrw
-xnu_devprop_load: xnu
-xnu_kernel64: xnu
-xnu_kernel: xnu
-xnu_kext: xnu
-xnu_kextdir: xnu
-xnu_mkext: xnu
-xnu_ramdisk: xnu
-xnu_resume: xnu
-xnu_uuid: xnu_uuid
-zfs-bootfs: zfsinfo
-zfsinfo: zfsinfo
Index: ot/grub.efi/i386-efi/crypto.lst
===================================================================
--- boot/grub.efi/i386-efi/crypto.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,45 +1,0 @@
-RIJNDAEL: gcry_rijndael
-RIJNDAEL192: gcry_rijndael
-RIJNDAEL256: gcry_rijndael
-AES128: gcry_rijndael
-AES-128: gcry_rijndael
-AES-192: gcry_rijndael
-AES-256: gcry_rijndael
-ADLER32: adler32
-CRC64: crc64
-ARCFOUR: gcry_arcfour
-BLOWFISH: gcry_blowfish
-CAMELLIA128: gcry_camellia
-CAMELLIA192: gcry_camellia
-CAMELLIA256: gcry_camellia
-CAST5: gcry_cast5
-CRC32: gcry_crc
-CRC32RFC1510: gcry_crc
-CRC24RFC2440: gcry_crc
-DES: gcry_des
-3DES: gcry_des
-DSA: gcry_dsa
-IDEA: gcry_idea
-MD4: gcry_md4
-MD5: gcry_md5
-RFC2268_40: gcry_rfc2268
-AES: gcry_rijndael
-AES192: gcry_rijndael
-AES256: gcry_rijndael
-RIPEMD160: gcry_rmd160
-RSA: gcry_rsa
-SEED: gcry_seed
-SERPENT128: gcry_serpent
-SERPENT192: gcry_serpent
-SERPENT256: gcry_serpent
-SHA1: gcry_sha1
-SHA224: gcry_sha256
-SHA256: gcry_sha256
-SHA512: gcry_sha512
-SHA384: gcry_sha512
-TIGER192: gcry_tiger
-TIGER: gcry_tiger
-TIGER2: gcry_tiger
-TWOFISH: gcry_twofish
-TWOFISH128: gcry_twofish
-WHIRLPOOL: gcry_whirlpool
Index: ot/grub.efi/i386-efi/fs.lst
===================================================================
--- boot/grub.efi/i386-efi/fs.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,36 +1,0 @@
-affs
-afs
-bfs
-btrfs
-cbfs
-cpio
-cpio_be
-exfat
-ext2
-fat
-hfs
-hfsplus
-iso9660
-jfs
-minix
-minix2
-minix2_be
-minix3
-minix3_be
-minix_be
-newc
-nilfs2
-ntfs
-odc
-procfs
-reiserfs
-romfs
-sfs
-squash4
-tar
-udf
-ufs1
-ufs1_be
-ufs2
-xfs
-zfs
Index: ot/grub.efi/i386-efi/gdb_grub
===================================================================
--- boot/grub.efi/i386-efi/gdb_grub	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,85 +1,0 @@
-###
-### Load debuging information about GNU GRUB 2 modules into GDB
-### automatically. Needs readelf, Perl and gmodule.pl script
-###
-### Has to be launched from the writable and trusted
-### directory containing *.image and *.module
-###
-### $Id: .gdbinit,v 1.1 2006/05/14 11:38:08 lkundrak Exp $
-### Lubomir Kundrak <lkudrak@skosi.org>
-###
-
-# Add section numbers and addresses to .segments.tmp
-define dump_module_sections
-	set $mod = $arg0
-
-	# FIXME: save logging status
-	set logging file .segments.tmp
-	set logging redirect on
-	set logging overwrite off
-	set logging on
-
-	printf "%s", $mod->name
-	set $segment = $mod->segment
-	while ($segment)
-		printf " %i 0x%lx", $segment->section, $segment->addr
-		set $segment = $segment->next
-	end
-	printf "\n"
-
-	set logging off
-	# FIXME: restore logging status
-end
-document dump_module_sections
-	Gather information about module whose mod structure was
-	given for use with match_and_load_symbols
-end
-
-# Generate and execute GDB commands and delete temporary files
-# afterwards
-define match_and_load_symbols
-	shell perl gmodule.pl <.segments.tmp >.loadsym.gdb
-	source .loadsym.gdb
-	shell rm -f .segments.tmp .loadsym.gdb
-end
-document match_and_load_symbols
-	Launch script, that matches section names with information
-	generated by dump_module_sections and load debugging info
-	apropriately
-end
-
-###
-
-define load_module
-	dump_module_sections $arg0
-	match_and_load_symbols
-end
-document load_module
-	Load debugging information for module given as argument.
-end
-
-define load_all_modules
-	set $this = grub_dl_head
-	while ($this != 0)
-		dump_module_sections $this
-		set $this = $this->next
-	end
-	match_and_load_symbols
-end
-document load_all_modules
-	Load debugging information for all loaded modules.
-end
-
-###
-
-set confirm off
-file kernel.exec
-target remote :1234
-
-# inform when module is loaded
-break grub_dl_add
-commands
-	silent
-	load_module mod
-	cont
-end
Index: ot/grub.efi/i386-efi/gmodule.pl
===================================================================
--- boot/grub.efi/i386-efi/gmodule.pl	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,30 +1,0 @@
-###
-### Generate GDB commands, that load symbols for specified module,
-### with proper section relocations. See .gdbinit
-###
-### $Id: gmodule.pl,v 1.2 2006/05/14 11:38:42 lkundrak Exp lkundrak $
-### Lubomir Kundrak <lkudrak@skosi.org>
-###
-
-use strict;
-
-while (<>) {
-	my ($name, %sections) = split;
-
-	print "add-symbol-file $name.module";
-
-	open (READELF, "readelf -S $name.mod |") or die;
-	while (<READELF>) {
-		/\[\s*(\d+)\]\s+(\.\S+)/ or next;
-
-		if ($2 eq '.text') {
-			print " $sections{$1}";
-			next;
-		}
-
-		print " -s $2 $sections{$1}"
-			if ($sections{$1} ne '0x0' and $sections{$1} ne '');
-	};
-	close (READELF);
-	print "\n";
-}
Index: ot/grub.efi/i386-efi/moddep.lst
===================================================================
--- boot/grub.efi/i386-efi/moddep.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,257 +1,0 @@
-videotest: font video gfxmenu
-odc: archelp
-loopback: extcmd
-macho:
-gcry_des: crypto
-memrw: extcmd
-terminfo: extcmd
-part_gpt:
-romfs: fshelp
-read:
-lsefimmap:
-aout:
-gcry_arcfour: crypto
-tftp: net priority_queue
-newc: archelp
-minix2_be:
-elf:
-videotest_checksum: font functional_test video_fb
-password_pbkdf2: crypto gcry_sha512 pbkdf2 normal
-gcry_seed: crypto
-pcidump: extcmd
-bsd: elf serial crypto gcry_md5 extcmd video boot aout cpuid relocator mmap
-sfs: fshelp
-reiserfs: fshelp
-part_sunpc:
-gfxmenu: video_colors trig bitmap_scale gfxterm font normal video bitmap
-backtrace:
-jfs:
-help: extcmd normal
-configfile: normal
-cbls: cbtable
-gfxterm_menu: font functional_test procfs normal video_fb
-gcry_idea: crypto
-tr: extcmd
-shift_test: functional_test
-ohci: cs5536 usb boot
-afs: fshelp
-spkmodem: terminfo
-usb_keyboard: usb keylayouts
-xzio: crypto
-syslinuxcfg: extcmd normal
-search_fs_file:
-usbms: scsi usb
-test_blockarg: extcmd normal
-true:
-affs: fshelp
-iso9660: fshelp
-exfat: fshelp
-setjmp_test: functional_test setjmp
-gfxterm: font video
-efinet: net
-disk:
-appleldr: boot
-xfs: fshelp
-testspeed: extcmd normal
-cpio_be: archelp
-functional_test: btrfs extcmd video video_fb
-bswap_test: functional_test
-sleep: extcmd normal
-memdisk:
-gcry_rijndael: crypto
-mdraid09_be: diskfilter
-gettext:
-gcry_sha1: crypto
-hfspluscomp: gzio hfsplus
-cmp:
-random: hexdump
-offsetio:
-file: macho elf extcmd offsetio
-usbserial_usbdebug: serial usb usbserial_common
-video_colors:
-morse:
-hashsum: crypto extcmd normal
-usb:
-halt: acpi
-gdb: serial backtrace
-gfxterm_background: video_colors bitmap_scale gfxterm extcmd video bitmap
-search_fs_uuid:
-gcry_dsa: verify mpi
-keystatus: extcmd
-linux: video boot relocator mmap
-geli: cryptodisk crypto gcry_sha512 pbkdf2 gcry_sha256
-cmdline_cat_test: font functional_test procfs normal video_fb
-part_sun:
-cbtable:
-pbkdf2_test: functional_test pbkdf2 gcry_sha1
-video_bochs: video video_fb
-bufio:
-usbserial_ftdi: serial usb usbserial_common
-legacy_password_test: functional_test legacycfg
-cpuid: extcmd
-bfs: fshelp
-hdparm: extcmd
-gcry_blowfish: crypto
-test:
-nilfs2: fshelp
-gcry_rsa: verify mpi
-cryptodisk: crypto extcmd procfs
-nativedisk:
-minicmd:
-signature_test: functional_test procfs
-ata: scsi
-udf: fshelp
-gzio:
-xnu_uuid: gcry_md5
-uhci: usb
-pata: ata
-mul_test: functional_test
-adler32: crypto
-terminal:
-div:
-ehci: cs5536 usb boot
-crypto:
-part_bsd: part_msdos
-cs5536:
-gcry_sha512: crypto
-password: crypto normal
-fshelp:
-sleep_test: functional_test datetime
-iorw: extcmd
-xnu: macho bitmap_scale random extcmd video bitmap boot relocator mmap
-mmap:
-exfctest: functional_test
-zfsinfo: zfs
-ldm: part_gpt diskfilter part_msdos
-eval: normal
-part_dvh:
-lssal:
-ext2: fshelp
-blocklist:
-net: priority_queue bufio datetime boot
-part_acorn:
-videoinfo: video
-btrfs: lzopio gzio
-lsmmap: mmap
-bitmap:
-ntfs: fshelp
-multiboot: net video boot relocator mmap
-gcry_crc: crypto
-png: bufio bitmap
-jpeg: bufio bitmap
-macbless: disk
-div_test: functional_test div
-regexp: extcmd normal
-parttool: normal
-usbserial_pl2303: serial usb usbserial_common
-cpio: archelp
-gcry_rmd160: crypto
-fat: fshelp
-ufs1_be:
-archelp:
-raid6rec: diskfilter
-http: net
-zfs: gzio
-lsefisystab:
-minix2:
-lsacpi: extcmd acpi
-datehook: datetime normal
-loadenv: disk extcmd
-bitmap_scale: bitmap
-probe: extcmd
-minix3:
-tar: archelp
-loadbios:
-hfs: fshelp
-procfs: archelp
-boot:
-keylayouts:
-progress: normal
-kernel:
-usbtest: usb
-relocator: mmap
-acpi: extcmd mmap
-tga: bufio bitmap
-reboot: relocator
-serial: extcmd terminfo
-zfscrypt: crypto pbkdf2 zfs extcmd gcry_sha1 gcry_rijndael
-efi_uga: video video_fb
-dm_nv: diskfilter
-cmp_test: functional_test
-luks: cryptodisk crypto pbkdf2
-font: bufio video
-raid5rec: diskfilter
-crc64: crypto
-datetime:
-efifwsetup: reboot
-ctz_test: functional_test
-video:
-cbmemc: normal cbtable terminfo
-hfsplus: fshelp
-gcry_cast5: crypto
-extcmd:
-squash4: fshelp lzopio xzio gzio
-part_plan:
-minix_be:
-gcry_whirlpool: crypto
-gcry_tiger: crypto
-fixvideo:
-search: search_fs_uuid search_fs_file extcmd search_label
-lspci: extcmd
-cbtime: cbtable
-video_fb:
-verify: crypto extcmd mpi gcry_sha1
-minix3_be:
-trig:
-msdospart: disk parttool
-priority_queue:
-gcry_twofish: crypto
-part_dfly:
-xnu_uuid_test: functional_test
-diskfilter:
-testload:
-part_apple:
-hexdump: extcmd
-date: datetime normal
-pbkdf2: crypto
-gcry_sha256: crypto
-ls: extcmd normal
-usbserial_common: serial usb
-ntfscomp: ntfs
-lzopio: crypto
-video_cirrus: video video_fb
-hello: extcmd
-scsi:
-cat: extcmd
-ahci: ata boot
-normal: terminal crypto bufio extcmd boot gettext
-linux16: video boot relocator mmap
-ufs1:
-mdraid09: diskfilter
-lvm: diskfilter
-chain: net efinet boot
-cbfs: archelp
-ufs2:
-time:
-setpci: extcmd
-gptsync: disk
-search_label:
-setjmp:
-multiboot2: net video boot relocator mmap acpi
-gcry_rfc2268: crypto
-mdraid1x: diskfilter
-mpi: crypto
-legacycfg: password crypto gcry_md5 normal
-play:
-part_amiga:
-efi_gop: video video_fb
-minix:
-echo: extcmd
-lsefi:
-gcry_serpent: crypto
-gcry_md4: crypto
-gcry_md5: crypto
-part_msdos:
-gcry_camellia: crypto
-at_keyboard: keylayouts boot
-all_video: efi_gop efi_uga video_bochs video_cirrus
Index: ot/grub.efi/i386-efi/modinfo.sh
===================================================================
--- boot/grub.efi/i386-efi/modinfo.sh	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,40 +1,0 @@
-#!/bin/sh
-
-# User-controllable options
-grub_modinfo_target_cpu=i386
-grub_modinfo_platform=efi
-grub_disk_cache_stats=0
-grub_boot_time_stats=0
-grub_have_font_source=1
-
-# Autodetected config
-grub_have_asm_uscore=0
-grub_bss_start_symbol="__bss_start"
-grub_end_symbol="end"
-
-# Build environment
-grub_target_cc='gcc'
-grub_target_cc_version='gcc (SUSE Linux) 4.8.5'
-grub_target_cflags=' -Os -Wall -W -Wshadow -Wpointer-arith -Wundef -Wchar-subscripts -Wcomment -Wdeprecated-declarations -Wdisabled-optimization -Wdiv-by-zero -Wfloat-equal -Wformat-extra-args -Wformat-security -Wformat-y2k -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Wmain -Wmissing-braces -Wmissing-format-attribute -Wmultichar -Wparentheses -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wswitch -Wtrigraphs -Wunknown-pragmas -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value  -Wunused-variable -Wwrite-strings -Wnested-externs -Wstrict-prototypes -g -Wredundant-decls -Wmissing-prototypes -Wmissing-declarations  -Wextra -Wattributes -Wendif-labels -Winit-self -Wint-to-pointer-cast -Winvalid-pch -Wmissing-field-initializers -Wnonnull -Woverflow -Wvla -Wpointer-to-int-cast -Wstrict-aliasing -Wvariadic-macros -Wvolatile-register-var -Wpointer-sign -Wmissing-include-dirs -Wmissing-prototypes -Wmissing-declarations -Wformat=2 -march=i386 -m32 -falign-jumps=1 -falign-loops=1 -falign-functions=1 -freg-struct-return -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow -msoft-float -fno-dwarf2-cfi-asm -mno-stack-arg-probe -fno-asynchronous-unwind-tables -fno-unwind-tables -Qn -fno-stack-protector -Wtrampolines -Werror'
-grub_target_cppflags=' -Wall -W  -DGRUB_MACHINE_EFI=1 -DGRUB_MACHINE=I386_EFI -m32 -nostdinc -isystem /usr/lib64/gcc/x86_64-suse-linux/4.8/include -I$(top_srcdir)/include -I$(top_builddir)/include'
-grub_target_ccasflags=' -g  -m32 -msoft-float'
-grub_target_ldflags=' -m32 -Wl,-melf_i386 -Wl,--build-id=none'
-grub_cflags=''
-grub_cppflags=' -D_FILE_OFFSET_BITS=64'
-grub_ccasflags=''
-grub_ldflags=''
-grub_target_strip='strip'
-grub_target_nm='nm'
-grub_target_ranlib='ranlib'
-grub_target_objconf=''
-grub_target_obj2elf=''
-grub_target_img_base_ldopt='-Wl,-Ttext'
-grub_target_img_ldflags='@TARGET_IMG_BASE_LDFLAGS@'
-
-# Version
-grub_version="2.02~beta2"
-grub_package="grub"
-grub_package_string="GRUB 2.02~beta2"
-grub_package_version="2.02~beta2"
-grub_package_name="GRUB"
-grub_package_bugreport="bug-grub@gnu.org"
Index: ot/grub.efi/i386-efi/partmap.lst
===================================================================
--- boot/grub.efi/i386-efi/partmap.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,11 +1,0 @@
-part_acorn
-part_amiga
-part_apple
-part_bsd
-part_dfly
-part_dvh
-part_gpt
-part_msdos
-part_plan
-part_sun
-part_sunpc
Index: ot/grub.efi/i386-efi/parttool.lst
===================================================================
--- boot/grub.efi/i386-efi/parttool.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,1 +1,0 @@
-msdos: msdospart
Index: ot/grub.efi/i386-efi/terminal.lst
===================================================================
--- boot/grub.efi/i386-efi/terminal.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,9 +1,0 @@
-iat_keyboard: at_keyboard
-iserial: serial
-iserial_*: serial
-oaudio: morse
-ocbmemc: cbmemc
-ogfxterm: gfxterm
-oserial: serial
-oserial_*: serial
-ospkmodem: spkmodem
Index: ot/grub.efi/i386-efi/video.lst
===================================================================
--- boot/grub.efi/i386-efi/video.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,4 +1,0 @@
-efi_gop
-efi_uga
-video_bochs
-video_cirrus
Index: ot/grub.efi/x86_64-efi/command.lst
===================================================================
--- boot/grub.efi/x86_64-efi/command.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,187 +1,0 @@
-*acpi: acpi
-*all_functional_test: functional_test
-*background_image: gfxterm_background
-*cat: cat
-*cpuid: cpuid
-*crc: hashsum
-*cryptomount: cryptodisk
-*echo: echo
-*extract_syslinux_entries_configfile: syslinuxcfg
-*extract_syslinux_entries_source: syslinuxcfg
-*file: file
-*functional_test: functional_test
-*gettext: gettext
-*hashsum: hashsum
-*hdparm: hdparm
-*hello: hello
-*help: help
-*hexdump: hexdump
-*inb: iorw
-*inl: iorw
-*inw: iorw
-*keystatus: keystatus
-*kfreebsd: bsd
-*knetbsd: bsd
-*kopenbsd: bsd
-*list_env: loadenv
-*load_env: loadenv
-*loopback: loopback
-*ls: ls
-*lsacpi: lsacpi
-*lspci: lspci
-*md5sum: hashsum
-*menuentry: normal
-*pcidump: pcidump
-*probe: probe
-*read_byte: memrw
-*read_dword: memrw
-*read_word: memrw
-*regexp: regexp
-*save_env: loadenv
-*search: search
-*serial: serial
-*setpci: setpci
-*sha1sum: hashsum
-*sha256sum: hashsum
-*sha512sum: hashsum
-*sleep: sleep
-*submenu: normal
-*syslinux_configfile: syslinuxcfg
-*syslinux_source: syslinuxcfg
-*terminfo: terminfo
-*test_blockarg: test_blockarg
-*testspeed: testspeed
-*tr: tr
-*trust: verify
-*verify_detached: verify
-*xnu_splash: xnu
-*zfskey: zfscrypt
-.: configfile
-[: test
-appleloader: appleldr
-authenticate: normal
-background_color: gfxterm_background
-backtrace: backtrace
-badram: mmap
-blocklist: blocklist
-boot: boot
-break: normal
-cat: minicmd
-cbmemc: cbmemc
-chainloader: chain
-clear: normal
-cmp: cmp
-configfile: configfile
-continue: normal
-coreboot_boottime: cbtime
-cutmem: mmap
-date: date
-distrust: verify
-dump: minicmd
-eval: eval
-exit: minicmd
-export: normal
-extract_entries_configfile: configfile
-extract_entries_source: configfile
-extract_legacy_entries_configfile: legacycfg
-extract_legacy_entries_source: legacycfg
-fakebios: loadbios
-false: true
-fix_video: fixvideo
-fwsetup: efifwsetup
-gptsync: gptsync
-halt: halt
-help: minicmd
-hexdump_random: random
-initrd16: linux16
-initrd: linux
-keymap: keylayouts
-kfreebsd_loadenv: bsd
-kfreebsd_module: bsd
-kfreebsd_module_elf: bsd
-knetbsd_module: bsd
-knetbsd_module_elf: bsd
-kopenbsd_ramdisk: bsd
-legacy_check_password: legacycfg
-legacy_configfile: legacycfg
-legacy_initrd: legacycfg
-legacy_initrd_nounzip: legacycfg
-legacy_kernel: legacycfg
-legacy_password: legacycfg
-legacy_source: legacycfg
-linux16: linux16
-linux: linux
-list_trusted: verify
-loadbios: loadbios
-loadfont: font
-lscoreboot: cbls
-lsefi: lsefi
-lsefimmap: lsefimmap
-lsefisystab: lsefisystab
-lsfonts: font
-lsmmap: lsmmap
-lsmod: minicmd
-lssal: lssal
-macppcbless: macbless
-mactelbless: macbless
-module2: multiboot2
-module: multiboot
-multiboot2: multiboot2
-multiboot: multiboot
-nativedisk: nativedisk
-net_add_addr: net
-net_add_dns: net
-net_add_route: net
-net_bootp: net
-net_del_addr: net
-net_del_dns: net
-net_del_route: net
-net_get_dhcp_option: net
-net_ipv6_autoconf: net
-net_ls_addr: net
-net_ls_cards: net
-net_ls_dns: net
-net_ls_routes: net
-net_nslookup: net
-normal: normal
-normal_exit: normal
-outb: iorw
-outl: iorw
-outw: iorw
-parttool: parttool
-password: password
-password_pbkdf2: password_pbkdf2
-play: play
-read: read
-reboot: reboot
-return: normal
-rmmod: minicmd
-search.file: search_fs_file
-search.fs_label: search_label
-search.fs_uuid: search_fs_uuid
-setparams: normal
-shift: normal
-source: configfile
-terminal_input: terminal
-terminal_output: terminal
-test: test
-testload: testload
-time: time
-true: true
-usb: usbtest
-videoinfo: videoinfo
-videotest: videotest
-write_byte: memrw
-write_dword: memrw
-write_word: memrw
-xnu_devprop_load: xnu
-xnu_kernel64: xnu
-xnu_kernel: xnu
-xnu_kext: xnu
-xnu_kextdir: xnu
-xnu_mkext: xnu
-xnu_ramdisk: xnu
-xnu_resume: xnu
-xnu_uuid: xnu_uuid
-zfs-bootfs: zfsinfo
-zfsinfo: zfsinfo
Index: ot/grub.efi/x86_64-efi/crypto.lst
===================================================================
--- boot/grub.efi/x86_64-efi/crypto.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,45 +1,0 @@
-RIJNDAEL: gcry_rijndael
-RIJNDAEL192: gcry_rijndael
-RIJNDAEL256: gcry_rijndael
-AES128: gcry_rijndael
-AES-128: gcry_rijndael
-AES-192: gcry_rijndael
-AES-256: gcry_rijndael
-ADLER32: adler32
-CRC64: crc64
-ARCFOUR: gcry_arcfour
-BLOWFISH: gcry_blowfish
-CAMELLIA128: gcry_camellia
-CAMELLIA192: gcry_camellia
-CAMELLIA256: gcry_camellia
-CAST5: gcry_cast5
-CRC32: gcry_crc
-CRC32RFC1510: gcry_crc
-CRC24RFC2440: gcry_crc
-DES: gcry_des
-3DES: gcry_des
-DSA: gcry_dsa
-IDEA: gcry_idea
-MD4: gcry_md4
-MD5: gcry_md5
-RFC2268_40: gcry_rfc2268
-AES: gcry_rijndael
-AES192: gcry_rijndael
-AES256: gcry_rijndael
-RIPEMD160: gcry_rmd160
-RSA: gcry_rsa
-SEED: gcry_seed
-SERPENT128: gcry_serpent
-SERPENT192: gcry_serpent
-SERPENT256: gcry_serpent
-SHA1: gcry_sha1
-SHA224: gcry_sha256
-SHA256: gcry_sha256
-SHA512: gcry_sha512
-SHA384: gcry_sha512
-TIGER192: gcry_tiger
-TIGER: gcry_tiger
-TIGER2: gcry_tiger
-TWOFISH: gcry_twofish
-TWOFISH128: gcry_twofish
-WHIRLPOOL: gcry_whirlpool
Index: ot/grub.efi/x86_64-efi/fs.lst
===================================================================
--- boot/grub.efi/x86_64-efi/fs.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,36 +1,0 @@
-affs
-afs
-bfs
-btrfs
-cbfs
-cpio
-cpio_be
-exfat
-ext2
-fat
-hfs
-hfsplus
-iso9660
-jfs
-minix
-minix2
-minix2_be
-minix3
-minix3_be
-minix_be
-newc
-nilfs2
-ntfs
-odc
-procfs
-reiserfs
-romfs
-sfs
-squash4
-tar
-udf
-ufs1
-ufs1_be
-ufs2
-xfs
-zfs
Index: ot/grub.efi/x86_64-efi/gdb_grub
===================================================================
--- boot/grub.efi/x86_64-efi/gdb_grub	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,85 +1,0 @@
-###
-### Load debuging information about GNU GRUB 2 modules into GDB
-### automatically. Needs readelf, Perl and gmodule.pl script
-###
-### Has to be launched from the writable and trusted
-### directory containing *.image and *.module
-###
-### $Id: .gdbinit,v 1.1 2006/05/14 11:38:08 lkundrak Exp $
-### Lubomir Kundrak <lkudrak@skosi.org>
-###
-
-# Add section numbers and addresses to .segments.tmp
-define dump_module_sections
-	set $mod = $arg0
-
-	# FIXME: save logging status
-	set logging file .segments.tmp
-	set logging redirect on
-	set logging overwrite off
-	set logging on
-
-	printf "%s", $mod->name
-	set $segment = $mod->segment
-	while ($segment)
-		printf " %i 0x%lx", $segment->section, $segment->addr
-		set $segment = $segment->next
-	end
-	printf "\n"
-
-	set logging off
-	# FIXME: restore logging status
-end
-document dump_module_sections
-	Gather information about module whose mod structure was
-	given for use with match_and_load_symbols
-end
-
-# Generate and execute GDB commands and delete temporary files
-# afterwards
-define match_and_load_symbols
-	shell perl gmodule.pl <.segments.tmp >.loadsym.gdb
-	source .loadsym.gdb
-	shell rm -f .segments.tmp .loadsym.gdb
-end
-document match_and_load_symbols
-	Launch script, that matches section names with information
-	generated by dump_module_sections and load debugging info
-	apropriately
-end
-
-###
-
-define load_module
-	dump_module_sections $arg0
-	match_and_load_symbols
-end
-document load_module
-	Load debugging information for module given as argument.
-end
-
-define load_all_modules
-	set $this = grub_dl_head
-	while ($this != 0)
-		dump_module_sections $this
-		set $this = $this->next
-	end
-	match_and_load_symbols
-end
-document load_all_modules
-	Load debugging information for all loaded modules.
-end
-
-###
-
-set confirm off
-file kernel.exec
-target remote :1234
-
-# inform when module is loaded
-break grub_dl_add
-commands
-	silent
-	load_module mod
-	cont
-end
Index: ot/grub.efi/x86_64-efi/gmodule.pl
===================================================================
--- boot/grub.efi/x86_64-efi/gmodule.pl	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,30 +1,0 @@
-###
-### Generate GDB commands, that load symbols for specified module,
-### with proper section relocations. See .gdbinit
-###
-### $Id: gmodule.pl,v 1.2 2006/05/14 11:38:42 lkundrak Exp lkundrak $
-### Lubomir Kundrak <lkudrak@skosi.org>
-###
-
-use strict;
-
-while (<>) {
-	my ($name, %sections) = split;
-
-	print "add-symbol-file $name.module";
-
-	open (READELF, "readelf -S $name.mod |") or die;
-	while (<READELF>) {
-		/\[\s*(\d+)\]\s+(\.\S+)/ or next;
-
-		if ($2 eq '.text') {
-			print " $sections{$1}";
-			next;
-		}
-
-		print " -s $2 $sections{$1}"
-			if ($sections{$1} ne '0x0' and $sections{$1} ne '');
-	};
-	close (READELF);
-	print "\n";
-}
Index: ot/grub.efi/x86_64-efi/moddep.lst
===================================================================
--- boot/grub.efi/x86_64-efi/moddep.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,256 +1,0 @@
-videotest: font video gfxmenu
-odc: archelp
-loopback: extcmd
-macho:
-gcry_des: crypto
-memrw: extcmd
-terminfo: extcmd
-part_gpt:
-romfs: fshelp
-read:
-lsefimmap:
-aout:
-gcry_arcfour: crypto
-tftp: net priority_queue
-newc: archelp
-minix2_be:
-elf:
-videotest_checksum: font functional_test video_fb
-password_pbkdf2: crypto gcry_sha512 pbkdf2 normal
-gcry_seed: crypto
-pcidump: extcmd
-bsd: elf serial crypto gcry_md5 extcmd video boot aout cpuid relocator mmap
-sfs: fshelp
-reiserfs: fshelp
-part_sunpc:
-gfxmenu: video_colors trig bitmap_scale gfxterm font normal video bitmap
-backtrace:
-jfs:
-help: extcmd normal
-configfile: normal
-cbls: cbtable
-gfxterm_menu: font functional_test procfs normal video_fb
-gcry_idea: crypto
-tr: extcmd
-shift_test: functional_test
-ohci: cs5536 usb boot
-afs: fshelp
-spkmodem: terminfo
-usb_keyboard: usb keylayouts
-xzio: crypto
-syslinuxcfg: extcmd normal
-search_fs_file:
-usbms: scsi usb
-test_blockarg: extcmd normal
-true:
-affs: fshelp
-iso9660: fshelp
-exfat: fshelp
-setjmp_test: functional_test setjmp
-gfxterm: font video
-efinet: net
-disk:
-appleldr: boot
-xfs: fshelp
-testspeed: extcmd normal
-cpio_be: archelp
-functional_test: btrfs extcmd video video_fb
-bswap_test: functional_test
-sleep: extcmd normal
-memdisk:
-gcry_rijndael: crypto
-mdraid09_be: diskfilter
-gettext:
-gcry_sha1: crypto
-hfspluscomp: gzio hfsplus
-cmp:
-random: hexdump
-offsetio:
-file: macho elf extcmd offsetio
-usbserial_usbdebug: serial usb usbserial_common
-video_colors:
-morse:
-hashsum: crypto extcmd normal
-usb:
-halt: acpi
-gfxterm_background: video_colors bitmap_scale gfxterm extcmd video bitmap
-search_fs_uuid:
-gcry_dsa: verify mpi
-keystatus: extcmd
-linux: video boot relocator mmap
-geli: cryptodisk crypto gcry_sha512 pbkdf2 gcry_sha256
-cmdline_cat_test: font functional_test procfs normal video_fb
-part_sun:
-cbtable:
-pbkdf2_test: functional_test pbkdf2 gcry_sha1
-video_bochs: video video_fb
-bufio:
-usbserial_ftdi: serial usb usbserial_common
-legacy_password_test: functional_test legacycfg
-cpuid: extcmd
-bfs: fshelp
-hdparm: extcmd
-gcry_blowfish: crypto
-test:
-nilfs2: fshelp
-gcry_rsa: verify mpi
-cryptodisk: crypto extcmd procfs
-nativedisk:
-minicmd:
-signature_test: functional_test procfs
-ata: scsi
-udf: fshelp
-gzio:
-xnu_uuid: gcry_md5
-uhci: usb
-pata: ata
-mul_test: functional_test
-adler32: crypto
-terminal:
-div:
-ehci: cs5536 usb boot
-crypto:
-part_bsd: part_msdos
-cs5536:
-gcry_sha512: crypto
-password: crypto normal
-fshelp:
-sleep_test: functional_test datetime
-iorw: extcmd
-xnu: macho bitmap_scale random extcmd video bitmap boot relocator mmap
-mmap:
-exfctest: functional_test
-zfsinfo: zfs
-ldm: part_gpt diskfilter part_msdos
-eval: normal
-part_dvh:
-lssal:
-ext2: fshelp
-blocklist:
-net: priority_queue bufio datetime boot
-part_acorn:
-videoinfo: video
-btrfs: lzopio gzio
-lsmmap: mmap
-bitmap:
-ntfs: fshelp
-multiboot: net video boot relocator mmap
-gcry_crc: crypto
-png: bufio bitmap
-jpeg: bufio bitmap
-macbless: disk
-div_test: functional_test div
-regexp: extcmd normal
-parttool: normal
-usbserial_pl2303: serial usb usbserial_common
-cpio: archelp
-gcry_rmd160: crypto
-fat: fshelp
-ufs1_be:
-archelp:
-raid6rec: diskfilter
-http: net
-zfs: gzio
-lsefisystab:
-minix2:
-lsacpi: extcmd acpi
-datehook: datetime normal
-loadenv: disk extcmd
-bitmap_scale: bitmap
-probe: extcmd
-minix3:
-tar: archelp
-loadbios:
-hfs: fshelp
-procfs: archelp
-boot:
-keylayouts:
-progress: normal
-kernel:
-usbtest: usb
-relocator: mmap
-acpi: extcmd mmap
-tga: bufio bitmap
-reboot:
-serial: extcmd terminfo
-zfscrypt: crypto pbkdf2 zfs extcmd gcry_sha1 gcry_rijndael
-efi_uga: video video_fb
-dm_nv: diskfilter
-cmp_test: functional_test
-luks: cryptodisk crypto pbkdf2
-font: bufio video
-raid5rec: diskfilter
-crc64: crypto
-datetime:
-efifwsetup: reboot
-ctz_test: functional_test
-video:
-cbmemc: normal cbtable terminfo
-hfsplus: fshelp
-gcry_cast5: crypto
-extcmd:
-squash4: fshelp lzopio xzio gzio
-part_plan:
-minix_be:
-gcry_whirlpool: crypto
-gcry_tiger: crypto
-fixvideo:
-search: search_fs_uuid search_fs_file extcmd search_label
-lspci: extcmd
-cbtime: cbtable
-video_fb:
-verify: crypto extcmd mpi gcry_sha1
-minix3_be:
-trig:
-msdospart: disk parttool
-priority_queue:
-gcry_twofish: crypto
-part_dfly:
-xnu_uuid_test: functional_test
-diskfilter:
-testload:
-part_apple:
-hexdump: extcmd
-date: datetime normal
-pbkdf2: crypto
-gcry_sha256: crypto
-ls: extcmd normal
-usbserial_common: serial usb
-ntfscomp: ntfs
-lzopio: crypto
-video_cirrus: video video_fb
-hello: extcmd
-scsi:
-cat: extcmd
-ahci: ata boot
-normal: terminal crypto bufio extcmd boot gettext
-linux16: video boot relocator mmap
-ufs1:
-mdraid09: diskfilter
-lvm: diskfilter
-chain: net efinet boot
-cbfs: archelp
-ufs2:
-time:
-setpci: extcmd
-gptsync: disk
-search_label:
-setjmp:
-multiboot2: net video boot relocator mmap acpi
-gcry_rfc2268: crypto
-mdraid1x: diskfilter
-mpi: crypto
-legacycfg: password crypto gcry_md5 normal
-play:
-part_amiga:
-efi_gop: video video_fb
-minix:
-echo: extcmd
-lsefi:
-gcry_serpent: crypto
-gcry_md4: crypto
-gcry_md5: crypto
-part_msdos:
-gcry_camellia: crypto
-at_keyboard: keylayouts boot
-all_video: efi_gop efi_uga video_bochs video_cirrus
Index: ot/grub.efi/x86_64-efi/modinfo.sh
===================================================================
--- boot/grub.efi/x86_64-efi/modinfo.sh	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,40 +1,0 @@
-#!/bin/sh
-
-# User-controllable options
-grub_modinfo_target_cpu=x86_64
-grub_modinfo_platform=efi
-grub_disk_cache_stats=0
-grub_boot_time_stats=0
-grub_have_font_source=1
-
-# Autodetected config
-grub_have_asm_uscore=0
-grub_bss_start_symbol=""
-grub_end_symbol=""
-
-# Build environment
-grub_target_cc='gcc'
-grub_target_cc_version='gcc (SUSE Linux) 4.8.5'
-grub_target_cflags=' -Os -Wall -W -Wshadow -Wpointer-arith -Wundef -Wchar-subscripts -Wcomment -Wdeprecated-declarations -Wdisabled-optimization -Wdiv-by-zero -Wfloat-equal -Wformat-extra-args -Wformat-security -Wformat-y2k -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Wmain -Wmissing-braces -Wmissing-format-attribute -Wmultichar -Wparentheses -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wswitch -Wtrigraphs -Wunknown-pragmas -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value  -Wunused-variable -Wwrite-strings -Wnested-externs -Wstrict-prototypes -g -Wredundant-decls -Wmissing-prototypes -Wmissing-declarations  -Wextra -Wattributes -Wendif-labels -Winit-self -Wint-to-pointer-cast -Winvalid-pch -Wmissing-field-initializers -Wnonnull -Woverflow -Wvla -Wpointer-to-int-cast -Wstrict-aliasing -Wvariadic-macros -Wvolatile-register-var -Wpointer-sign -Wmissing-include-dirs -Wmissing-prototypes -Wmissing-declarations -Wformat=2 -m64 -freg-struct-return -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow -msoft-float -fno-dwarf2-cfi-asm -mno-stack-arg-probe -fno-asynchronous-unwind-tables -fno-unwind-tables -mcmodel=large -mno-red-zone -Qn -fno-stack-protector -Wtrampolines -Werror'
-grub_target_cppflags=' -Wall -W  -DGRUB_MACHINE_EFI=1 -DGRUB_MACHINE=X86_64_EFI -m64 -nostdinc -isystem /usr/lib64/gcc/x86_64-suse-linux/4.8/include -I$(top_srcdir)/include -I$(top_builddir)/include'
-grub_target_ccasflags=' -g  -m64 -msoft-float'
-grub_target_ldflags=' -m64 -Wl,-melf_x86_64 -Wl,--build-id=none'
-grub_cflags=''
-grub_cppflags=' -D_FILE_OFFSET_BITS=64'
-grub_ccasflags=''
-grub_ldflags=''
-grub_target_strip='strip'
-grub_target_nm='nm'
-grub_target_ranlib='ranlib'
-grub_target_objconf=''
-grub_target_obj2elf=''
-grub_target_img_base_ldopt='-Wl,-Ttext'
-grub_target_img_ldflags='@TARGET_IMG_BASE_LDFLAGS@'
-
-# Version
-grub_version="2.02~beta2"
-grub_package="grub"
-grub_package_string="GRUB 2.02~beta2"
-grub_package_version="2.02~beta2"
-grub_package_name="GRUB"
-grub_package_bugreport="bug-grub@gnu.org"
Index: ot/grub.efi/x86_64-efi/partmap.lst
===================================================================
--- boot/grub.efi/x86_64-efi/partmap.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,11 +1,0 @@
-part_acorn
-part_amiga
-part_apple
-part_bsd
-part_dfly
-part_dvh
-part_gpt
-part_msdos
-part_plan
-part_sun
-part_sunpc
Index: ot/grub.efi/x86_64-efi/parttool.lst
===================================================================
--- boot/grub.efi/x86_64-efi/parttool.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,1 +1,0 @@
-msdos: msdospart
Index: ot/grub.efi/x86_64-efi/terminal.lst
===================================================================
--- boot/grub.efi/x86_64-efi/terminal.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,9 +1,0 @@
-iat_keyboard: at_keyboard
-iserial: serial
-iserial_*: serial
-oaudio: morse
-ocbmemc: cbmemc
-ogfxterm: gfxterm
-oserial: serial
-oserial_*: serial
-ospkmodem: spkmodem
Index: ot/grub.efi/x86_64-efi/video.lst
===================================================================
--- boot/grub.efi/x86_64-efi/video.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,4 +1,0 @@
-efi_gop
-efi_uga
-video_bochs
-video_cirrus
Index: ot/grub.pc/COPYING
===================================================================
--- boot/grub.pc/COPYING	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,674 +1,0 @@
-                    GNU GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.  We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors.  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-  To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights.  Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received.  You must make sure that they, too, receive
-or can get the source code.  And you must show them these terms so they
-know their rights.
-
-  Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
-  For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software.  For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
-  Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so.  This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software.  The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable.  Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products.  If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
-  Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary.  To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                       TERMS AND CONDITIONS
-
-  0. Definitions.
-
-  "This License" refers to version 3 of the GNU General Public License.
-
-  "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
-  "The Program" refers to any copyrightable work licensed under this
-License.  Each licensee is addressed as "you".  "Licensees" and
-"recipients" may be individuals or organizations.
-
-  To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy.  The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
-  A "covered work" means either the unmodified Program or a work based
-on the Program.
-
-  To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy.  Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-  To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies.  Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
-  An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License.  If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-  1. Source Code.
-
-  The "source code" for a work means the preferred form of the work
-for making modifications to it.  "Object code" means any non-source
-form of a work.
-
-  A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-  The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form.  A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-  The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities.  However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work.  For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-  The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
-  The Corresponding Source for a work in source code form is that
-same work.
-
-  2. Basic Permissions.
-
-  All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met.  This License explicitly affirms your unlimited
-permission to run the unmodified Program.  The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work.  This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-  You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force.  You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright.  Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-  Conveying under any other circumstances is permitted solely under
-the conditions stated below.  Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-  No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-  When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
-  4. Conveying Verbatim Copies.
-
-  You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-  You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-  You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
-    a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
-
-    b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under section
-    7.  This requirement modifies the requirement in section 4 to
-    "keep intact all notices".
-
-    c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy.  This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged.  This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
-
-    d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
-
-  A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit.  Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-  You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
-    a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
-
-    b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the
-    Corresponding Source from a network server at no charge.
-
-    c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source.  This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
-
-    d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge.  You need not require recipients to copy the
-    Corresponding Source along with the object code.  If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source.  Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
-
-    e) Convey the object code using peer-to-peer transmission, provided
-    you inform other peers where the object code and Corresponding
-    Source of the work are being offered to the general public at no
-    charge under subsection 6d.
-
-  A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-  A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling.  In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage.  For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product.  A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
-  "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source.  The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
-  If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information.  But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-  The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed.  Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
-  Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-  7. Additional Terms.
-
-  "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law.  If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-  When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it.  (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.)  You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-  Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
-    a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
-
-    b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
-
-    c) Prohibiting misrepresentation of the origin of that material, or
-    requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
-
-    d) Limiting the use for publicity purposes of names of licensors or
-    authors of the material; or
-
-    e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
-
-    f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions of
-    it) with contractual assumptions of liability to the recipient, for
-    any liability that these contractual assumptions directly impose on
-    those licensors and authors.
-
-  All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10.  If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term.  If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-  If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-  Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
-  8. Termination.
-
-  You may not propagate or modify a covered work except as expressly
-provided under this License.  Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-  However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
-  Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-  Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License.  If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-  You are not required to accept this License in order to receive or
-run a copy of the Program.  Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance.  However,
-nothing other than this License grants you permission to propagate or
-modify any covered work.  These actions infringe copyright if you do
-not accept this License.  Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-  Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License.  You are not responsible
-for enforcing compliance by third parties with this License.
-
-  An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations.  If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-  You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License.  For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-  11. Patents.
-
-  A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based.  The
-work thus licensed is called the contributor's "contributor version".
-
-  A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version.  For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-  In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement).  To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-  If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients.  "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-  If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-  A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License.  You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
-  Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-  If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all.  For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
-  13. Use with the GNU Affero General Public License.
-
-  Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work.  The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
-  14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-  Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation.  If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
-  If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
-  Later license versions may give you additional or different
-permissions.  However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-  15. Disclaimer of Warranty.
-
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-  If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
-    <program>  Copyright (C) <year>  <name of author>
-    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
-  You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
-  The GNU General Public License does not permit incorporating your program
-into proprietary programs.  If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.  But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
Index: ot/grub.pc/README
===================================================================
--- boot/grub.pc/README	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,9 +1,0 @@
-The binary files of GRUB boot loader in this directory have been created
-by compiling GRUB for the 'i386-pc' target and then using the grub-mkrescue
-script to create the El Torito boot image.
-
-For licensing terms of GRUB boot loader see the file COPYING contained
-in this directory. Full version of GRUB, including its source code,
-can be downloaded from GRUB's project page:
-
-http://www.gnu.org/software/grub/
Index: ot/grub.pc/REVISION
===================================================================
--- boot/grub.pc/REVISION	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,1 +1,0 @@
-bc220962e366b1b46769ed6f9fa5be603ba58ab5
Index: ot/grub.pc/i386-pc/command.lst
===================================================================
--- boot/grub.pc/i386-pc/command.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,198 +1,0 @@
-*acpi: acpi
-*all_functional_test: functional_test
-*background_image: gfxterm_background
-*cat: cat
-*cpuid: cpuid
-*crc: hashsum
-*cryptomount: cryptodisk
-*drivemap: drivemap
-*echo: echo
-*extract_syslinux_entries_configfile: syslinuxcfg
-*extract_syslinux_entries_source: syslinuxcfg
-*file: file
-*functional_test: functional_test
-*gettext: gettext
-*halt: halt
-*hashsum: hashsum
-*hdparm: hdparm
-*hello: hello
-*help: help
-*hexdump: hexdump
-*inb: iorw
-*inl: iorw
-*inw: iorw
-*keystatus: keystatus
-*kfreebsd: bsd
-*knetbsd: bsd
-*kopenbsd: bsd
-*list_env: loadenv
-*load_env: loadenv
-*loopback: loopback
-*ls: ls
-*lsacpi: lsacpi
-*lspci: lspci
-*md5sum: hashsum
-*menuentry: normal
-*pcidump: pcidump
-*plan9: plan9
-*probe: probe
-*read_byte: memrw
-*read_dword: memrw
-*read_word: memrw
-*regexp: regexp
-*save_env: loadenv
-*search: search
-*sendkey: sendkey
-*serial: serial
-*setpci: setpci
-*sha1sum: hashsum
-*sha256sum: hashsum
-*sha512sum: hashsum
-*sleep: sleep
-*submenu: normal
-*syslinux_configfile: syslinuxcfg
-*syslinux_source: syslinuxcfg
-*terminfo: terminfo
-*test_blockarg: test_blockarg
-*testspeed: testspeed
-*tr: tr
-*trust: verify
-*verify_detached: verify
-*xnu_splash: xnu
-*zfskey: zfscrypt
-.: configfile
-[: test
-authenticate: normal
-background_color: gfxterm_background
-backtrace: backtrace
-badram: mmap
-blocklist: blocklist
-boot: boot
-break: normal
-cat: minicmd
-cbmemc: cbmemc
-chainloader: chain
-clear: normal
-cmosclean: cmostest
-cmosdump: cmosdump
-cmosset: cmostest
-cmostest: cmostest
-cmp: cmp
-configfile: configfile
-continue: normal
-coreboot_boottime: cbtime
-cutmem: mmap
-date: date
-distrust: verify
-dump: minicmd
-efiemu_loadcore: efiemu
-efiemu_prepare: efiemu
-efiemu_unload: efiemu
-eval: eval
-exit: minicmd
-export: normal
-extract_entries_configfile: configfile
-extract_entries_source: configfile
-extract_legacy_entries_configfile: legacycfg
-extract_legacy_entries_source: legacycfg
-false: true
-freedos: freedos
-gdbstub: gdb
-gdbstub_break: gdb
-gdbstub_stop: gdb
-gptsync: gptsync
-help: minicmd
-hexdump_random: random
-initrd16: linux16
-initrd: linux
-keymap: keylayouts
-kfreebsd_loadenv: bsd
-kfreebsd_module: bsd
-kfreebsd_module_elf: bsd
-knetbsd_module: bsd
-knetbsd_module_elf: bsd
-kopenbsd_ramdisk: bsd
-legacy_check_password: legacycfg
-legacy_configfile: legacycfg
-legacy_initrd: legacycfg
-legacy_initrd_nounzip: legacycfg
-legacy_kernel: legacycfg
-legacy_password: legacycfg
-legacy_source: legacycfg
-linux16: linux16
-linux: linux
-list_trusted: verify
-loadfont: font
-lsapm: lsapm
-lscoreboot: cbls
-lsfonts: font
-lsmmap: lsmmap
-lsmod: minicmd
-macppcbless: macbless
-mactelbless: macbless
-module2: multiboot2
-module: multiboot
-multiboot2: multiboot2
-multiboot: multiboot
-nativedisk: nativedisk
-net_add_addr: net
-net_add_dns: net
-net_add_route: net
-net_bootp: net
-net_del_addr: net
-net_del_dns: net
-net_del_route: net
-net_get_dhcp_option: net
-net_ipv6_autoconf: net
-net_ls_addr: net
-net_ls_cards: net
-net_ls_dns: net
-net_ls_routes: net
-net_nslookup: net
-normal: normal
-normal_exit: normal
-ntldr: ntldr
-outb: iorw
-outl: iorw
-outw: iorw
-parttool: parttool
-password: password
-password_pbkdf2: password_pbkdf2
-play: play
-pxechainloader: pxechain
-read: read
-reboot: reboot
-return: normal
-rmmod: minicmd
-search.file: search_fs_file
-search.fs_label: search_label
-search.fs_uuid: search_fs_uuid
-setparams: normal
-shift: normal
-source: configfile
-terminal_input: terminal
-terminal_output: terminal
-test: test
-testload: testload
-time: time
-true: true
-truecrypt: truecrypt
-usb: usbtest
-vbeinfo: videoinfo
-vbetest: videotest
-videoinfo: videoinfo
-videotest: videotest
-write_byte: memrw
-write_dword: memrw
-write_word: memrw
-xnu_devprop_load: xnu
-xnu_kernel64: xnu
-xnu_kernel: xnu
-xnu_kext: xnu
-xnu_kextdir: xnu
-xnu_mkext: xnu
-xnu_ramdisk: xnu
-xnu_resume: xnu
-xnu_uuid: xnu_uuid
-zfs-bootfs: zfsinfo
-zfsinfo: zfsinfo
Index: ot/grub.pc/i386-pc/crypto.lst
===================================================================
--- boot/grub.pc/i386-pc/crypto.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,45 +1,0 @@
-RIJNDAEL: gcry_rijndael
-RIJNDAEL192: gcry_rijndael
-RIJNDAEL256: gcry_rijndael
-AES128: gcry_rijndael
-AES-128: gcry_rijndael
-AES-192: gcry_rijndael
-AES-256: gcry_rijndael
-ADLER32: adler32
-CRC64: crc64
-ARCFOUR: gcry_arcfour
-BLOWFISH: gcry_blowfish
-CAMELLIA128: gcry_camellia
-CAMELLIA192: gcry_camellia
-CAMELLIA256: gcry_camellia
-CAST5: gcry_cast5
-CRC32: gcry_crc
-CRC32RFC1510: gcry_crc
-CRC24RFC2440: gcry_crc
-DES: gcry_des
-3DES: gcry_des
-DSA: gcry_dsa
-IDEA: gcry_idea
-MD4: gcry_md4
-MD5: gcry_md5
-RFC2268_40: gcry_rfc2268
-AES: gcry_rijndael
-AES192: gcry_rijndael
-AES256: gcry_rijndael
-RIPEMD160: gcry_rmd160
-RSA: gcry_rsa
-SEED: gcry_seed
-SERPENT128: gcry_serpent
-SERPENT192: gcry_serpent
-SERPENT256: gcry_serpent
-SHA1: gcry_sha1
-SHA224: gcry_sha256
-SHA256: gcry_sha256
-SHA512: gcry_sha512
-SHA384: gcry_sha512
-TIGER192: gcry_tiger
-TIGER: gcry_tiger
-TIGER2: gcry_tiger
-TWOFISH: gcry_twofish
-TWOFISH128: gcry_twofish
-WHIRLPOOL: gcry_whirlpool
Index: ot/grub.pc/i386-pc/fs.lst
===================================================================
--- boot/grub.pc/i386-pc/fs.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,36 +1,0 @@
-affs
-afs
-bfs
-btrfs
-cbfs
-cpio
-cpio_be
-exfat
-ext2
-fat
-hfs
-hfsplus
-iso9660
-jfs
-minix
-minix2
-minix2_be
-minix3
-minix3_be
-minix_be
-newc
-nilfs2
-ntfs
-odc
-procfs
-reiserfs
-romfs
-sfs
-squash4
-tar
-udf
-ufs1
-ufs1_be
-ufs2
-xfs
-zfs
Index: ot/grub.pc/i386-pc/gdb_grub
===================================================================
--- boot/grub.pc/i386-pc/gdb_grub	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,85 +1,0 @@
-###
-### Load debuging information about GNU GRUB 2 modules into GDB
-### automatically. Needs readelf, Perl and gmodule.pl script
-###
-### Has to be launched from the writable and trusted
-### directory containing *.image and *.module
-###
-### $Id: .gdbinit,v 1.1 2006/05/14 11:38:08 lkundrak Exp $
-### Lubomir Kundrak <lkudrak@skosi.org>
-###
-
-# Add section numbers and addresses to .segments.tmp
-define dump_module_sections
-	set $mod = $arg0
-
-	# FIXME: save logging status
-	set logging file .segments.tmp
-	set logging redirect on
-	set logging overwrite off
-	set logging on
-
-	printf "%s", $mod->name
-	set $segment = $mod->segment
-	while ($segment)
-		printf " %i 0x%lx", $segment->section, $segment->addr
-		set $segment = $segment->next
-	end
-	printf "\n"
-
-	set logging off
-	# FIXME: restore logging status
-end
-document dump_module_sections
-	Gather information about module whose mod structure was
-	given for use with match_and_load_symbols
-end
-
-# Generate and execute GDB commands and delete temporary files
-# afterwards
-define match_and_load_symbols
-	shell perl gmodule.pl <.segments.tmp >.loadsym.gdb
-	source .loadsym.gdb
-	shell rm -f .segments.tmp .loadsym.gdb
-end
-document match_and_load_symbols
-	Launch script, that matches section names with information
-	generated by dump_module_sections and load debugging info
-	apropriately
-end
-
-###
-
-define load_module
-	dump_module_sections $arg0
-	match_and_load_symbols
-end
-document load_module
-	Load debugging information for module given as argument.
-end
-
-define load_all_modules
-	set $this = grub_dl_head
-	while ($this != 0)
-		dump_module_sections $this
-		set $this = $this->next
-	end
-	match_and_load_symbols
-end
-document load_all_modules
-	Load debugging information for all loaded modules.
-end
-
-###
-
-set confirm off
-file kernel.exec
-target remote :1234
-
-# inform when module is loaded
-break grub_dl_add
-commands
-	silent
-	load_module mod
-	cont
-end
Index: ot/grub.pc/i386-pc/gmodule.pl
===================================================================
--- boot/grub.pc/i386-pc/gmodule.pl	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,30 +1,0 @@
-###
-### Generate GDB commands, that load symbols for specified module,
-### with proper section relocations. See .gdbinit
-###
-### $Id: gmodule.pl,v 1.2 2006/05/14 11:38:42 lkundrak Exp lkundrak $
-### Lubomir Kundrak <lkudrak@skosi.org>
-###
-
-use strict;
-
-while (<>) {
-	my ($name, %sections) = split;
-
-	print "add-symbol-file $name.module";
-
-	open (READELF, "readelf -S $name.mod |") or die;
-	while (<READELF>) {
-		/\[\s*(\d+)\]\s+(\.\S+)/ or next;
-
-		if ($2 eq '.text') {
-			print " $sections{$1}";
-			next;
-		}
-
-		print " -s $2 $sections{$1}"
-			if ($sections{$1} ne '0x0' and $sections{$1} ne '');
-	};
-	close (READELF);
-	print "\n";
-}
Index: ot/grub.pc/i386-pc/moddep.lst
===================================================================
--- boot/grub.pc/i386-pc/moddep.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,264 +1,0 @@
-videotest: font video gfxmenu
-odc: archelp
-loopback: extcmd
-macho:
-gcry_des: crypto
-memrw: extcmd
-terminfo: extcmd
-part_gpt:
-romfs: fshelp
-read:
-aout:
-gcry_arcfour: crypto
-vga_text:
-tftp: net priority_queue
-newc: archelp
-minix2_be:
-elf:
-videotest_checksum: font functional_test video_fb
-password_pbkdf2: crypto gcry_sha512 pbkdf2 normal
-gcry_seed: crypto
-pcidump: extcmd pci
-bsd: elf serial crypto gcry_md5 extcmd vbe video boot aout cpuid relocator mmap
-sfs: fshelp
-reiserfs: fshelp
-part_sunpc:
-gfxmenu: video_colors trig bitmap_scale gfxterm font normal video bitmap
-backtrace:
-jfs:
-help: extcmd normal
-configfile: normal
-cbls: cbtable
-gfxterm_menu: font functional_test procfs normal video_fb
-gcry_idea: crypto
-tr: extcmd
-shift_test: functional_test
-ohci: cs5536 usb boot pci
-afs: fshelp
-spkmodem: terminfo
-usb_keyboard: usb keylayouts
-xzio: crypto
-syslinuxcfg: extcmd normal
-search_fs_file:
-vga: video video_fb
-usbms: scsi usb
-test_blockarg: extcmd normal
-true:
-affs: fshelp
-iso9660: fshelp
-exfat: fshelp
-setjmp_test: functional_test setjmp
-gfxterm: font video
-disk:
-xfs: fshelp
-testspeed: extcmd normal
-cpio_be: archelp
-functional_test: btrfs extcmd video video_fb
-pxechain: pxe video boot relocator
-bswap_test: functional_test
-sleep: extcmd normal
-memdisk:
-gcry_rijndael: crypto
-mdraid09_be: diskfilter
-gettext:
-gcry_sha1: crypto
-hfspluscomp: gzio hfsplus
-cmp:
-random: hexdump acpi
-offsetio:
-file: macho elf extcmd offsetio
-usbserial_usbdebug: serial usb usbserial_common
-video_colors:
-morse:
-hashsum: crypto extcmd normal
-usb: pci
-halt: extcmd acpi
-gdb: serial backtrace
-gfxterm_background: video_colors bitmap_scale gfxterm extcmd video bitmap
-search_fs_uuid:
-gcry_dsa: verify mpi
-keystatus: extcmd
-linux: normal vbe video boot relocator mmap
-geli: cryptodisk crypto gcry_sha512 pbkdf2 gcry_sha256
-cmdline_cat_test: font functional_test procfs normal video_fb
-part_sun:
-cbtable:
-plan9: extcmd video boot relocator
-sendkey: extcmd boot
-pbkdf2_test: functional_test pbkdf2 gcry_sha1
-video_bochs: video pci video_fb
-bufio:
-usbserial_ftdi: serial usb usbserial_common
-legacy_password_test: functional_test legacycfg
-cpuid: extcmd
-bfs: fshelp
-hdparm: extcmd
-gcry_blowfish: crypto
-test:
-nilfs2: fshelp
-gcry_rsa: verify mpi
-cryptodisk: crypto extcmd procfs
-nativedisk:
-minicmd:
-signature_test: functional_test procfs
-ata: scsi
-udf: fshelp
-gzio:
-xnu_uuid: gcry_md5
-uhci: usb pci
-pata: ata pci
-mul_test: functional_test
-adler32: crypto
-terminal:
-div:
-ehci: cs5536 usb boot pci
-crypto:
-part_bsd: part_msdos
-cs5536: pci
-biosdisk:
-lsapm:
-gcry_sha512: crypto
-password: crypto normal
-efiemu: gcry_crc crypto cpuid acpi
-fshelp:
-sleep_test: functional_test datetime
-iorw: extcmd
-xnu: macho bitmap_scale random extcmd video bitmap boot efiemu relocator mmap
-mmap: boot
-exfctest: functional_test
-zfsinfo: zfs
-ldm: part_gpt diskfilter part_msdos
-cmostest:
-eval: normal
-part_dvh:
-ext2: fshelp
-blocklist:
-net: priority_queue bufio datetime boot
-drivemap: extcmd boot mmap
-part_acorn:
-videoinfo: video
-btrfs: lzopio gzio
-lsmmap:
-bitmap:
-vbe: video video_fb
-ntfs: fshelp
-multiboot: net vbe video boot relocator mmap lsapm
-gcry_crc: crypto
-png: bufio bitmap
-jpeg: bufio bitmap
-macbless: disk
-div_test: functional_test div
-regexp: extcmd normal
-parttool: normal
-usbserial_pl2303: serial usb usbserial_common
-cpio: archelp
-gcry_rmd160: crypto
-fat: fshelp
-ufs1_be:
-truecrypt: video boot relocator mmap gzio
-archelp:
-raid6rec: diskfilter
-ntldr: chain video boot relocator
-http: net
-zfs: gzio
-minix2:
-mda_text:
-lsacpi: extcmd acpi
-datehook: datetime normal
-loadenv: disk extcmd
-bitmap_scale: bitmap
-probe: extcmd
-minix3:
-tar: archelp
-hfs: fshelp
-procfs: archelp
-boot:
-keylayouts:
-progress: normal
-kernel:
-usbtest: usb
-relocator: mmap
-acpi: extcmd mmap
-tga: bufio bitmap
-reboot: relocator
-serial: extcmd terminfo
-zfscrypt: crypto pbkdf2 zfs extcmd gcry_sha1 gcry_rijndael
-dm_nv: diskfilter
-cmp_test: functional_test
-luks: cryptodisk crypto pbkdf2
-font: bufio video
-raid5rec: diskfilter
-crc64: crypto
-datetime:
-ctz_test: functional_test
-video:
-pci:
-cbmemc: normal cbtable terminfo
-cmosdump:
-hfsplus: fshelp
-gcry_cast5: crypto
-extcmd:
-squash4: fshelp lzopio xzio gzio
-part_plan:
-minix_be:
-gcry_whirlpool: crypto
-pxe: net boot
-gcry_tiger: crypto
-search: search_fs_uuid search_fs_file extcmd search_label
-lspci: extcmd pci
-cbtime: cbtable
-video_fb:
-verify: crypto extcmd mpi gcry_sha1
-minix3_be:
-trig:
-msdospart: disk parttool
-priority_queue:
-gcry_twofish: crypto
-part_dfly:
-xnu_uuid_test: functional_test
-diskfilter:
-testload:
-part_apple:
-hexdump: extcmd
-date: datetime normal
-pbkdf2: crypto
-gcry_sha256: crypto
-ls: extcmd normal
-usbserial_common: serial usb
-ntfscomp: ntfs
-lzopio: crypto
-video_cirrus: video pci video_fb
-hello: extcmd
-scsi:
-cat: extcmd
-ahci: ata boot pci
-normal: terminal crypto bufio extcmd boot gettext
-linux16: video boot relocator mmap
-ufs1:
-mdraid09: diskfilter
-lvm: diskfilter
-cbfs: archelp
-chain: video boot relocator
-ufs2:
-time:
-setpci: extcmd pci
-gptsync: disk
-freedos: chain video boot relocator
-search_label:
-setjmp:
-multiboot2: net vbe video boot relocator mmap lsapm acpi
-gcry_rfc2268: crypto
-mdraid1x: diskfilter
-mpi: crypto
-legacycfg: linux password crypto gcry_md5 normal
-play:
-part_amiga:
-minix:
-echo: extcmd
-gcry_serpent: crypto
-gcry_md4: crypto
-gcry_md5: crypto
-part_msdos:
-gcry_camellia: crypto
-at_keyboard: keylayouts boot
-all_video: vbe vga video_bochs video_cirrus
Index: ot/grub.pc/i386-pc/modinfo.sh
===================================================================
--- boot/grub.pc/i386-pc/modinfo.sh	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,40 +1,0 @@
-#!/bin/sh
-
-# User-controllable options
-grub_modinfo_target_cpu=i386
-grub_modinfo_platform=pc
-grub_disk_cache_stats=0
-grub_boot_time_stats=0
-grub_have_font_source=1
-
-# Autodetected config
-grub_have_asm_uscore=0
-grub_bss_start_symbol="__bss_start"
-grub_end_symbol="end"
-
-# Build environment
-grub_target_cc='gcc'
-grub_target_cc_version='gcc (SUSE Linux) 4.8.5'
-grub_target_cflags=' -Os -Wall -W -Wshadow -Wpointer-arith -Wundef -Wchar-subscripts -Wcomment -Wdeprecated-declarations -Wdisabled-optimization -Wdiv-by-zero -Wfloat-equal -Wformat-extra-args -Wformat-security -Wformat-y2k -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Wmain -Wmissing-braces -Wmissing-format-attribute -Wmultichar -Wparentheses -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wswitch -Wtrigraphs -Wunknown-pragmas -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value  -Wunused-variable -Wwrite-strings -Wnested-externs -Wstrict-prototypes -g -Wredundant-decls -Wmissing-prototypes -Wmissing-declarations  -Wextra -Wattributes -Wendif-labels -Winit-self -Wint-to-pointer-cast -Winvalid-pch -Wmissing-field-initializers -Wnonnull -Woverflow -Wvla -Wpointer-to-int-cast -Wstrict-aliasing -Wvariadic-macros -Wvolatile-register-var -Wpointer-sign -Wmissing-include-dirs -Wmissing-prototypes -Wmissing-declarations -Wformat=2 -march=i386 -m32 -mrtd -mregparm=3 -falign-jumps=1 -falign-loops=1 -falign-functions=1 -freg-struct-return -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow -msoft-float -fno-dwarf2-cfi-asm -mno-stack-arg-probe -fno-asynchronous-unwind-tables -fno-unwind-tables -Qn -fno-stack-protector -Wtrampolines -Werror'
-grub_target_cppflags=' -Wall -W  -DGRUB_MACHINE_PCBIOS=1 -DGRUB_MACHINE=I386_PC -m32 -nostdinc -isystem /usr/lib64/gcc/x86_64-suse-linux/4.8/include -I$(top_srcdir)/include -I$(top_builddir)/include'
-grub_target_ccasflags=' -g  -m32 -msoft-float'
-grub_target_ldflags=' -m32 -Wl,-melf_i386 -Wl,--build-id=none'
-grub_cflags=''
-grub_cppflags=' -D_FILE_OFFSET_BITS=64'
-grub_ccasflags=''
-grub_ldflags=''
-grub_target_strip='strip'
-grub_target_nm='nm'
-grub_target_ranlib='ranlib'
-grub_target_objconf=''
-grub_target_obj2elf=''
-grub_target_img_base_ldopt='-Wl,-Ttext'
-grub_target_img_ldflags='@TARGET_IMG_BASE_LDFLAGS@'
-
-# Version
-grub_version="2.02~beta2"
-grub_package="grub"
-grub_package_string="GRUB 2.02~beta2"
-grub_package_version="2.02~beta2"
-grub_package_name="GRUB"
-grub_package_bugreport="bug-grub@gnu.org"
Index: ot/grub.pc/i386-pc/partmap.lst
===================================================================
--- boot/grub.pc/i386-pc/partmap.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,11 +1,0 @@
-part_acorn
-part_amiga
-part_apple
-part_bsd
-part_dfly
-part_dvh
-part_gpt
-part_msdos
-part_plan
-part_sun
-part_sunpc
Index: ot/grub.pc/i386-pc/parttool.lst
===================================================================
--- boot/grub.pc/i386-pc/parttool.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,1 +1,0 @@
-msdos: msdospart
Index: ot/grub.pc/i386-pc/terminal.lst
===================================================================
--- boot/grub.pc/i386-pc/terminal.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,11 +1,0 @@
-iat_keyboard: at_keyboard
-iserial: serial
-iserial_*: serial
-oaudio: morse
-ocbmemc: cbmemc
-ogfxterm: gfxterm
-omda_text: mda_text
-oserial: serial
-oserial_*: serial
-ospkmodem: spkmodem
-ovga_text: vga_text
Index: ot/grub.pc/i386-pc/video.lst
===================================================================
--- boot/grub.pc/i386-pc/video.lst	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,4 +1,0 @@
-vbe
-vga
-video_bochs
-video_cirrus
Index: boot/grub/amd64-efi
===================================================================
--- boot/grub/amd64-efi	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/amd64-efi	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+ia32-efi
Index: boot/grub/amd64-pc
===================================================================
--- boot/grub/amd64-pc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/amd64-pc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+ia32-pc
Index: boot/grub/arm64-efi/COPYING
===================================================================
--- boot/grub/arm64-efi/COPYING	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/arm64-efi/COPYING	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
Index: boot/grub/arm64-efi/README
===================================================================
--- boot/grub/arm64-efi/README	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/arm64-efi/README	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,9 @@
+The binary files of GRUB boot loader in this directory have been created
+by compiling GRUB for the 'arm64-efi' target and then using the grub-mkrescue
+script to create the El Torito boot image.
+
+For licensing terms of GRUB boot loader see the file COPYING contained
+in this directory. Full version of GRUB, including its source code,
+can be downloaded from GRUB's project page:
+
+http://www.gnu.org/software/grub/
Index: boot/grub/arm64-efi/REVISION
===================================================================
--- boot/grub/arm64-efi/REVISION	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/arm64-efi/REVISION	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+bc220962e366b1b46769ed6f9fa5be603ba58ab5
Index: boot/grub/arm64-efi/arm64-efi/command.lst
===================================================================
--- boot/grub/arm64-efi/arm64-efi/command.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/arm64-efi/arm64-efi/command.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,133 @@
+*acpi: acpi
+*all_functional_test: functional_test
+*background_image: gfxterm_background
+*cat: cat
+*crc: hashsum
+*cryptomount: cryptodisk
+*echo: echo
+*extract_syslinux_entries_configfile: syslinuxcfg
+*extract_syslinux_entries_source: syslinuxcfg
+*file: file
+*functional_test: functional_test
+*gettext: gettext
+*hashsum: hashsum
+*hello: hello
+*help: help
+*hexdump: hexdump
+*keystatus: keystatus
+*list_env: loadenv
+*load_env: loadenv
+*loopback: loopback
+*ls: ls
+*lsacpi: lsacpi
+*md5sum: hashsum
+*menuentry: normal
+*probe: probe
+*read_byte: memrw
+*read_dword: memrw
+*read_word: memrw
+*regexp: regexp
+*save_env: loadenv
+*search: search
+*serial: serial
+*sha1sum: hashsum
+*sha256sum: hashsum
+*sha512sum: hashsum
+*sleep: sleep
+*submenu: normal
+*syslinux_configfile: syslinuxcfg
+*syslinux_source: syslinuxcfg
+*terminfo: terminfo
+*test_blockarg: test_blockarg
+*testspeed: testspeed
+*tr: tr
+*trust: verify
+*verify_detached: verify
+*zfskey: zfscrypt
+.: configfile
+[: test
+authenticate: normal
+background_color: gfxterm_background
+badram: mmap
+blocklist: blocklist
+boot: boot
+break: normal
+cat: minicmd
+chainloader: chain
+clear: normal
+cmp: cmp
+configfile: configfile
+continue: normal
+cutmem: mmap
+date: date
+devicetree: fdt
+distrust: verify
+dump: minicmd
+eval: eval
+exit: minicmd
+export: normal
+extract_entries_configfile: configfile
+extract_entries_source: configfile
+false: true
+fwsetup: efifwsetup
+gptsync: gptsync
+halt: halt
+help: minicmd
+initrd: linux
+linux: linux
+list_trusted: verify
+loadfont: font
+lsefi: lsefi
+lsefimmap: lsefimmap
+lsefisystab: lsefisystab
+lsfonts: font
+lsmmap: lsmmap
+lsmod: minicmd
+lssal: lssal
+macppcbless: macbless
+mactelbless: macbless
+net_add_addr: net
+net_add_dns: net
+net_add_route: net
+net_bootp: net
+net_del_addr: net
+net_del_dns: net
+net_del_route: net
+net_get_dhcp_option: net
+net_ipv6_autoconf: net
+net_ls_addr: net
+net_ls_cards: net
+net_ls_dns: net
+net_ls_routes: net
+net_nslookup: net
+normal: normal
+normal_exit: normal
+parttool: parttool
+password: password
+password_pbkdf2: password_pbkdf2
+read: read
+reboot: reboot
+return: normal
+rmmod: minicmd
+search.file: search_fs_file
+search.fs_label: search_label
+search.fs_uuid: search_fs_uuid
+setparams: normal
+shift: normal
+source: configfile
+terminal_input: terminal
+terminal_output: terminal
+test: test
+testload: testload
+time: time
+true: true
+videoinfo: videoinfo
+videotest: videotest
+write_byte: memrw
+write_dword: memrw
+write_word: memrw
+xen_hypervisor: xen_boot
+xen_module: xen_boot
+xnu_uuid: xnu_uuid
+zfs-bootfs: zfsinfo
+zfsinfo: zfsinfo
Index: boot/grub/arm64-efi/arm64-efi/crypto.lst
===================================================================
--- boot/grub/arm64-efi/arm64-efi/crypto.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/arm64-efi/arm64-efi/crypto.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,45 @@
+RIJNDAEL: gcry_rijndael
+RIJNDAEL192: gcry_rijndael
+RIJNDAEL256: gcry_rijndael
+AES128: gcry_rijndael
+AES-128: gcry_rijndael
+AES-192: gcry_rijndael
+AES-256: gcry_rijndael
+ADLER32: adler32
+CRC64: crc64
+ARCFOUR: gcry_arcfour
+BLOWFISH: gcry_blowfish
+CAMELLIA128: gcry_camellia
+CAMELLIA192: gcry_camellia
+CAMELLIA256: gcry_camellia
+CAST5: gcry_cast5
+CRC32: gcry_crc
+CRC32RFC1510: gcry_crc
+CRC24RFC2440: gcry_crc
+DES: gcry_des
+3DES: gcry_des
+DSA: gcry_dsa
+IDEA: gcry_idea
+MD4: gcry_md4
+MD5: gcry_md5
+RFC2268_40: gcry_rfc2268
+AES: gcry_rijndael
+AES192: gcry_rijndael
+AES256: gcry_rijndael
+RIPEMD160: gcry_rmd160
+RSA: gcry_rsa
+SEED: gcry_seed
+SERPENT128: gcry_serpent
+SERPENT192: gcry_serpent
+SERPENT256: gcry_serpent
+SHA1: gcry_sha1
+SHA224: gcry_sha256
+SHA256: gcry_sha256
+SHA512: gcry_sha512
+SHA384: gcry_sha512
+TIGER192: gcry_tiger
+TIGER: gcry_tiger
+TIGER2: gcry_tiger
+TWOFISH: gcry_twofish
+TWOFISH128: gcry_twofish
+WHIRLPOOL: gcry_whirlpool
Index: boot/grub/arm64-efi/arm64-efi/fs.lst
===================================================================
--- boot/grub/arm64-efi/arm64-efi/fs.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/arm64-efi/arm64-efi/fs.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,36 @@
+affs
+afs
+bfs
+btrfs
+cbfs
+cpio
+cpio_be
+exfat
+ext2
+fat
+hfs
+hfsplus
+iso9660
+jfs
+minix
+minix2
+minix2_be
+minix3
+minix3_be
+minix_be
+newc
+nilfs2
+ntfs
+odc
+procfs
+reiserfs
+romfs
+sfs
+squash4
+tar
+udf
+ufs1
+ufs1_be
+ufs2
+xfs
+zfs
Index: boot/grub/arm64-efi/arm64-efi/gdb_grub
===================================================================
--- boot/grub/arm64-efi/arm64-efi/gdb_grub	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/arm64-efi/arm64-efi/gdb_grub	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,85 @@
+###
+### Load debuging information about GNU GRUB 2 modules into GDB
+### automatically. Needs readelf, Perl and gmodule.pl script
+###
+### Has to be launched from the writable and trusted
+### directory containing *.image and *.module
+###
+### $Id: .gdbinit,v 1.1 2006/05/14 11:38:08 lkundrak Exp $
+### Lubomir Kundrak <lkudrak@skosi.org>
+###
+
+# Add section numbers and addresses to .segments.tmp
+define dump_module_sections
+	set $mod = $arg0
+
+	# FIXME: save logging status
+	set logging file .segments.tmp
+	set logging redirect on
+	set logging overwrite off
+	set logging on
+
+	printf "%s", $mod->name
+	set $segment = $mod->segment
+	while ($segment)
+		printf " %i 0x%lx", $segment->section, $segment->addr
+		set $segment = $segment->next
+	end
+	printf "\n"
+
+	set logging off
+	# FIXME: restore logging status
+end
+document dump_module_sections
+	Gather information about module whose mod structure was
+	given for use with match_and_load_symbols
+end
+
+# Generate and execute GDB commands and delete temporary files
+# afterwards
+define match_and_load_symbols
+	shell perl gmodule.pl <.segments.tmp >.loadsym.gdb
+	source .loadsym.gdb
+	shell rm -f .segments.tmp .loadsym.gdb
+end
+document match_and_load_symbols
+	Launch script, that matches section names with information
+	generated by dump_module_sections and load debugging info
+	apropriately
+end
+
+###
+
+define load_module
+	dump_module_sections $arg0
+	match_and_load_symbols
+end
+document load_module
+	Load debugging information for module given as argument.
+end
+
+define load_all_modules
+	set $this = grub_dl_head
+	while ($this != 0)
+		dump_module_sections $this
+		set $this = $this->next
+	end
+	match_and_load_symbols
+end
+document load_all_modules
+	Load debugging information for all loaded modules.
+end
+
+###
+
+set confirm off
+file kernel.exec
+target remote :1234
+
+# inform when module is loaded
+break grub_dl_add
+commands
+	silent
+	load_module mod
+	cont
+end
Index: boot/grub/arm64-efi/arm64-efi/gmodule.pl
===================================================================
--- boot/grub/arm64-efi/arm64-efi/gmodule.pl	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/arm64-efi/arm64-efi/gmodule.pl	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,30 @@
+###
+### Generate GDB commands, that load symbols for specified module,
+### with proper section relocations. See .gdbinit
+###
+### $Id: gmodule.pl,v 1.2 2006/05/14 11:38:42 lkundrak Exp lkundrak $
+### Lubomir Kundrak <lkudrak@skosi.org>
+###
+
+use strict;
+
+while (<>) {
+	my ($name, %sections) = split;
+
+	print "add-symbol-file $name.module";
+
+	open (READELF, "readelf -S $name.mod |") or die;
+	while (<READELF>) {
+		/\[\s*(\d+)\]\s+(\.\S+)/ or next;
+
+		if ($2 eq '.text') {
+			print " $sections{$1}";
+			next;
+		}
+
+		print " -s $2 $sections{$1}"
+			if ($sections{$1} ne '0x0' and $sections{$1} ne '');
+	};
+	close (READELF);
+	print "\n";
+}
Index: boot/grub/arm64-efi/arm64-efi/moddep.lst
===================================================================
--- boot/grub/arm64-efi/arm64-efi/moddep.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/arm64-efi/arm64-efi/moddep.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,210 @@
+videotest: font video gfxmenu
+odc: archelp
+loopback: extcmd
+macho:
+gcry_des: crypto
+memrw: extcmd
+terminfo: extcmd
+part_gpt:
+romfs: fshelp
+read:
+lsefimmap:
+gcry_arcfour: crypto
+tftp: net priority_queue
+newc: archelp
+minix2_be:
+elf:
+videotest_checksum: font functional_test video_fb
+password_pbkdf2: crypto gcry_sha512 pbkdf2 normal
+gcry_seed: crypto
+sfs: fshelp
+reiserfs: fshelp
+part_sunpc:
+gfxmenu: video_colors trig bitmap_scale gfxterm font normal video bitmap
+jfs:
+help: extcmd normal
+configfile: normal
+gfxterm_menu: font functional_test procfs normal video_fb
+gcry_idea: crypto
+tr: extcmd
+shift_test: functional_test
+afs: fshelp
+xzio: crypto
+syslinuxcfg: extcmd normal
+search_fs_file:
+test_blockarg: extcmd normal
+xen_boot: linux boot fdt
+true:
+affs: fshelp
+iso9660: fshelp
+exfat: fshelp
+setjmp_test: functional_test setjmp
+gfxterm: font video
+fdt:
+efinet: net
+disk:
+xfs: fshelp
+testspeed: extcmd normal
+cpio_be: archelp
+functional_test: btrfs extcmd video video_fb
+bswap_test: functional_test
+sleep: extcmd normal
+memdisk:
+gcry_rijndael: crypto
+mdraid09_be: diskfilter
+gettext:
+gcry_sha1: crypto
+hfspluscomp: gzio hfsplus
+cmp:
+offsetio:
+file: macho elf extcmd offsetio
+video_colors:
+hashsum: crypto extcmd normal
+halt:
+gfxterm_background: video_colors bitmap_scale gfxterm extcmd video bitmap
+search_fs_uuid:
+gcry_dsa: verify mpi
+keystatus: extcmd
+linux: boot fdt
+geli: cryptodisk crypto gcry_sha512 pbkdf2 gcry_sha256
+cmdline_cat_test: font functional_test procfs normal video_fb
+part_sun:
+pbkdf2_test: functional_test pbkdf2 gcry_sha1
+bufio:
+bfs: fshelp
+gcry_blowfish: crypto
+test:
+nilfs2: fshelp
+gcry_rsa: verify mpi
+cryptodisk: crypto extcmd procfs
+minicmd:
+signature_test: functional_test procfs
+udf: fshelp
+gzio:
+xnu_uuid: gcry_md5
+mul_test: functional_test
+adler32: crypto
+terminal:
+div:
+crypto:
+part_bsd: part_msdos
+gcry_sha512: crypto
+password: crypto normal
+fshelp:
+sleep_test: functional_test datetime
+mmap:
+exfctest: functional_test
+zfsinfo: zfs
+ldm: part_gpt diskfilter part_msdos
+eval: normal
+part_dvh:
+lssal:
+ext2: fshelp
+blocklist:
+net: priority_queue bufio datetime boot
+part_acorn:
+videoinfo: video
+btrfs: lzopio gzio
+lsmmap: mmap
+bitmap:
+ntfs: fshelp
+gcry_crc: crypto
+png: bufio bitmap
+jpeg: bufio bitmap
+macbless: disk
+div_test: functional_test div
+regexp: extcmd normal
+parttool: normal
+cpio: archelp
+gcry_rmd160: crypto
+fat: fshelp
+ufs1_be:
+archelp:
+raid6rec: diskfilter
+http: net
+zfs: gzio
+lsefisystab:
+minix2:
+lsacpi: extcmd acpi
+datehook: datetime normal
+loadenv: disk extcmd
+bitmap_scale: bitmap
+probe: extcmd
+minix3:
+tar: archelp
+hfs: fshelp
+procfs: archelp
+boot:
+progress: normal
+kernel:
+acpi: extcmd mmap
+tga: bufio bitmap
+reboot:
+serial: extcmd terminfo
+zfscrypt: crypto pbkdf2 zfs extcmd gcry_sha1 gcry_rijndael
+dm_nv: diskfilter
+cmp_test: functional_test
+luks: cryptodisk crypto pbkdf2
+font: bufio video
+raid5rec: diskfilter
+crc64: crypto
+datetime:
+efifwsetup: reboot
+ctz_test: functional_test
+video:
+hfsplus: fshelp
+gcry_cast5: crypto
+extcmd:
+squash4: fshelp lzopio xzio gzio
+part_plan:
+minix_be:
+gcry_whirlpool: crypto
+gcry_tiger: crypto
+search: search_fs_uuid search_fs_file extcmd search_label
+video_fb:
+verify: crypto extcmd mpi gcry_sha1
+minix3_be:
+trig:
+msdospart: disk parttool
+priority_queue:
+gcry_twofish: crypto
+part_dfly:
+xnu_uuid_test: functional_test
+diskfilter:
+testload:
+part_apple:
+hexdump: extcmd
+date: datetime normal
+pbkdf2: crypto
+gcry_sha256: crypto
+ls: extcmd normal
+ntfscomp: ntfs
+lzopio: crypto
+hello: extcmd
+scsi:
+cat: extcmd
+normal: terminal crypto bufio extcmd boot gettext
+ufs1:
+mdraid09: diskfilter
+lvm: diskfilter
+chain: net efinet boot
+cbfs: archelp
+ufs2:
+time:
+gptsync: disk
+search_label:
+setjmp:
+gcry_rfc2268: crypto
+mdraid1x: diskfilter
+mpi: crypto
+part_amiga:
+efi_gop: video video_fb
+minix:
+echo: extcmd
+lsefi:
+gcry_serpent: crypto
+gcry_md4: crypto
+gcry_md5: crypto
+part_msdos:
+gcry_camellia: crypto
+all_video: efi_gop
Index: boot/grub/arm64-efi/arm64-efi/modinfo.sh
===================================================================
--- boot/grub/arm64-efi/arm64-efi/modinfo.sh	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/arm64-efi/arm64-efi/modinfo.sh	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+# User-controllable options
+grub_modinfo_target_cpu=arm64
+grub_modinfo_platform=efi
+grub_disk_cache_stats=0
+grub_boot_time_stats=0
+grub_have_font_source=1
+
+# Autodetected config
+grub_have_asm_uscore=0
+grub_bss_start_symbol=""
+grub_end_symbol=""
+
+# Build environment
+grub_target_cc='aarch64-linux-gnu-gcc'
+grub_target_cc_version='aarch64-linux-gnu-gcc (Linaro GCC 6.3-2017.02) 6.3.1 20170109'
+grub_target_cflags=' -Os -Wall -W -Wshadow -Wpointer-arith -Wundef -Wchar-subscripts -Wcomment -Wdeprecated-declarations -Wdisabled-optimization -Wdiv-by-zero -Wfloat-equal -Wformat-extra-args -Wformat-security -Wformat-y2k -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Wmain -Wmissing-braces -Wmissing-format-attribute -Wmultichar -Wparentheses -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wswitch -Wtrigraphs -Wunknown-pragmas -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value  -Wunused-variable -Wwrite-strings -Wnested-externs -Wstrict-prototypes -g -Wredundant-decls -Wmissing-prototypes -Wmissing-declarations -Wcast-align  -Wextra -Wattributes -Wendif-labels -Winit-self -Wint-to-pointer-cast -Winvalid-pch -Wmissing-field-initializers -Wnonnull -Woverflow -Wvla -Wpointer-to-int-cast -Wstrict-aliasing -Wvariadic-macros -Wvolatile-register-var -Wpointer-sign -Wmissing-include-dirs -Wmissing-prototypes -Wmissing-declarations -Wformat=2 -freg-struct-return -mgeneral-regs-only -fno-dwarf2-cfi-asm -fno-asynchronous-unwind-tables -fno-unwind-tables -Qn -fno-stack-protector -Wtrampolines'
+grub_target_cppflags=' -Wall -W  -DGRUB_MACHINE_EFI=1 -DGRUB_MACHINE=ARM64_EFI -nostdinc -isystem /home/setup/opt/gcc-linaro-6.3.1-2017.02-x86_64_aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/6.3.1/include -I$(top_srcdir)/include -I$(top_builddir)/include'
+grub_target_ccasflags=' -g  -mgeneral-regs-only'
+grub_target_ldflags=' -Wl,--build-id=none'
+grub_cflags=''
+grub_cppflags=' -D_FILE_OFFSET_BITS=64'
+grub_ccasflags=''
+grub_ldflags=''
+grub_target_strip='aarch64-linux-gnu-strip'
+grub_target_nm='aarch64-linux-gnu-nm'
+grub_target_ranlib='aarch64-linux-gnu-ranlib'
+grub_target_objconf=''
+grub_target_obj2elf=''
+grub_target_img_base_ldopt='-Wl,-Ttext'
+grub_target_img_ldflags='@TARGET_IMG_BASE_LDFLAGS@'
+
+# Version
+grub_version="2.02~beta2"
+grub_package="grub"
+grub_package_string="GRUB 2.02~beta2"
+grub_package_version="2.02~beta2"
+grub_package_name="GRUB"
+grub_package_bugreport="bug-grub@gnu.org"
Index: boot/grub/arm64-efi/arm64-efi/partmap.lst
===================================================================
--- boot/grub/arm64-efi/arm64-efi/partmap.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/arm64-efi/arm64-efi/partmap.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,11 @@
+part_acorn
+part_amiga
+part_apple
+part_bsd
+part_dfly
+part_dvh
+part_gpt
+part_msdos
+part_plan
+part_sun
+part_sunpc
Index: boot/grub/arm64-efi/arm64-efi/parttool.lst
===================================================================
--- boot/grub/arm64-efi/arm64-efi/parttool.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/arm64-efi/arm64-efi/parttool.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+msdos: msdospart
Index: boot/grub/arm64-efi/arm64-efi/terminal.lst
===================================================================
--- boot/grub/arm64-efi/arm64-efi/terminal.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/arm64-efi/arm64-efi/terminal.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,3 @@
+iserial_*: serial
+ogfxterm: gfxterm
+oserial_*: serial
Index: boot/grub/arm64-efi/arm64-efi/video.lst
===================================================================
--- boot/grub/arm64-efi/arm64-efi/video.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/arm64-efi/arm64-efi/video.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+efi_gop
Index: boot/grub/ia32-efi/COPYING
===================================================================
--- boot/grub/ia32-efi/COPYING	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/COPYING	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
Index: boot/grub/ia32-efi/README
===================================================================
--- boot/grub/ia32-efi/README	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/README	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,12 @@
+The binary files of GRUB boot loader in this directory have been created
+by compiling GRUB for the 'i386-efi' and 'x86_64-efi' targets. The combined
+32bit and 64bit EFI boot floppy image was created by modifying the
+i386-grub-mkrescue and x86_64-grub-mkrescue scripts to create EFI payloads
+which search for the bootable ISO image with the volume label
+'HelenOS boot ISO'.
+
+For licensing terms of GRUB boot loader see the file COPYING contained
+in this directory. Full version of GRUB, including its source code,
+can be downloaded from GRUB's project page:
+
+http://www.gnu.org/software/grub/
Index: boot/grub/ia32-efi/REVISION
===================================================================
--- boot/grub/ia32-efi/REVISION	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/REVISION	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+bc220962e366b1b46769ed6f9fa5be603ba58ab5
Index: boot/grub/ia32-efi/i386-efi/command.lst
===================================================================
--- boot/grub/ia32-efi/i386-efi/command.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/i386-efi/command.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,190 @@
+*acpi: acpi
+*all_functional_test: functional_test
+*background_image: gfxterm_background
+*cat: cat
+*cpuid: cpuid
+*crc: hashsum
+*cryptomount: cryptodisk
+*echo: echo
+*extract_syslinux_entries_configfile: syslinuxcfg
+*extract_syslinux_entries_source: syslinuxcfg
+*file: file
+*functional_test: functional_test
+*gettext: gettext
+*hashsum: hashsum
+*hdparm: hdparm
+*hello: hello
+*help: help
+*hexdump: hexdump
+*inb: iorw
+*inl: iorw
+*inw: iorw
+*keystatus: keystatus
+*kfreebsd: bsd
+*knetbsd: bsd
+*kopenbsd: bsd
+*list_env: loadenv
+*load_env: loadenv
+*loopback: loopback
+*ls: ls
+*lsacpi: lsacpi
+*lspci: lspci
+*md5sum: hashsum
+*menuentry: normal
+*pcidump: pcidump
+*probe: probe
+*read_byte: memrw
+*read_dword: memrw
+*read_word: memrw
+*regexp: regexp
+*save_env: loadenv
+*search: search
+*serial: serial
+*setpci: setpci
+*sha1sum: hashsum
+*sha256sum: hashsum
+*sha512sum: hashsum
+*sleep: sleep
+*submenu: normal
+*syslinux_configfile: syslinuxcfg
+*syslinux_source: syslinuxcfg
+*terminfo: terminfo
+*test_blockarg: test_blockarg
+*testspeed: testspeed
+*tr: tr
+*trust: verify
+*verify_detached: verify
+*xnu_splash: xnu
+*zfskey: zfscrypt
+.: configfile
+[: test
+appleloader: appleldr
+authenticate: normal
+background_color: gfxterm_background
+backtrace: backtrace
+badram: mmap
+blocklist: blocklist
+boot: boot
+break: normal
+cat: minicmd
+cbmemc: cbmemc
+chainloader: chain
+clear: normal
+cmp: cmp
+configfile: configfile
+continue: normal
+coreboot_boottime: cbtime
+cutmem: mmap
+date: date
+distrust: verify
+dump: minicmd
+eval: eval
+exit: minicmd
+export: normal
+extract_entries_configfile: configfile
+extract_entries_source: configfile
+extract_legacy_entries_configfile: legacycfg
+extract_legacy_entries_source: legacycfg
+fakebios: loadbios
+false: true
+fix_video: fixvideo
+fwsetup: efifwsetup
+gdbstub: gdb
+gdbstub_break: gdb
+gdbstub_stop: gdb
+gptsync: gptsync
+halt: halt
+help: minicmd
+hexdump_random: random
+initrd16: linux16
+initrd: linux
+keymap: keylayouts
+kfreebsd_loadenv: bsd
+kfreebsd_module: bsd
+kfreebsd_module_elf: bsd
+knetbsd_module: bsd
+knetbsd_module_elf: bsd
+kopenbsd_ramdisk: bsd
+legacy_check_password: legacycfg
+legacy_configfile: legacycfg
+legacy_initrd: legacycfg
+legacy_initrd_nounzip: legacycfg
+legacy_kernel: legacycfg
+legacy_password: legacycfg
+legacy_source: legacycfg
+linux16: linux16
+linux: linux
+list_trusted: verify
+loadbios: loadbios
+loadfont: font
+lscoreboot: cbls
+lsefi: lsefi
+lsefimmap: lsefimmap
+lsefisystab: lsefisystab
+lsfonts: font
+lsmmap: lsmmap
+lsmod: minicmd
+lssal: lssal
+macppcbless: macbless
+mactelbless: macbless
+module2: multiboot2
+module: multiboot
+multiboot2: multiboot2
+multiboot: multiboot
+nativedisk: nativedisk
+net_add_addr: net
+net_add_dns: net
+net_add_route: net
+net_bootp: net
+net_del_addr: net
+net_del_dns: net
+net_del_route: net
+net_get_dhcp_option: net
+net_ipv6_autoconf: net
+net_ls_addr: net
+net_ls_cards: net
+net_ls_dns: net
+net_ls_routes: net
+net_nslookup: net
+normal: normal
+normal_exit: normal
+outb: iorw
+outl: iorw
+outw: iorw
+parttool: parttool
+password: password
+password_pbkdf2: password_pbkdf2
+play: play
+read: read
+reboot: reboot
+return: normal
+rmmod: minicmd
+search.file: search_fs_file
+search.fs_label: search_label
+search.fs_uuid: search_fs_uuid
+setparams: normal
+shift: normal
+source: configfile
+terminal_input: terminal
+terminal_output: terminal
+test: test
+testload: testload
+time: time
+true: true
+usb: usbtest
+videoinfo: videoinfo
+videotest: videotest
+write_byte: memrw
+write_dword: memrw
+write_word: memrw
+xnu_devprop_load: xnu
+xnu_kernel64: xnu
+xnu_kernel: xnu
+xnu_kext: xnu
+xnu_kextdir: xnu
+xnu_mkext: xnu
+xnu_ramdisk: xnu
+xnu_resume: xnu
+xnu_uuid: xnu_uuid
+zfs-bootfs: zfsinfo
+zfsinfo: zfsinfo
Index: boot/grub/ia32-efi/i386-efi/crypto.lst
===================================================================
--- boot/grub/ia32-efi/i386-efi/crypto.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/i386-efi/crypto.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,45 @@
+RIJNDAEL: gcry_rijndael
+RIJNDAEL192: gcry_rijndael
+RIJNDAEL256: gcry_rijndael
+AES128: gcry_rijndael
+AES-128: gcry_rijndael
+AES-192: gcry_rijndael
+AES-256: gcry_rijndael
+ADLER32: adler32
+CRC64: crc64
+ARCFOUR: gcry_arcfour
+BLOWFISH: gcry_blowfish
+CAMELLIA128: gcry_camellia
+CAMELLIA192: gcry_camellia
+CAMELLIA256: gcry_camellia
+CAST5: gcry_cast5
+CRC32: gcry_crc
+CRC32RFC1510: gcry_crc
+CRC24RFC2440: gcry_crc
+DES: gcry_des
+3DES: gcry_des
+DSA: gcry_dsa
+IDEA: gcry_idea
+MD4: gcry_md4
+MD5: gcry_md5
+RFC2268_40: gcry_rfc2268
+AES: gcry_rijndael
+AES192: gcry_rijndael
+AES256: gcry_rijndael
+RIPEMD160: gcry_rmd160
+RSA: gcry_rsa
+SEED: gcry_seed
+SERPENT128: gcry_serpent
+SERPENT192: gcry_serpent
+SERPENT256: gcry_serpent
+SHA1: gcry_sha1
+SHA224: gcry_sha256
+SHA256: gcry_sha256
+SHA512: gcry_sha512
+SHA384: gcry_sha512
+TIGER192: gcry_tiger
+TIGER: gcry_tiger
+TIGER2: gcry_tiger
+TWOFISH: gcry_twofish
+TWOFISH128: gcry_twofish
+WHIRLPOOL: gcry_whirlpool
Index: boot/grub/ia32-efi/i386-efi/fs.lst
===================================================================
--- boot/grub/ia32-efi/i386-efi/fs.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/i386-efi/fs.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,36 @@
+affs
+afs
+bfs
+btrfs
+cbfs
+cpio
+cpio_be
+exfat
+ext2
+fat
+hfs
+hfsplus
+iso9660
+jfs
+minix
+minix2
+minix2_be
+minix3
+minix3_be
+minix_be
+newc
+nilfs2
+ntfs
+odc
+procfs
+reiserfs
+romfs
+sfs
+squash4
+tar
+udf
+ufs1
+ufs1_be
+ufs2
+xfs
+zfs
Index: boot/grub/ia32-efi/i386-efi/gdb_grub
===================================================================
--- boot/grub/ia32-efi/i386-efi/gdb_grub	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/i386-efi/gdb_grub	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,85 @@
+###
+### Load debuging information about GNU GRUB 2 modules into GDB
+### automatically. Needs readelf, Perl and gmodule.pl script
+###
+### Has to be launched from the writable and trusted
+### directory containing *.image and *.module
+###
+### $Id: .gdbinit,v 1.1 2006/05/14 11:38:08 lkundrak Exp $
+### Lubomir Kundrak <lkudrak@skosi.org>
+###
+
+# Add section numbers and addresses to .segments.tmp
+define dump_module_sections
+	set $mod = $arg0
+
+	# FIXME: save logging status
+	set logging file .segments.tmp
+	set logging redirect on
+	set logging overwrite off
+	set logging on
+
+	printf "%s", $mod->name
+	set $segment = $mod->segment
+	while ($segment)
+		printf " %i 0x%lx", $segment->section, $segment->addr
+		set $segment = $segment->next
+	end
+	printf "\n"
+
+	set logging off
+	# FIXME: restore logging status
+end
+document dump_module_sections
+	Gather information about module whose mod structure was
+	given for use with match_and_load_symbols
+end
+
+# Generate and execute GDB commands and delete temporary files
+# afterwards
+define match_and_load_symbols
+	shell perl gmodule.pl <.segments.tmp >.loadsym.gdb
+	source .loadsym.gdb
+	shell rm -f .segments.tmp .loadsym.gdb
+end
+document match_and_load_symbols
+	Launch script, that matches section names with information
+	generated by dump_module_sections and load debugging info
+	apropriately
+end
+
+###
+
+define load_module
+	dump_module_sections $arg0
+	match_and_load_symbols
+end
+document load_module
+	Load debugging information for module given as argument.
+end
+
+define load_all_modules
+	set $this = grub_dl_head
+	while ($this != 0)
+		dump_module_sections $this
+		set $this = $this->next
+	end
+	match_and_load_symbols
+end
+document load_all_modules
+	Load debugging information for all loaded modules.
+end
+
+###
+
+set confirm off
+file kernel.exec
+target remote :1234
+
+# inform when module is loaded
+break grub_dl_add
+commands
+	silent
+	load_module mod
+	cont
+end
Index: boot/grub/ia32-efi/i386-efi/gmodule.pl
===================================================================
--- boot/grub/ia32-efi/i386-efi/gmodule.pl	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/i386-efi/gmodule.pl	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,30 @@
+###
+### Generate GDB commands, that load symbols for specified module,
+### with proper section relocations. See .gdbinit
+###
+### $Id: gmodule.pl,v 1.2 2006/05/14 11:38:42 lkundrak Exp lkundrak $
+### Lubomir Kundrak <lkudrak@skosi.org>
+###
+
+use strict;
+
+while (<>) {
+	my ($name, %sections) = split;
+
+	print "add-symbol-file $name.module";
+
+	open (READELF, "readelf -S $name.mod |") or die;
+	while (<READELF>) {
+		/\[\s*(\d+)\]\s+(\.\S+)/ or next;
+
+		if ($2 eq '.text') {
+			print " $sections{$1}";
+			next;
+		}
+
+		print " -s $2 $sections{$1}"
+			if ($sections{$1} ne '0x0' and $sections{$1} ne '');
+	};
+	close (READELF);
+	print "\n";
+}
Index: boot/grub/ia32-efi/i386-efi/moddep.lst
===================================================================
--- boot/grub/ia32-efi/i386-efi/moddep.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/i386-efi/moddep.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,257 @@
+videotest: font video gfxmenu
+odc: archelp
+loopback: extcmd
+macho:
+gcry_des: crypto
+memrw: extcmd
+terminfo: extcmd
+part_gpt:
+romfs: fshelp
+read:
+lsefimmap:
+aout:
+gcry_arcfour: crypto
+tftp: net priority_queue
+newc: archelp
+minix2_be:
+elf:
+videotest_checksum: font functional_test video_fb
+password_pbkdf2: crypto gcry_sha512 pbkdf2 normal
+gcry_seed: crypto
+pcidump: extcmd
+bsd: elf serial crypto gcry_md5 extcmd video boot aout cpuid relocator mmap
+sfs: fshelp
+reiserfs: fshelp
+part_sunpc:
+gfxmenu: video_colors trig bitmap_scale gfxterm font normal video bitmap
+backtrace:
+jfs:
+help: extcmd normal
+configfile: normal
+cbls: cbtable
+gfxterm_menu: font functional_test procfs normal video_fb
+gcry_idea: crypto
+tr: extcmd
+shift_test: functional_test
+ohci: cs5536 usb boot
+afs: fshelp
+spkmodem: terminfo
+usb_keyboard: usb keylayouts
+xzio: crypto
+syslinuxcfg: extcmd normal
+search_fs_file:
+usbms: scsi usb
+test_blockarg: extcmd normal
+true:
+affs: fshelp
+iso9660: fshelp
+exfat: fshelp
+setjmp_test: functional_test setjmp
+gfxterm: font video
+efinet: net
+disk:
+appleldr: boot
+xfs: fshelp
+testspeed: extcmd normal
+cpio_be: archelp
+functional_test: btrfs extcmd video video_fb
+bswap_test: functional_test
+sleep: extcmd normal
+memdisk:
+gcry_rijndael: crypto
+mdraid09_be: diskfilter
+gettext:
+gcry_sha1: crypto
+hfspluscomp: gzio hfsplus
+cmp:
+random: hexdump
+offsetio:
+file: macho elf extcmd offsetio
+usbserial_usbdebug: serial usb usbserial_common
+video_colors:
+morse:
+hashsum: crypto extcmd normal
+usb:
+halt: acpi
+gdb: serial backtrace
+gfxterm_background: video_colors bitmap_scale gfxterm extcmd video bitmap
+search_fs_uuid:
+gcry_dsa: verify mpi
+keystatus: extcmd
+linux: video boot relocator mmap
+geli: cryptodisk crypto gcry_sha512 pbkdf2 gcry_sha256
+cmdline_cat_test: font functional_test procfs normal video_fb
+part_sun:
+cbtable:
+pbkdf2_test: functional_test pbkdf2 gcry_sha1
+video_bochs: video video_fb
+bufio:
+usbserial_ftdi: serial usb usbserial_common
+legacy_password_test: functional_test legacycfg
+cpuid: extcmd
+bfs: fshelp
+hdparm: extcmd
+gcry_blowfish: crypto
+test:
+nilfs2: fshelp
+gcry_rsa: verify mpi
+cryptodisk: crypto extcmd procfs
+nativedisk:
+minicmd:
+signature_test: functional_test procfs
+ata: scsi
+udf: fshelp
+gzio:
+xnu_uuid: gcry_md5
+uhci: usb
+pata: ata
+mul_test: functional_test
+adler32: crypto
+terminal:
+div:
+ehci: cs5536 usb boot
+crypto:
+part_bsd: part_msdos
+cs5536:
+gcry_sha512: crypto
+password: crypto normal
+fshelp:
+sleep_test: functional_test datetime
+iorw: extcmd
+xnu: macho bitmap_scale random extcmd video bitmap boot relocator mmap
+mmap:
+exfctest: functional_test
+zfsinfo: zfs
+ldm: part_gpt diskfilter part_msdos
+eval: normal
+part_dvh:
+lssal:
+ext2: fshelp
+blocklist:
+net: priority_queue bufio datetime boot
+part_acorn:
+videoinfo: video
+btrfs: lzopio gzio
+lsmmap: mmap
+bitmap:
+ntfs: fshelp
+multiboot: net video boot relocator mmap
+gcry_crc: crypto
+png: bufio bitmap
+jpeg: bufio bitmap
+macbless: disk
+div_test: functional_test div
+regexp: extcmd normal
+parttool: normal
+usbserial_pl2303: serial usb usbserial_common
+cpio: archelp
+gcry_rmd160: crypto
+fat: fshelp
+ufs1_be:
+archelp:
+raid6rec: diskfilter
+http: net
+zfs: gzio
+lsefisystab:
+minix2:
+lsacpi: extcmd acpi
+datehook: datetime normal
+loadenv: disk extcmd
+bitmap_scale: bitmap
+probe: extcmd
+minix3:
+tar: archelp
+loadbios:
+hfs: fshelp
+procfs: archelp
+boot:
+keylayouts:
+progress: normal
+kernel:
+usbtest: usb
+relocator: mmap
+acpi: extcmd mmap
+tga: bufio bitmap
+reboot: relocator
+serial: extcmd terminfo
+zfscrypt: crypto pbkdf2 zfs extcmd gcry_sha1 gcry_rijndael
+efi_uga: video video_fb
+dm_nv: diskfilter
+cmp_test: functional_test
+luks: cryptodisk crypto pbkdf2
+font: bufio video
+raid5rec: diskfilter
+crc64: crypto
+datetime:
+efifwsetup: reboot
+ctz_test: functional_test
+video:
+cbmemc: normal cbtable terminfo
+hfsplus: fshelp
+gcry_cast5: crypto
+extcmd:
+squash4: fshelp lzopio xzio gzio
+part_plan:
+minix_be:
+gcry_whirlpool: crypto
+gcry_tiger: crypto
+fixvideo:
+search: search_fs_uuid search_fs_file extcmd search_label
+lspci: extcmd
+cbtime: cbtable
+video_fb:
+verify: crypto extcmd mpi gcry_sha1
+minix3_be:
+trig:
+msdospart: disk parttool
+priority_queue:
+gcry_twofish: crypto
+part_dfly:
+xnu_uuid_test: functional_test
+diskfilter:
+testload:
+part_apple:
+hexdump: extcmd
+date: datetime normal
+pbkdf2: crypto
+gcry_sha256: crypto
+ls: extcmd normal
+usbserial_common: serial usb
+ntfscomp: ntfs
+lzopio: crypto
+video_cirrus: video video_fb
+hello: extcmd
+scsi:
+cat: extcmd
+ahci: ata boot
+normal: terminal crypto bufio extcmd boot gettext
+linux16: video boot relocator mmap
+ufs1:
+mdraid09: diskfilter
+lvm: diskfilter
+chain: net efinet boot
+cbfs: archelp
+ufs2:
+time:
+setpci: extcmd
+gptsync: disk
+search_label:
+setjmp:
+multiboot2: net video boot relocator mmap acpi
+gcry_rfc2268: crypto
+mdraid1x: diskfilter
+mpi: crypto
+legacycfg: password crypto gcry_md5 normal
+play:
+part_amiga:
+efi_gop: video video_fb
+minix:
+echo: extcmd
+lsefi:
+gcry_serpent: crypto
+gcry_md4: crypto
+gcry_md5: crypto
+part_msdos:
+gcry_camellia: crypto
+at_keyboard: keylayouts boot
+all_video: efi_gop efi_uga video_bochs video_cirrus
Index: boot/grub/ia32-efi/i386-efi/modinfo.sh
===================================================================
--- boot/grub/ia32-efi/i386-efi/modinfo.sh	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/i386-efi/modinfo.sh	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+# User-controllable options
+grub_modinfo_target_cpu=i386
+grub_modinfo_platform=efi
+grub_disk_cache_stats=0
+grub_boot_time_stats=0
+grub_have_font_source=1
+
+# Autodetected config
+grub_have_asm_uscore=0
+grub_bss_start_symbol="__bss_start"
+grub_end_symbol="end"
+
+# Build environment
+grub_target_cc='gcc'
+grub_target_cc_version='gcc (SUSE Linux) 4.8.5'
+grub_target_cflags=' -Os -Wall -W -Wshadow -Wpointer-arith -Wundef -Wchar-subscripts -Wcomment -Wdeprecated-declarations -Wdisabled-optimization -Wdiv-by-zero -Wfloat-equal -Wformat-extra-args -Wformat-security -Wformat-y2k -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Wmain -Wmissing-braces -Wmissing-format-attribute -Wmultichar -Wparentheses -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wswitch -Wtrigraphs -Wunknown-pragmas -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value  -Wunused-variable -Wwrite-strings -Wnested-externs -Wstrict-prototypes -g -Wredundant-decls -Wmissing-prototypes -Wmissing-declarations  -Wextra -Wattributes -Wendif-labels -Winit-self -Wint-to-pointer-cast -Winvalid-pch -Wmissing-field-initializers -Wnonnull -Woverflow -Wvla -Wpointer-to-int-cast -Wstrict-aliasing -Wvariadic-macros -Wvolatile-register-var -Wpointer-sign -Wmissing-include-dirs -Wmissing-prototypes -Wmissing-declarations -Wformat=2 -march=i386 -m32 -falign-jumps=1 -falign-loops=1 -falign-functions=1 -freg-struct-return -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow -msoft-float -fno-dwarf2-cfi-asm -mno-stack-arg-probe -fno-asynchronous-unwind-tables -fno-unwind-tables -Qn -fno-stack-protector -Wtrampolines -Werror'
+grub_target_cppflags=' -Wall -W  -DGRUB_MACHINE_EFI=1 -DGRUB_MACHINE=I386_EFI -m32 -nostdinc -isystem /usr/lib64/gcc/x86_64-suse-linux/4.8/include -I$(top_srcdir)/include -I$(top_builddir)/include'
+grub_target_ccasflags=' -g  -m32 -msoft-float'
+grub_target_ldflags=' -m32 -Wl,-melf_i386 -Wl,--build-id=none'
+grub_cflags=''
+grub_cppflags=' -D_FILE_OFFSET_BITS=64'
+grub_ccasflags=''
+grub_ldflags=''
+grub_target_strip='strip'
+grub_target_nm='nm'
+grub_target_ranlib='ranlib'
+grub_target_objconf=''
+grub_target_obj2elf=''
+grub_target_img_base_ldopt='-Wl,-Ttext'
+grub_target_img_ldflags='@TARGET_IMG_BASE_LDFLAGS@'
+
+# Version
+grub_version="2.02~beta2"
+grub_package="grub"
+grub_package_string="GRUB 2.02~beta2"
+grub_package_version="2.02~beta2"
+grub_package_name="GRUB"
+grub_package_bugreport="bug-grub@gnu.org"
Index: boot/grub/ia32-efi/i386-efi/partmap.lst
===================================================================
--- boot/grub/ia32-efi/i386-efi/partmap.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/i386-efi/partmap.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,11 @@
+part_acorn
+part_amiga
+part_apple
+part_bsd
+part_dfly
+part_dvh
+part_gpt
+part_msdos
+part_plan
+part_sun
+part_sunpc
Index: boot/grub/ia32-efi/i386-efi/parttool.lst
===================================================================
--- boot/grub/ia32-efi/i386-efi/parttool.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/i386-efi/parttool.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+msdos: msdospart
Index: boot/grub/ia32-efi/i386-efi/terminal.lst
===================================================================
--- boot/grub/ia32-efi/i386-efi/terminal.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/i386-efi/terminal.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,9 @@
+iat_keyboard: at_keyboard
+iserial: serial
+iserial_*: serial
+oaudio: morse
+ocbmemc: cbmemc
+ogfxterm: gfxterm
+oserial: serial
+oserial_*: serial
+ospkmodem: spkmodem
Index: boot/grub/ia32-efi/i386-efi/video.lst
===================================================================
--- boot/grub/ia32-efi/i386-efi/video.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/i386-efi/video.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,4 @@
+efi_gop
+efi_uga
+video_bochs
+video_cirrus
Index: boot/grub/ia32-efi/x86_64-efi/command.lst
===================================================================
--- boot/grub/ia32-efi/x86_64-efi/command.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/x86_64-efi/command.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,187 @@
+*acpi: acpi
+*all_functional_test: functional_test
+*background_image: gfxterm_background
+*cat: cat
+*cpuid: cpuid
+*crc: hashsum
+*cryptomount: cryptodisk
+*echo: echo
+*extract_syslinux_entries_configfile: syslinuxcfg
+*extract_syslinux_entries_source: syslinuxcfg
+*file: file
+*functional_test: functional_test
+*gettext: gettext
+*hashsum: hashsum
+*hdparm: hdparm
+*hello: hello
+*help: help
+*hexdump: hexdump
+*inb: iorw
+*inl: iorw
+*inw: iorw
+*keystatus: keystatus
+*kfreebsd: bsd
+*knetbsd: bsd
+*kopenbsd: bsd
+*list_env: loadenv
+*load_env: loadenv
+*loopback: loopback
+*ls: ls
+*lsacpi: lsacpi
+*lspci: lspci
+*md5sum: hashsum
+*menuentry: normal
+*pcidump: pcidump
+*probe: probe
+*read_byte: memrw
+*read_dword: memrw
+*read_word: memrw
+*regexp: regexp
+*save_env: loadenv
+*search: search
+*serial: serial
+*setpci: setpci
+*sha1sum: hashsum
+*sha256sum: hashsum
+*sha512sum: hashsum
+*sleep: sleep
+*submenu: normal
+*syslinux_configfile: syslinuxcfg
+*syslinux_source: syslinuxcfg
+*terminfo: terminfo
+*test_blockarg: test_blockarg
+*testspeed: testspeed
+*tr: tr
+*trust: verify
+*verify_detached: verify
+*xnu_splash: xnu
+*zfskey: zfscrypt
+.: configfile
+[: test
+appleloader: appleldr
+authenticate: normal
+background_color: gfxterm_background
+backtrace: backtrace
+badram: mmap
+blocklist: blocklist
+boot: boot
+break: normal
+cat: minicmd
+cbmemc: cbmemc
+chainloader: chain
+clear: normal
+cmp: cmp
+configfile: configfile
+continue: normal
+coreboot_boottime: cbtime
+cutmem: mmap
+date: date
+distrust: verify
+dump: minicmd
+eval: eval
+exit: minicmd
+export: normal
+extract_entries_configfile: configfile
+extract_entries_source: configfile
+extract_legacy_entries_configfile: legacycfg
+extract_legacy_entries_source: legacycfg
+fakebios: loadbios
+false: true
+fix_video: fixvideo
+fwsetup: efifwsetup
+gptsync: gptsync
+halt: halt
+help: minicmd
+hexdump_random: random
+initrd16: linux16
+initrd: linux
+keymap: keylayouts
+kfreebsd_loadenv: bsd
+kfreebsd_module: bsd
+kfreebsd_module_elf: bsd
+knetbsd_module: bsd
+knetbsd_module_elf: bsd
+kopenbsd_ramdisk: bsd
+legacy_check_password: legacycfg
+legacy_configfile: legacycfg
+legacy_initrd: legacycfg
+legacy_initrd_nounzip: legacycfg
+legacy_kernel: legacycfg
+legacy_password: legacycfg
+legacy_source: legacycfg
+linux16: linux16
+linux: linux
+list_trusted: verify
+loadbios: loadbios
+loadfont: font
+lscoreboot: cbls
+lsefi: lsefi
+lsefimmap: lsefimmap
+lsefisystab: lsefisystab
+lsfonts: font
+lsmmap: lsmmap
+lsmod: minicmd
+lssal: lssal
+macppcbless: macbless
+mactelbless: macbless
+module2: multiboot2
+module: multiboot
+multiboot2: multiboot2
+multiboot: multiboot
+nativedisk: nativedisk
+net_add_addr: net
+net_add_dns: net
+net_add_route: net
+net_bootp: net
+net_del_addr: net
+net_del_dns: net
+net_del_route: net
+net_get_dhcp_option: net
+net_ipv6_autoconf: net
+net_ls_addr: net
+net_ls_cards: net
+net_ls_dns: net
+net_ls_routes: net
+net_nslookup: net
+normal: normal
+normal_exit: normal
+outb: iorw
+outl: iorw
+outw: iorw
+parttool: parttool
+password: password
+password_pbkdf2: password_pbkdf2
+play: play
+read: read
+reboot: reboot
+return: normal
+rmmod: minicmd
+search.file: search_fs_file
+search.fs_label: search_label
+search.fs_uuid: search_fs_uuid
+setparams: normal
+shift: normal
+source: configfile
+terminal_input: terminal
+terminal_output: terminal
+test: test
+testload: testload
+time: time
+true: true
+usb: usbtest
+videoinfo: videoinfo
+videotest: videotest
+write_byte: memrw
+write_dword: memrw
+write_word: memrw
+xnu_devprop_load: xnu
+xnu_kernel64: xnu
+xnu_kernel: xnu
+xnu_kext: xnu
+xnu_kextdir: xnu
+xnu_mkext: xnu
+xnu_ramdisk: xnu
+xnu_resume: xnu
+xnu_uuid: xnu_uuid
+zfs-bootfs: zfsinfo
+zfsinfo: zfsinfo
Index: boot/grub/ia32-efi/x86_64-efi/crypto.lst
===================================================================
--- boot/grub/ia32-efi/x86_64-efi/crypto.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/x86_64-efi/crypto.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,45 @@
+RIJNDAEL: gcry_rijndael
+RIJNDAEL192: gcry_rijndael
+RIJNDAEL256: gcry_rijndael
+AES128: gcry_rijndael
+AES-128: gcry_rijndael
+AES-192: gcry_rijndael
+AES-256: gcry_rijndael
+ADLER32: adler32
+CRC64: crc64
+ARCFOUR: gcry_arcfour
+BLOWFISH: gcry_blowfish
+CAMELLIA128: gcry_camellia
+CAMELLIA192: gcry_camellia
+CAMELLIA256: gcry_camellia
+CAST5: gcry_cast5
+CRC32: gcry_crc
+CRC32RFC1510: gcry_crc
+CRC24RFC2440: gcry_crc
+DES: gcry_des
+3DES: gcry_des
+DSA: gcry_dsa
+IDEA: gcry_idea
+MD4: gcry_md4
+MD5: gcry_md5
+RFC2268_40: gcry_rfc2268
+AES: gcry_rijndael
+AES192: gcry_rijndael
+AES256: gcry_rijndael
+RIPEMD160: gcry_rmd160
+RSA: gcry_rsa
+SEED: gcry_seed
+SERPENT128: gcry_serpent
+SERPENT192: gcry_serpent
+SERPENT256: gcry_serpent
+SHA1: gcry_sha1
+SHA224: gcry_sha256
+SHA256: gcry_sha256
+SHA512: gcry_sha512
+SHA384: gcry_sha512
+TIGER192: gcry_tiger
+TIGER: gcry_tiger
+TIGER2: gcry_tiger
+TWOFISH: gcry_twofish
+TWOFISH128: gcry_twofish
+WHIRLPOOL: gcry_whirlpool
Index: boot/grub/ia32-efi/x86_64-efi/fs.lst
===================================================================
--- boot/grub/ia32-efi/x86_64-efi/fs.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/x86_64-efi/fs.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,36 @@
+affs
+afs
+bfs
+btrfs
+cbfs
+cpio
+cpio_be
+exfat
+ext2
+fat
+hfs
+hfsplus
+iso9660
+jfs
+minix
+minix2
+minix2_be
+minix3
+minix3_be
+minix_be
+newc
+nilfs2
+ntfs
+odc
+procfs
+reiserfs
+romfs
+sfs
+squash4
+tar
+udf
+ufs1
+ufs1_be
+ufs2
+xfs
+zfs
Index: boot/grub/ia32-efi/x86_64-efi/gdb_grub
===================================================================
--- boot/grub/ia32-efi/x86_64-efi/gdb_grub	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/x86_64-efi/gdb_grub	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,85 @@
+###
+### Load debuging information about GNU GRUB 2 modules into GDB
+### automatically. Needs readelf, Perl and gmodule.pl script
+###
+### Has to be launched from the writable and trusted
+### directory containing *.image and *.module
+###
+### $Id: .gdbinit,v 1.1 2006/05/14 11:38:08 lkundrak Exp $
+### Lubomir Kundrak <lkudrak@skosi.org>
+###
+
+# Add section numbers and addresses to .segments.tmp
+define dump_module_sections
+	set $mod = $arg0
+
+	# FIXME: save logging status
+	set logging file .segments.tmp
+	set logging redirect on
+	set logging overwrite off
+	set logging on
+
+	printf "%s", $mod->name
+	set $segment = $mod->segment
+	while ($segment)
+		printf " %i 0x%lx", $segment->section, $segment->addr
+		set $segment = $segment->next
+	end
+	printf "\n"
+
+	set logging off
+	# FIXME: restore logging status
+end
+document dump_module_sections
+	Gather information about module whose mod structure was
+	given for use with match_and_load_symbols
+end
+
+# Generate and execute GDB commands and delete temporary files
+# afterwards
+define match_and_load_symbols
+	shell perl gmodule.pl <.segments.tmp >.loadsym.gdb
+	source .loadsym.gdb
+	shell rm -f .segments.tmp .loadsym.gdb
+end
+document match_and_load_symbols
+	Launch script, that matches section names with information
+	generated by dump_module_sections and load debugging info
+	apropriately
+end
+
+###
+
+define load_module
+	dump_module_sections $arg0
+	match_and_load_symbols
+end
+document load_module
+	Load debugging information for module given as argument.
+end
+
+define load_all_modules
+	set $this = grub_dl_head
+	while ($this != 0)
+		dump_module_sections $this
+		set $this = $this->next
+	end
+	match_and_load_symbols
+end
+document load_all_modules
+	Load debugging information for all loaded modules.
+end
+
+###
+
+set confirm off
+file kernel.exec
+target remote :1234
+
+# inform when module is loaded
+break grub_dl_add
+commands
+	silent
+	load_module mod
+	cont
+end
Index: boot/grub/ia32-efi/x86_64-efi/gmodule.pl
===================================================================
--- boot/grub/ia32-efi/x86_64-efi/gmodule.pl	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/x86_64-efi/gmodule.pl	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,30 @@
+###
+### Generate GDB commands, that load symbols for specified module,
+### with proper section relocations. See .gdbinit
+###
+### $Id: gmodule.pl,v 1.2 2006/05/14 11:38:42 lkundrak Exp lkundrak $
+### Lubomir Kundrak <lkudrak@skosi.org>
+###
+
+use strict;
+
+while (<>) {
+	my ($name, %sections) = split;
+
+	print "add-symbol-file $name.module";
+
+	open (READELF, "readelf -S $name.mod |") or die;
+	while (<READELF>) {
+		/\[\s*(\d+)\]\s+(\.\S+)/ or next;
+
+		if ($2 eq '.text') {
+			print " $sections{$1}";
+			next;
+		}
+
+		print " -s $2 $sections{$1}"
+			if ($sections{$1} ne '0x0' and $sections{$1} ne '');
+	};
+	close (READELF);
+	print "\n";
+}
Index: boot/grub/ia32-efi/x86_64-efi/moddep.lst
===================================================================
--- boot/grub/ia32-efi/x86_64-efi/moddep.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/x86_64-efi/moddep.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,256 @@
+videotest: font video gfxmenu
+odc: archelp
+loopback: extcmd
+macho:
+gcry_des: crypto
+memrw: extcmd
+terminfo: extcmd
+part_gpt:
+romfs: fshelp
+read:
+lsefimmap:
+aout:
+gcry_arcfour: crypto
+tftp: net priority_queue
+newc: archelp
+minix2_be:
+elf:
+videotest_checksum: font functional_test video_fb
+password_pbkdf2: crypto gcry_sha512 pbkdf2 normal
+gcry_seed: crypto
+pcidump: extcmd
+bsd: elf serial crypto gcry_md5 extcmd video boot aout cpuid relocator mmap
+sfs: fshelp
+reiserfs: fshelp
+part_sunpc:
+gfxmenu: video_colors trig bitmap_scale gfxterm font normal video bitmap
+backtrace:
+jfs:
+help: extcmd normal
+configfile: normal
+cbls: cbtable
+gfxterm_menu: font functional_test procfs normal video_fb
+gcry_idea: crypto
+tr: extcmd
+shift_test: functional_test
+ohci: cs5536 usb boot
+afs: fshelp
+spkmodem: terminfo
+usb_keyboard: usb keylayouts
+xzio: crypto
+syslinuxcfg: extcmd normal
+search_fs_file:
+usbms: scsi usb
+test_blockarg: extcmd normal
+true:
+affs: fshelp
+iso9660: fshelp
+exfat: fshelp
+setjmp_test: functional_test setjmp
+gfxterm: font video
+efinet: net
+disk:
+appleldr: boot
+xfs: fshelp
+testspeed: extcmd normal
+cpio_be: archelp
+functional_test: btrfs extcmd video video_fb
+bswap_test: functional_test
+sleep: extcmd normal
+memdisk:
+gcry_rijndael: crypto
+mdraid09_be: diskfilter
+gettext:
+gcry_sha1: crypto
+hfspluscomp: gzio hfsplus
+cmp:
+random: hexdump
+offsetio:
+file: macho elf extcmd offsetio
+usbserial_usbdebug: serial usb usbserial_common
+video_colors:
+morse:
+hashsum: crypto extcmd normal
+usb:
+halt: acpi
+gfxterm_background: video_colors bitmap_scale gfxterm extcmd video bitmap
+search_fs_uuid:
+gcry_dsa: verify mpi
+keystatus: extcmd
+linux: video boot relocator mmap
+geli: cryptodisk crypto gcry_sha512 pbkdf2 gcry_sha256
+cmdline_cat_test: font functional_test procfs normal video_fb
+part_sun:
+cbtable:
+pbkdf2_test: functional_test pbkdf2 gcry_sha1
+video_bochs: video video_fb
+bufio:
+usbserial_ftdi: serial usb usbserial_common
+legacy_password_test: functional_test legacycfg
+cpuid: extcmd
+bfs: fshelp
+hdparm: extcmd
+gcry_blowfish: crypto
+test:
+nilfs2: fshelp
+gcry_rsa: verify mpi
+cryptodisk: crypto extcmd procfs
+nativedisk:
+minicmd:
+signature_test: functional_test procfs
+ata: scsi
+udf: fshelp
+gzio:
+xnu_uuid: gcry_md5
+uhci: usb
+pata: ata
+mul_test: functional_test
+adler32: crypto
+terminal:
+div:
+ehci: cs5536 usb boot
+crypto:
+part_bsd: part_msdos
+cs5536:
+gcry_sha512: crypto
+password: crypto normal
+fshelp:
+sleep_test: functional_test datetime
+iorw: extcmd
+xnu: macho bitmap_scale random extcmd video bitmap boot relocator mmap
+mmap:
+exfctest: functional_test
+zfsinfo: zfs
+ldm: part_gpt diskfilter part_msdos
+eval: normal
+part_dvh:
+lssal:
+ext2: fshelp
+blocklist:
+net: priority_queue bufio datetime boot
+part_acorn:
+videoinfo: video
+btrfs: lzopio gzio
+lsmmap: mmap
+bitmap:
+ntfs: fshelp
+multiboot: net video boot relocator mmap
+gcry_crc: crypto
+png: bufio bitmap
+jpeg: bufio bitmap
+macbless: disk
+div_test: functional_test div
+regexp: extcmd normal
+parttool: normal
+usbserial_pl2303: serial usb usbserial_common
+cpio: archelp
+gcry_rmd160: crypto
+fat: fshelp
+ufs1_be:
+archelp:
+raid6rec: diskfilter
+http: net
+zfs: gzio
+lsefisystab:
+minix2:
+lsacpi: extcmd acpi
+datehook: datetime normal
+loadenv: disk extcmd
+bitmap_scale: bitmap
+probe: extcmd
+minix3:
+tar: archelp
+loadbios:
+hfs: fshelp
+procfs: archelp
+boot:
+keylayouts:
+progress: normal
+kernel:
+usbtest: usb
+relocator: mmap
+acpi: extcmd mmap
+tga: bufio bitmap
+reboot:
+serial: extcmd terminfo
+zfscrypt: crypto pbkdf2 zfs extcmd gcry_sha1 gcry_rijndael
+efi_uga: video video_fb
+dm_nv: diskfilter
+cmp_test: functional_test
+luks: cryptodisk crypto pbkdf2
+font: bufio video
+raid5rec: diskfilter
+crc64: crypto
+datetime:
+efifwsetup: reboot
+ctz_test: functional_test
+video:
+cbmemc: normal cbtable terminfo
+hfsplus: fshelp
+gcry_cast5: crypto
+extcmd:
+squash4: fshelp lzopio xzio gzio
+part_plan:
+minix_be:
+gcry_whirlpool: crypto
+gcry_tiger: crypto
+fixvideo:
+search: search_fs_uuid search_fs_file extcmd search_label
+lspci: extcmd
+cbtime: cbtable
+video_fb:
+verify: crypto extcmd mpi gcry_sha1
+minix3_be:
+trig:
+msdospart: disk parttool
+priority_queue:
+gcry_twofish: crypto
+part_dfly:
+xnu_uuid_test: functional_test
+diskfilter:
+testload:
+part_apple:
+hexdump: extcmd
+date: datetime normal
+pbkdf2: crypto
+gcry_sha256: crypto
+ls: extcmd normal
+usbserial_common: serial usb
+ntfscomp: ntfs
+lzopio: crypto
+video_cirrus: video video_fb
+hello: extcmd
+scsi:
+cat: extcmd
+ahci: ata boot
+normal: terminal crypto bufio extcmd boot gettext
+linux16: video boot relocator mmap
+ufs1:
+mdraid09: diskfilter
+lvm: diskfilter
+chain: net efinet boot
+cbfs: archelp
+ufs2:
+time:
+setpci: extcmd
+gptsync: disk
+search_label:
+setjmp:
+multiboot2: net video boot relocator mmap acpi
+gcry_rfc2268: crypto
+mdraid1x: diskfilter
+mpi: crypto
+legacycfg: password crypto gcry_md5 normal
+play:
+part_amiga:
+efi_gop: video video_fb
+minix:
+echo: extcmd
+lsefi:
+gcry_serpent: crypto
+gcry_md4: crypto
+gcry_md5: crypto
+part_msdos:
+gcry_camellia: crypto
+at_keyboard: keylayouts boot
+all_video: efi_gop efi_uga video_bochs video_cirrus
Index: boot/grub/ia32-efi/x86_64-efi/modinfo.sh
===================================================================
--- boot/grub/ia32-efi/x86_64-efi/modinfo.sh	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/x86_64-efi/modinfo.sh	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+# User-controllable options
+grub_modinfo_target_cpu=x86_64
+grub_modinfo_platform=efi
+grub_disk_cache_stats=0
+grub_boot_time_stats=0
+grub_have_font_source=1
+
+# Autodetected config
+grub_have_asm_uscore=0
+grub_bss_start_symbol=""
+grub_end_symbol=""
+
+# Build environment
+grub_target_cc='gcc'
+grub_target_cc_version='gcc (SUSE Linux) 4.8.5'
+grub_target_cflags=' -Os -Wall -W -Wshadow -Wpointer-arith -Wundef -Wchar-subscripts -Wcomment -Wdeprecated-declarations -Wdisabled-optimization -Wdiv-by-zero -Wfloat-equal -Wformat-extra-args -Wformat-security -Wformat-y2k -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Wmain -Wmissing-braces -Wmissing-format-attribute -Wmultichar -Wparentheses -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wswitch -Wtrigraphs -Wunknown-pragmas -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value  -Wunused-variable -Wwrite-strings -Wnested-externs -Wstrict-prototypes -g -Wredundant-decls -Wmissing-prototypes -Wmissing-declarations  -Wextra -Wattributes -Wendif-labels -Winit-self -Wint-to-pointer-cast -Winvalid-pch -Wmissing-field-initializers -Wnonnull -Woverflow -Wvla -Wpointer-to-int-cast -Wstrict-aliasing -Wvariadic-macros -Wvolatile-register-var -Wpointer-sign -Wmissing-include-dirs -Wmissing-prototypes -Wmissing-declarations -Wformat=2 -m64 -freg-struct-return -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow -msoft-float -fno-dwarf2-cfi-asm -mno-stack-arg-probe -fno-asynchronous-unwind-tables -fno-unwind-tables -mcmodel=large -mno-red-zone -Qn -fno-stack-protector -Wtrampolines -Werror'
+grub_target_cppflags=' -Wall -W  -DGRUB_MACHINE_EFI=1 -DGRUB_MACHINE=X86_64_EFI -m64 -nostdinc -isystem /usr/lib64/gcc/x86_64-suse-linux/4.8/include -I$(top_srcdir)/include -I$(top_builddir)/include'
+grub_target_ccasflags=' -g  -m64 -msoft-float'
+grub_target_ldflags=' -m64 -Wl,-melf_x86_64 -Wl,--build-id=none'
+grub_cflags=''
+grub_cppflags=' -D_FILE_OFFSET_BITS=64'
+grub_ccasflags=''
+grub_ldflags=''
+grub_target_strip='strip'
+grub_target_nm='nm'
+grub_target_ranlib='ranlib'
+grub_target_objconf=''
+grub_target_obj2elf=''
+grub_target_img_base_ldopt='-Wl,-Ttext'
+grub_target_img_ldflags='@TARGET_IMG_BASE_LDFLAGS@'
+
+# Version
+grub_version="2.02~beta2"
+grub_package="grub"
+grub_package_string="GRUB 2.02~beta2"
+grub_package_version="2.02~beta2"
+grub_package_name="GRUB"
+grub_package_bugreport="bug-grub@gnu.org"
Index: boot/grub/ia32-efi/x86_64-efi/partmap.lst
===================================================================
--- boot/grub/ia32-efi/x86_64-efi/partmap.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/x86_64-efi/partmap.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,11 @@
+part_acorn
+part_amiga
+part_apple
+part_bsd
+part_dfly
+part_dvh
+part_gpt
+part_msdos
+part_plan
+part_sun
+part_sunpc
Index: boot/grub/ia32-efi/x86_64-efi/parttool.lst
===================================================================
--- boot/grub/ia32-efi/x86_64-efi/parttool.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/x86_64-efi/parttool.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+msdos: msdospart
Index: boot/grub/ia32-efi/x86_64-efi/terminal.lst
===================================================================
--- boot/grub/ia32-efi/x86_64-efi/terminal.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/x86_64-efi/terminal.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,9 @@
+iat_keyboard: at_keyboard
+iserial: serial
+iserial_*: serial
+oaudio: morse
+ocbmemc: cbmemc
+ogfxterm: gfxterm
+oserial: serial
+oserial_*: serial
+ospkmodem: spkmodem
Index: boot/grub/ia32-efi/x86_64-efi/video.lst
===================================================================
--- boot/grub/ia32-efi/x86_64-efi/video.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-efi/x86_64-efi/video.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,4 @@
+efi_gop
+efi_uga
+video_bochs
+video_cirrus
Index: boot/grub/ia32-pc/COPYING
===================================================================
--- boot/grub/ia32-pc/COPYING	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-pc/COPYING	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
Index: boot/grub/ia32-pc/README
===================================================================
--- boot/grub/ia32-pc/README	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-pc/README	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,9 @@
+The binary files of GRUB boot loader in this directory have been created
+by compiling GRUB for the 'i386-pc' target and then using the grub-mkrescue
+script to create the El Torito boot image.
+
+For licensing terms of GRUB boot loader see the file COPYING contained
+in this directory. Full version of GRUB, including its source code,
+can be downloaded from GRUB's project page:
+
+http://www.gnu.org/software/grub/
Index: boot/grub/ia32-pc/REVISION
===================================================================
--- boot/grub/ia32-pc/REVISION	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-pc/REVISION	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+bc220962e366b1b46769ed6f9fa5be603ba58ab5
Index: boot/grub/ia32-pc/i386-pc/command.lst
===================================================================
--- boot/grub/ia32-pc/i386-pc/command.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-pc/i386-pc/command.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,198 @@
+*acpi: acpi
+*all_functional_test: functional_test
+*background_image: gfxterm_background
+*cat: cat
+*cpuid: cpuid
+*crc: hashsum
+*cryptomount: cryptodisk
+*drivemap: drivemap
+*echo: echo
+*extract_syslinux_entries_configfile: syslinuxcfg
+*extract_syslinux_entries_source: syslinuxcfg
+*file: file
+*functional_test: functional_test
+*gettext: gettext
+*halt: halt
+*hashsum: hashsum
+*hdparm: hdparm
+*hello: hello
+*help: help
+*hexdump: hexdump
+*inb: iorw
+*inl: iorw
+*inw: iorw
+*keystatus: keystatus
+*kfreebsd: bsd
+*knetbsd: bsd
+*kopenbsd: bsd
+*list_env: loadenv
+*load_env: loadenv
+*loopback: loopback
+*ls: ls
+*lsacpi: lsacpi
+*lspci: lspci
+*md5sum: hashsum
+*menuentry: normal
+*pcidump: pcidump
+*plan9: plan9
+*probe: probe
+*read_byte: memrw
+*read_dword: memrw
+*read_word: memrw
+*regexp: regexp
+*save_env: loadenv
+*search: search
+*sendkey: sendkey
+*serial: serial
+*setpci: setpci
+*sha1sum: hashsum
+*sha256sum: hashsum
+*sha512sum: hashsum
+*sleep: sleep
+*submenu: normal
+*syslinux_configfile: syslinuxcfg
+*syslinux_source: syslinuxcfg
+*terminfo: terminfo
+*test_blockarg: test_blockarg
+*testspeed: testspeed
+*tr: tr
+*trust: verify
+*verify_detached: verify
+*xnu_splash: xnu
+*zfskey: zfscrypt
+.: configfile
+[: test
+authenticate: normal
+background_color: gfxterm_background
+backtrace: backtrace
+badram: mmap
+blocklist: blocklist
+boot: boot
+break: normal
+cat: minicmd
+cbmemc: cbmemc
+chainloader: chain
+clear: normal
+cmosclean: cmostest
+cmosdump: cmosdump
+cmosset: cmostest
+cmostest: cmostest
+cmp: cmp
+configfile: configfile
+continue: normal
+coreboot_boottime: cbtime
+cutmem: mmap
+date: date
+distrust: verify
+dump: minicmd
+efiemu_loadcore: efiemu
+efiemu_prepare: efiemu
+efiemu_unload: efiemu
+eval: eval
+exit: minicmd
+export: normal
+extract_entries_configfile: configfile
+extract_entries_source: configfile
+extract_legacy_entries_configfile: legacycfg
+extract_legacy_entries_source: legacycfg
+false: true
+freedos: freedos
+gdbstub: gdb
+gdbstub_break: gdb
+gdbstub_stop: gdb
+gptsync: gptsync
+help: minicmd
+hexdump_random: random
+initrd16: linux16
+initrd: linux
+keymap: keylayouts
+kfreebsd_loadenv: bsd
+kfreebsd_module: bsd
+kfreebsd_module_elf: bsd
+knetbsd_module: bsd
+knetbsd_module_elf: bsd
+kopenbsd_ramdisk: bsd
+legacy_check_password: legacycfg
+legacy_configfile: legacycfg
+legacy_initrd: legacycfg
+legacy_initrd_nounzip: legacycfg
+legacy_kernel: legacycfg
+legacy_password: legacycfg
+legacy_source: legacycfg
+linux16: linux16
+linux: linux
+list_trusted: verify
+loadfont: font
+lsapm: lsapm
+lscoreboot: cbls
+lsfonts: font
+lsmmap: lsmmap
+lsmod: minicmd
+macppcbless: macbless
+mactelbless: macbless
+module2: multiboot2
+module: multiboot
+multiboot2: multiboot2
+multiboot: multiboot
+nativedisk: nativedisk
+net_add_addr: net
+net_add_dns: net
+net_add_route: net
+net_bootp: net
+net_del_addr: net
+net_del_dns: net
+net_del_route: net
+net_get_dhcp_option: net
+net_ipv6_autoconf: net
+net_ls_addr: net
+net_ls_cards: net
+net_ls_dns: net
+net_ls_routes: net
+net_nslookup: net
+normal: normal
+normal_exit: normal
+ntldr: ntldr
+outb: iorw
+outl: iorw
+outw: iorw
+parttool: parttool
+password: password
+password_pbkdf2: password_pbkdf2
+play: play
+pxechainloader: pxechain
+read: read
+reboot: reboot
+return: normal
+rmmod: minicmd
+search.file: search_fs_file
+search.fs_label: search_label
+search.fs_uuid: search_fs_uuid
+setparams: normal
+shift: normal
+source: configfile
+terminal_input: terminal
+terminal_output: terminal
+test: test
+testload: testload
+time: time
+true: true
+truecrypt: truecrypt
+usb: usbtest
+vbeinfo: videoinfo
+vbetest: videotest
+videoinfo: videoinfo
+videotest: videotest
+write_byte: memrw
+write_dword: memrw
+write_word: memrw
+xnu_devprop_load: xnu
+xnu_kernel64: xnu
+xnu_kernel: xnu
+xnu_kext: xnu
+xnu_kextdir: xnu
+xnu_mkext: xnu
+xnu_ramdisk: xnu
+xnu_resume: xnu
+xnu_uuid: xnu_uuid
+zfs-bootfs: zfsinfo
+zfsinfo: zfsinfo
Index: boot/grub/ia32-pc/i386-pc/crypto.lst
===================================================================
--- boot/grub/ia32-pc/i386-pc/crypto.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-pc/i386-pc/crypto.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,45 @@
+RIJNDAEL: gcry_rijndael
+RIJNDAEL192: gcry_rijndael
+RIJNDAEL256: gcry_rijndael
+AES128: gcry_rijndael
+AES-128: gcry_rijndael
+AES-192: gcry_rijndael
+AES-256: gcry_rijndael
+ADLER32: adler32
+CRC64: crc64
+ARCFOUR: gcry_arcfour
+BLOWFISH: gcry_blowfish
+CAMELLIA128: gcry_camellia
+CAMELLIA192: gcry_camellia
+CAMELLIA256: gcry_camellia
+CAST5: gcry_cast5
+CRC32: gcry_crc
+CRC32RFC1510: gcry_crc
+CRC24RFC2440: gcry_crc
+DES: gcry_des
+3DES: gcry_des
+DSA: gcry_dsa
+IDEA: gcry_idea
+MD4: gcry_md4
+MD5: gcry_md5
+RFC2268_40: gcry_rfc2268
+AES: gcry_rijndael
+AES192: gcry_rijndael
+AES256: gcry_rijndael
+RIPEMD160: gcry_rmd160
+RSA: gcry_rsa
+SEED: gcry_seed
+SERPENT128: gcry_serpent
+SERPENT192: gcry_serpent
+SERPENT256: gcry_serpent
+SHA1: gcry_sha1
+SHA224: gcry_sha256
+SHA256: gcry_sha256
+SHA512: gcry_sha512
+SHA384: gcry_sha512
+TIGER192: gcry_tiger
+TIGER: gcry_tiger
+TIGER2: gcry_tiger
+TWOFISH: gcry_twofish
+TWOFISH128: gcry_twofish
+WHIRLPOOL: gcry_whirlpool
Index: boot/grub/ia32-pc/i386-pc/fs.lst
===================================================================
--- boot/grub/ia32-pc/i386-pc/fs.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-pc/i386-pc/fs.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,36 @@
+affs
+afs
+bfs
+btrfs
+cbfs
+cpio
+cpio_be
+exfat
+ext2
+fat
+hfs
+hfsplus
+iso9660
+jfs
+minix
+minix2
+minix2_be
+minix3
+minix3_be
+minix_be
+newc
+nilfs2
+ntfs
+odc
+procfs
+reiserfs
+romfs
+sfs
+squash4
+tar
+udf
+ufs1
+ufs1_be
+ufs2
+xfs
+zfs
Index: boot/grub/ia32-pc/i386-pc/gdb_grub
===================================================================
--- boot/grub/ia32-pc/i386-pc/gdb_grub	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-pc/i386-pc/gdb_grub	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,85 @@
+###
+### Load debuging information about GNU GRUB 2 modules into GDB
+### automatically. Needs readelf, Perl and gmodule.pl script
+###
+### Has to be launched from the writable and trusted
+### directory containing *.image and *.module
+###
+### $Id: .gdbinit,v 1.1 2006/05/14 11:38:08 lkundrak Exp $
+### Lubomir Kundrak <lkudrak@skosi.org>
+###
+
+# Add section numbers and addresses to .segments.tmp
+define dump_module_sections
+	set $mod = $arg0
+
+	# FIXME: save logging status
+	set logging file .segments.tmp
+	set logging redirect on
+	set logging overwrite off
+	set logging on
+
+	printf "%s", $mod->name
+	set $segment = $mod->segment
+	while ($segment)
+		printf " %i 0x%lx", $segment->section, $segment->addr
+		set $segment = $segment->next
+	end
+	printf "\n"
+
+	set logging off
+	# FIXME: restore logging status
+end
+document dump_module_sections
+	Gather information about module whose mod structure was
+	given for use with match_and_load_symbols
+end
+
+# Generate and execute GDB commands and delete temporary files
+# afterwards
+define match_and_load_symbols
+	shell perl gmodule.pl <.segments.tmp >.loadsym.gdb
+	source .loadsym.gdb
+	shell rm -f .segments.tmp .loadsym.gdb
+end
+document match_and_load_symbols
+	Launch script, that matches section names with information
+	generated by dump_module_sections and load debugging info
+	apropriately
+end
+
+###
+
+define load_module
+	dump_module_sections $arg0
+	match_and_load_symbols
+end
+document load_module
+	Load debugging information for module given as argument.
+end
+
+define load_all_modules
+	set $this = grub_dl_head
+	while ($this != 0)
+		dump_module_sections $this
+		set $this = $this->next
+	end
+	match_and_load_symbols
+end
+document load_all_modules
+	Load debugging information for all loaded modules.
+end
+
+###
+
+set confirm off
+file kernel.exec
+target remote :1234
+
+# inform when module is loaded
+break grub_dl_add
+commands
+	silent
+	load_module mod
+	cont
+end
Index: boot/grub/ia32-pc/i386-pc/gmodule.pl
===================================================================
--- boot/grub/ia32-pc/i386-pc/gmodule.pl	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-pc/i386-pc/gmodule.pl	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,30 @@
+###
+### Generate GDB commands, that load symbols for specified module,
+### with proper section relocations. See .gdbinit
+###
+### $Id: gmodule.pl,v 1.2 2006/05/14 11:38:42 lkundrak Exp lkundrak $
+### Lubomir Kundrak <lkudrak@skosi.org>
+###
+
+use strict;
+
+while (<>) {
+	my ($name, %sections) = split;
+
+	print "add-symbol-file $name.module";
+
+	open (READELF, "readelf -S $name.mod |") or die;
+	while (<READELF>) {
+		/\[\s*(\d+)\]\s+(\.\S+)/ or next;
+
+		if ($2 eq '.text') {
+			print " $sections{$1}";
+			next;
+		}
+
+		print " -s $2 $sections{$1}"
+			if ($sections{$1} ne '0x0' and $sections{$1} ne '');
+	};
+	close (READELF);
+	print "\n";
+}
Index: boot/grub/ia32-pc/i386-pc/moddep.lst
===================================================================
--- boot/grub/ia32-pc/i386-pc/moddep.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-pc/i386-pc/moddep.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,264 @@
+videotest: font video gfxmenu
+odc: archelp
+loopback: extcmd
+macho:
+gcry_des: crypto
+memrw: extcmd
+terminfo: extcmd
+part_gpt:
+romfs: fshelp
+read:
+aout:
+gcry_arcfour: crypto
+vga_text:
+tftp: net priority_queue
+newc: archelp
+minix2_be:
+elf:
+videotest_checksum: font functional_test video_fb
+password_pbkdf2: crypto gcry_sha512 pbkdf2 normal
+gcry_seed: crypto
+pcidump: extcmd pci
+bsd: elf serial crypto gcry_md5 extcmd vbe video boot aout cpuid relocator mmap
+sfs: fshelp
+reiserfs: fshelp
+part_sunpc:
+gfxmenu: video_colors trig bitmap_scale gfxterm font normal video bitmap
+backtrace:
+jfs:
+help: extcmd normal
+configfile: normal
+cbls: cbtable
+gfxterm_menu: font functional_test procfs normal video_fb
+gcry_idea: crypto
+tr: extcmd
+shift_test: functional_test
+ohci: cs5536 usb boot pci
+afs: fshelp
+spkmodem: terminfo
+usb_keyboard: usb keylayouts
+xzio: crypto
+syslinuxcfg: extcmd normal
+search_fs_file:
+vga: video video_fb
+usbms: scsi usb
+test_blockarg: extcmd normal
+true:
+affs: fshelp
+iso9660: fshelp
+exfat: fshelp
+setjmp_test: functional_test setjmp
+gfxterm: font video
+disk:
+xfs: fshelp
+testspeed: extcmd normal
+cpio_be: archelp
+functional_test: btrfs extcmd video video_fb
+pxechain: pxe video boot relocator
+bswap_test: functional_test
+sleep: extcmd normal
+memdisk:
+gcry_rijndael: crypto
+mdraid09_be: diskfilter
+gettext:
+gcry_sha1: crypto
+hfspluscomp: gzio hfsplus
+cmp:
+random: hexdump acpi
+offsetio:
+file: macho elf extcmd offsetio
+usbserial_usbdebug: serial usb usbserial_common
+video_colors:
+morse:
+hashsum: crypto extcmd normal
+usb: pci
+halt: extcmd acpi
+gdb: serial backtrace
+gfxterm_background: video_colors bitmap_scale gfxterm extcmd video bitmap
+search_fs_uuid:
+gcry_dsa: verify mpi
+keystatus: extcmd
+linux: normal vbe video boot relocator mmap
+geli: cryptodisk crypto gcry_sha512 pbkdf2 gcry_sha256
+cmdline_cat_test: font functional_test procfs normal video_fb
+part_sun:
+cbtable:
+plan9: extcmd video boot relocator
+sendkey: extcmd boot
+pbkdf2_test: functional_test pbkdf2 gcry_sha1
+video_bochs: video pci video_fb
+bufio:
+usbserial_ftdi: serial usb usbserial_common
+legacy_password_test: functional_test legacycfg
+cpuid: extcmd
+bfs: fshelp
+hdparm: extcmd
+gcry_blowfish: crypto
+test:
+nilfs2: fshelp
+gcry_rsa: verify mpi
+cryptodisk: crypto extcmd procfs
+nativedisk:
+minicmd:
+signature_test: functional_test procfs
+ata: scsi
+udf: fshelp
+gzio:
+xnu_uuid: gcry_md5
+uhci: usb pci
+pata: ata pci
+mul_test: functional_test
+adler32: crypto
+terminal:
+div:
+ehci: cs5536 usb boot pci
+crypto:
+part_bsd: part_msdos
+cs5536: pci
+biosdisk:
+lsapm:
+gcry_sha512: crypto
+password: crypto normal
+efiemu: gcry_crc crypto cpuid acpi
+fshelp:
+sleep_test: functional_test datetime
+iorw: extcmd
+xnu: macho bitmap_scale random extcmd video bitmap boot efiemu relocator mmap
+mmap: boot
+exfctest: functional_test
+zfsinfo: zfs
+ldm: part_gpt diskfilter part_msdos
+cmostest:
+eval: normal
+part_dvh:
+ext2: fshelp
+blocklist:
+net: priority_queue bufio datetime boot
+drivemap: extcmd boot mmap
+part_acorn:
+videoinfo: video
+btrfs: lzopio gzio
+lsmmap:
+bitmap:
+vbe: video video_fb
+ntfs: fshelp
+multiboot: net vbe video boot relocator mmap lsapm
+gcry_crc: crypto
+png: bufio bitmap
+jpeg: bufio bitmap
+macbless: disk
+div_test: functional_test div
+regexp: extcmd normal
+parttool: normal
+usbserial_pl2303: serial usb usbserial_common
+cpio: archelp
+gcry_rmd160: crypto
+fat: fshelp
+ufs1_be:
+truecrypt: video boot relocator mmap gzio
+archelp:
+raid6rec: diskfilter
+ntldr: chain video boot relocator
+http: net
+zfs: gzio
+minix2:
+mda_text:
+lsacpi: extcmd acpi
+datehook: datetime normal
+loadenv: disk extcmd
+bitmap_scale: bitmap
+probe: extcmd
+minix3:
+tar: archelp
+hfs: fshelp
+procfs: archelp
+boot:
+keylayouts:
+progress: normal
+kernel:
+usbtest: usb
+relocator: mmap
+acpi: extcmd mmap
+tga: bufio bitmap
+reboot: relocator
+serial: extcmd terminfo
+zfscrypt: crypto pbkdf2 zfs extcmd gcry_sha1 gcry_rijndael
+dm_nv: diskfilter
+cmp_test: functional_test
+luks: cryptodisk crypto pbkdf2
+font: bufio video
+raid5rec: diskfilter
+crc64: crypto
+datetime:
+ctz_test: functional_test
+video:
+pci:
+cbmemc: normal cbtable terminfo
+cmosdump:
+hfsplus: fshelp
+gcry_cast5: crypto
+extcmd:
+squash4: fshelp lzopio xzio gzio
+part_plan:
+minix_be:
+gcry_whirlpool: crypto
+pxe: net boot
+gcry_tiger: crypto
+search: search_fs_uuid search_fs_file extcmd search_label
+lspci: extcmd pci
+cbtime: cbtable
+video_fb:
+verify: crypto extcmd mpi gcry_sha1
+minix3_be:
+trig:
+msdospart: disk parttool
+priority_queue:
+gcry_twofish: crypto
+part_dfly:
+xnu_uuid_test: functional_test
+diskfilter:
+testload:
+part_apple:
+hexdump: extcmd
+date: datetime normal
+pbkdf2: crypto
+gcry_sha256: crypto
+ls: extcmd normal
+usbserial_common: serial usb
+ntfscomp: ntfs
+lzopio: crypto
+video_cirrus: video pci video_fb
+hello: extcmd
+scsi:
+cat: extcmd
+ahci: ata boot pci
+normal: terminal crypto bufio extcmd boot gettext
+linux16: video boot relocator mmap
+ufs1:
+mdraid09: diskfilter
+lvm: diskfilter
+cbfs: archelp
+chain: video boot relocator
+ufs2:
+time:
+setpci: extcmd pci
+gptsync: disk
+freedos: chain video boot relocator
+search_label:
+setjmp:
+multiboot2: net vbe video boot relocator mmap lsapm acpi
+gcry_rfc2268: crypto
+mdraid1x: diskfilter
+mpi: crypto
+legacycfg: linux password crypto gcry_md5 normal
+play:
+part_amiga:
+minix:
+echo: extcmd
+gcry_serpent: crypto
+gcry_md4: crypto
+gcry_md5: crypto
+part_msdos:
+gcry_camellia: crypto
+at_keyboard: keylayouts boot
+all_video: vbe vga video_bochs video_cirrus
Index: boot/grub/ia32-pc/i386-pc/modinfo.sh
===================================================================
--- boot/grub/ia32-pc/i386-pc/modinfo.sh	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-pc/i386-pc/modinfo.sh	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+# User-controllable options
+grub_modinfo_target_cpu=i386
+grub_modinfo_platform=pc
+grub_disk_cache_stats=0
+grub_boot_time_stats=0
+grub_have_font_source=1
+
+# Autodetected config
+grub_have_asm_uscore=0
+grub_bss_start_symbol="__bss_start"
+grub_end_symbol="end"
+
+# Build environment
+grub_target_cc='gcc'
+grub_target_cc_version='gcc (SUSE Linux) 4.8.5'
+grub_target_cflags=' -Os -Wall -W -Wshadow -Wpointer-arith -Wundef -Wchar-subscripts -Wcomment -Wdeprecated-declarations -Wdisabled-optimization -Wdiv-by-zero -Wfloat-equal -Wformat-extra-args -Wformat-security -Wformat-y2k -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Wmain -Wmissing-braces -Wmissing-format-attribute -Wmultichar -Wparentheses -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wswitch -Wtrigraphs -Wunknown-pragmas -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value  -Wunused-variable -Wwrite-strings -Wnested-externs -Wstrict-prototypes -g -Wredundant-decls -Wmissing-prototypes -Wmissing-declarations  -Wextra -Wattributes -Wendif-labels -Winit-self -Wint-to-pointer-cast -Winvalid-pch -Wmissing-field-initializers -Wnonnull -Woverflow -Wvla -Wpointer-to-int-cast -Wstrict-aliasing -Wvariadic-macros -Wvolatile-register-var -Wpointer-sign -Wmissing-include-dirs -Wmissing-prototypes -Wmissing-declarations -Wformat=2 -march=i386 -m32 -mrtd -mregparm=3 -falign-jumps=1 -falign-loops=1 -falign-functions=1 -freg-struct-return -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow -msoft-float -fno-dwarf2-cfi-asm -mno-stack-arg-probe -fno-asynchronous-unwind-tables -fno-unwind-tables -Qn -fno-stack-protector -Wtrampolines -Werror'
+grub_target_cppflags=' -Wall -W  -DGRUB_MACHINE_PCBIOS=1 -DGRUB_MACHINE=I386_PC -m32 -nostdinc -isystem /usr/lib64/gcc/x86_64-suse-linux/4.8/include -I$(top_srcdir)/include -I$(top_builddir)/include'
+grub_target_ccasflags=' -g  -m32 -msoft-float'
+grub_target_ldflags=' -m32 -Wl,-melf_i386 -Wl,--build-id=none'
+grub_cflags=''
+grub_cppflags=' -D_FILE_OFFSET_BITS=64'
+grub_ccasflags=''
+grub_ldflags=''
+grub_target_strip='strip'
+grub_target_nm='nm'
+grub_target_ranlib='ranlib'
+grub_target_objconf=''
+grub_target_obj2elf=''
+grub_target_img_base_ldopt='-Wl,-Ttext'
+grub_target_img_ldflags='@TARGET_IMG_BASE_LDFLAGS@'
+
+# Version
+grub_version="2.02~beta2"
+grub_package="grub"
+grub_package_string="GRUB 2.02~beta2"
+grub_package_version="2.02~beta2"
+grub_package_name="GRUB"
+grub_package_bugreport="bug-grub@gnu.org"
Index: boot/grub/ia32-pc/i386-pc/partmap.lst
===================================================================
--- boot/grub/ia32-pc/i386-pc/partmap.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-pc/i386-pc/partmap.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,11 @@
+part_acorn
+part_amiga
+part_apple
+part_bsd
+part_dfly
+part_dvh
+part_gpt
+part_msdos
+part_plan
+part_sun
+part_sunpc
Index: boot/grub/ia32-pc/i386-pc/parttool.lst
===================================================================
--- boot/grub/ia32-pc/i386-pc/parttool.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-pc/i386-pc/parttool.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+msdos: msdospart
Index: boot/grub/ia32-pc/i386-pc/terminal.lst
===================================================================
--- boot/grub/ia32-pc/i386-pc/terminal.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-pc/i386-pc/terminal.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,11 @@
+iat_keyboard: at_keyboard
+iserial: serial
+iserial_*: serial
+oaudio: morse
+ocbmemc: cbmemc
+ogfxterm: gfxterm
+omda_text: mda_text
+oserial: serial
+oserial_*: serial
+ospkmodem: spkmodem
+ovga_text: vga_text
Index: boot/grub/ia32-pc/i386-pc/video.lst
===================================================================
--- boot/grub/ia32-pc/i386-pc/video.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ boot/grub/ia32-pc/i386-pc/video.lst	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,4 @@
+vbe
+vga
+video_bochs
+video_cirrus
Index: contrib/qemu/build-from-scratch.sh
===================================================================
--- contrib/qemu/build-from-scratch.sh	(revision c878693123930f0906703462cf2807430679517e)
+++ contrib/qemu/build-from-scratch.sh	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -29,5 +29,5 @@
 #
 
-VERSION=3.0.0
+VERSION=4.0.0
 BASENAME=qemu-${VERSION}
 BASENAME_MASTER=qemu-master
@@ -106,5 +106,5 @@
 echo "==== Configuring QEMU ===="
 
-./configure --target-list=i386-softmmu,x86_64-softmmu,arm-softmmu,ppc-softmmu,sparc64-softmmu,mips-softmmu,mipsel-softmmu --audio-drv-list=pa
+./configure --target-list=i386-softmmu,x86_64-softmmu,arm-softmmu,aarch64-softmmu,ppc-softmmu,sparc64-softmmu,mips-softmmu,mipsel-softmmu --audio-drv-list=pa
 
 echo "==== Building QEMU ===="
Index: defaults/amd64/Makefile.config
===================================================================
--- defaults/amd64/Makefile.config	(revision c878693123930f0906703462cf2807430679517e)
+++ defaults/amd64/Makefile.config	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -65,4 +65,16 @@
 CONFIG_BFB_BPP = 16
 
+# Dynamic linking support
+CONFIG_RTLD = y
+
+# Build shared libraries
+CONFIG_BUILD_SHARED_LIBS = y
+
+# Link against shared libraries
+CONFIG_USE_SHARED_LIBS = y
+
+# Include userspace unit tests (PCUT)
+CONFIG_PCUT_TESTS = y
+
 # Include development files (headers, libraries)
 CONFIG_DEVEL_FILES = y
Index: defaults/arm32/Makefile.config
===================================================================
--- defaults/arm32/Makefile.config	(revision c878693123930f0906703462cf2807430679517e)
+++ defaults/arm32/Makefile.config	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,4 +38,13 @@
 CONFIG_HID_OUT = generic
 
+# Dynamic linking support
+CONFIG_RTLD = y
+
+# Build shared libraries
+CONFIG_BUILD_SHARED_LIBS = y
+
+# Link against shared libraries
+CONFIG_USE_SHARED_LIBS = y
+
 # Optimization level
 OPTIMIZATION = 3
Index: defaults/arm32/beagleboardxm/Makefile.config
===================================================================
--- defaults/arm32/beagleboardxm/Makefile.config	(revision c878693123930f0906703462cf2807430679517e)
+++ defaults/arm32/beagleboardxm/Makefile.config	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -10,2 +10,5 @@
 CONFIG_BFB_MODE = 1024x768
 CONFIG_BFB_BPP = 24
+
+# Barebone build with essential binaries only
+CONFIG_BAREBONE = y
Index: defaults/arm32/beaglebone/Makefile.config
===================================================================
--- defaults/arm32/beaglebone/Makefile.config	(revision c878693123930f0906703462cf2807430679517e)
+++ defaults/arm32/beaglebone/Makefile.config	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -7,2 +7,5 @@
 #framebuffer
 CONFIG_FB = n
+
+# Barebone build with essential binaries only
+CONFIG_BAREBONE = y
Index: defaults/arm64/Makefile.config
===================================================================
--- defaults/arm64/Makefile.config	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ defaults/arm64/Makefile.config	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,50 @@
+# Platform
+PLATFORM = arm64
+
+# Ramdisk format
+RDFMT = ext4fs
+
+# Compiler
+COMPILER = gcc_cross
+
+# In case compiler is clang, whether or not to use its integrated assembler.
+INTEGRATED_AS = default
+
+# Debug build
+CONFIG_DEBUG = y
+
+# Deadlock detection support for spinlocks
+CONFIG_DEBUG_SPINLOCK = y
+
+# Support for SMP
+CONFIG_SMP = y
+
+# Lazy FPU context switching
+CONFIG_FPU_LAZY = 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
+
+# Optimization level
+OPTIMIZATION = 3
Index: defaults/arm64/output
===================================================================
--- defaults/arm64/output	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ defaults/arm64/output	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+image.iso
Index: defaults/arm64/virt/Makefile.config
===================================================================
--- defaults/arm64/virt/Makefile.config	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ defaults/arm64/virt/Makefile.config	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,2 @@
+# Machine type
+MACHINE = virt
Index: defaults/ia32/Makefile.config
===================================================================
--- defaults/ia32/Makefile.config	(revision c878693123930f0906703462cf2807430679517e)
+++ defaults/ia32/Makefile.config	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -77,4 +77,7 @@
 CONFIG_USE_SHARED_LIBS = y
 
+# Include userspace unit tests (PCUT)
+CONFIG_PCUT_TESTS = y
+
 # Include development files (headers, libraries)
 CONFIG_DEVEL_FILES = y
Index: defaults/ppc32/Makefile.config
===================================================================
--- defaults/ppc32/Makefile.config	(revision c878693123930f0906703462cf2807430679517e)
+++ defaults/ppc32/Makefile.config	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -44,4 +44,13 @@
 CONFIG_FB = y
 
+# Dynamic linking support
+CONFIG_RTLD = y
+
+# Build shared libraries
+CONFIG_BUILD_SHARED_LIBS = y
+
+# Link against shared libraries
+CONFIG_USE_SHARED_LIBS = y
+
 # OHCI root hub power switch, ganged is enough
 OHCI_POWER_SWITCH = ganged
Index: defaults/sparc64/niagara/Makefile.config
===================================================================
--- defaults/sparc64/niagara/Makefile.config	(revision c878693123930f0906703462cf2807430679517e)
+++ defaults/sparc64/niagara/Makefile.config	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -14,4 +14,13 @@
 CONFIG_FB = n
 
+# Dynamic linking support
+CONFIG_RTLD = y
+
+# Build shared libraries
+CONFIG_BUILD_SHARED_LIBS = y
+
+# Link against shared libraries
+CONFIG_USE_SHARED_LIBS = y
+
 # Barebone build with essential binaries only
 CONFIG_BAREBONE = y
Index: defaults/sparc64/ultra/Makefile.config
===================================================================
--- defaults/sparc64/ultra/Makefile.config	(revision c878693123930f0906703462cf2807430679517e)
+++ defaults/sparc64/ultra/Makefile.config	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -8,4 +8,13 @@
 QUADFLOAT = hard
 
+# Dynamic linking support
+CONFIG_RTLD = y
+
+# Build shared libraries
+CONFIG_BUILD_SHARED_LIBS = y
+
+# Link against shared libraries
+CONFIG_USE_SHARED_LIBS = y
+
 # Barebone build with essential binaries only
 CONFIG_BAREBONE = y
Index: doxygen/doxygen.cfg.diff
===================================================================
--- doxygen/doxygen.cfg.diff	(revision c878693123930f0906703462cf2807430679517e)
+++ doxygen/doxygen.cfg.diff	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -24,5 +24,5 @@
  
 -ENABLED_SECTIONS       =
-+ENABLED_SECTIONS       = abs32le amd64 arm32 ia32 ia64 mips32 ppc32 riscv64 sparc64
++ENABLED_SECTIONS       = abs32le amd64 arm32 arm64 ia32 ia64 mips32 ppc32 riscv64 sparc64
  
  # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
@@ -33,5 +33,5 @@
  
 -INPUT                  =
-+INPUT                  = ..
++INPUT                  = ../README.md ../abi ../boot ../kernel ../uspace
  
  # This tag can be used to specify the character encoding of the source files
Index: kernel/Makefile
===================================================================
--- kernel/Makefile	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -87,5 +87,5 @@
 INCLUDES_FLAGS = $(addprefix -I,$(INCLUDES))
 
-DEFS = -DKERNEL -DRELEASE=$(RELEASE) "-DCOPYRIGHT=$(COPYRIGHT)" "-DNAME=$(NAME)" -D__$(BITS)_BITS__ -D__$(ENDIANESS)__
+DEFS = -D_HELENOS_SOURCE -DKERNEL -DRELEASE=$(RELEASE) "-DCOPYRIGHT=$(COPYRIGHT)" "-DNAME=$(NAME)" -D__$(BITS)_BITS__ -D__$(ENDIANESS)__
 
 COMMON_CFLAGS = $(INCLUDES_FLAGS) -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
@@ -162,5 +162,4 @@
 GENERIC_SOURCES = \
 	generic/src/adt/bitmap.c \
-	generic/src/adt/btree.c \
 	generic/src/adt/hash_table.c \
 	generic/src/adt/list.c \
@@ -279,5 +278,4 @@
 		test/test.c \
 		test/atomic/atomic1.c \
-		test/btree/btree1.c \
 		test/fault/fault1.c \
 		test/mm/falloc1.c \
@@ -314,5 +312,4 @@
 ifeq ($(CONFIG_TRACE),y)
 	INSTRUMENTED_SOURCES = \
-		generic/src/adt/btree.c \
 		generic/src/cpu/cpu.c \
 		generic/src/ddi/ddi.c \
Index: kernel/arch/abs32le/include/arch/asm.h
===================================================================
--- kernel/arch/abs32le/include/arch/asm.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/abs32le/include/arch/asm.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -40,9 +40,9 @@
 #include <trace.h>
 
-NO_TRACE static inline void asm_delay_loop(uint32_t usec)
-{
-}
-
-NO_TRACE static inline __attribute__((noreturn)) void cpu_halt(void)
+_NO_TRACE static inline void asm_delay_loop(uint32_t usec)
+{
+}
+
+_NO_TRACE static inline __attribute__((noreturn)) void cpu_halt(void)
 {
 	/*
@@ -57,5 +57,5 @@
 }
 
-NO_TRACE static inline void cpu_sleep(void)
+_NO_TRACE static inline void cpu_sleep(void)
 {
 	/*
@@ -67,5 +67,5 @@
 }
 
-NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t val)
+_NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t val)
 {
 }
@@ -79,5 +79,5 @@
  *
  */
-NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t val)
+_NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t val)
 {
 }
@@ -91,5 +91,5 @@
  *
  */
-NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t val)
+_NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t val)
 {
 }
@@ -103,5 +103,5 @@
  *
  */
-NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
+_NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
 {
 	return 0;
@@ -116,5 +116,5 @@
  *
  */
-NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port)
+_NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port)
 {
 	return 0;
@@ -129,10 +129,10 @@
  *
  */
-NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
-{
-	return 0;
-}
-
-NO_TRACE static inline ipl_t interrupts_enable(void)
+_NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
+{
+	return 0;
+}
+
+_NO_TRACE static inline ipl_t interrupts_enable(void)
 {
 	/*
@@ -146,5 +146,5 @@
 }
 
-NO_TRACE static inline ipl_t interrupts_disable(void)
+_NO_TRACE static inline ipl_t interrupts_disable(void)
 {
 	/*
@@ -160,5 +160,5 @@
 }
 
-NO_TRACE static inline void interrupts_restore(ipl_t ipl)
+_NO_TRACE static inline void interrupts_restore(ipl_t ipl)
 {
 	/*
@@ -168,5 +168,5 @@
 }
 
-NO_TRACE static inline ipl_t interrupts_read(void)
+_NO_TRACE static inline ipl_t interrupts_read(void)
 {
 	/*
@@ -178,5 +178,5 @@
 }
 
-NO_TRACE static inline bool interrupts_disabled(void)
+_NO_TRACE static inline bool interrupts_disabled(void)
 {
 	/*
@@ -188,5 +188,5 @@
 }
 
-NO_TRACE static inline uintptr_t get_stack_base(void)
+_NO_TRACE static inline uintptr_t get_stack_base(void)
 {
 	/*
Index: kernel/arch/abs32le/include/arch/cycle.h
===================================================================
--- kernel/arch/abs32le/include/arch/cycle.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/abs32le/include/arch/cycle.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,5 +38,5 @@
 #include <trace.h>
 
-NO_TRACE static inline uint64_t get_cycle(void)
+_NO_TRACE static inline uint64_t get_cycle(void)
 {
 	return 0;
Index: kernel/arch/abs32le/include/arch/istate.h
===================================================================
--- kernel/arch/abs32le/include/arch/istate.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/abs32le/include/arch/istate.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -62,5 +62,5 @@
 } istate_t;
 
-NO_TRACE static inline int istate_from_uspace(istate_t *istate)
+_NO_TRACE static inline int istate_from_uspace(istate_t *istate)
     REQUIRES_EXTENT_MUTABLE(istate)
 {
@@ -73,5 +73,5 @@
 }
 
-NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
+_NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
     uintptr_t retaddr)
     WRITES(&istate->ip)
@@ -82,5 +82,5 @@
 }
 
-NO_TRACE static inline uintptr_t istate_get_pc(istate_t *istate)
+_NO_TRACE static inline uintptr_t istate_get_pc(istate_t *istate)
     REQUIRES_EXTENT_MUTABLE(istate)
 {
@@ -90,5 +90,5 @@
 }
 
-NO_TRACE static inline uintptr_t istate_get_fp(istate_t *istate)
+_NO_TRACE static inline uintptr_t istate_get_fp(istate_t *istate)
     REQUIRES_EXTENT_MUTABLE(istate)
 {
Index: kernel/arch/abs32le/include/arch/mm/as.h
===================================================================
--- kernel/arch/abs32le/include/arch/mm/as.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/abs32le/include/arch/mm/as.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,4 +37,5 @@
 
 #define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH  0
+#define KERNEL_SEPARATE_PTL0_ARCH           0
 
 #define KERNEL_ADDRESS_SPACE_START_ARCH  UINT32_C(0x80000000)
Index: kernel/arch/abs32le/include/arch/mm/page.h
===================================================================
--- kernel/arch/abs32le/include/arch/mm/page.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/abs32le/include/arch/mm/page.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -147,5 +147,5 @@
 } __attribute__((packed)) pte_t;
 
-NO_TRACE static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
+_NO_TRACE static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
     REQUIRES_ARRAY_MUTABLE(pt, PTL0_ENTRIES_ARCH)
 {
@@ -161,5 +161,5 @@
 }
 
-NO_TRACE static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
+_NO_TRACE static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
     WRITES(ARRAY_RANGE(pt, PTL0_ENTRIES_ARCH))
     REQUIRES_ARRAY_MUTABLE(pt, PTL0_ENTRIES_ARCH)
@@ -180,5 +180,5 @@
 }
 
-NO_TRACE static inline void set_pt_present(pte_t *pt, size_t i)
+_NO_TRACE static inline void set_pt_present(pte_t *pt, size_t i)
     WRITES(ARRAY_RANGE(pt, PTL0_ENTRIES_ARCH))
     REQUIRES_ARRAY_MUTABLE(pt, PTL0_ENTRIES_ARCH)
Index: kernel/arch/amd64/Makefile.inc
===================================================================
--- kernel/arch/amd64/Makefile.inc	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/amd64/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -60,5 +60,4 @@
 	arch/$(KARCH)/src/ddi/ddi.c \
 	arch/$(KARCH)/src/drivers/i8254.c \
-	arch/$(KARCH)/src/drivers/i8259.c \
 	arch/$(KARCH)/src/delay.S \
 	arch/$(KARCH)/src/amd64.c \
Index: kernel/arch/amd64/include/arch/asm.h
===================================================================
--- kernel/arch/amd64/include/arch/asm.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/amd64/include/arch/asm.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -50,5 +50,5 @@
  *
  */
-NO_TRACE static inline uintptr_t get_stack_base(void)
+_NO_TRACE static inline uintptr_t get_stack_base(void)
 {
 	uintptr_t v;
@@ -63,5 +63,5 @@
 }
 
-NO_TRACE static inline void cpu_sleep(void)
+_NO_TRACE static inline void cpu_sleep(void)
 {
 	asm volatile (
@@ -70,5 +70,5 @@
 }
 
-NO_TRACE static inline void __attribute__((noreturn)) cpu_halt(void)
+_NO_TRACE static inline void __attribute__((noreturn)) cpu_halt(void)
 {
 	while (true) {
@@ -87,5 +87,5 @@
  *
  */
-NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
+_NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
 {
 	if (port < (ioport8_t *) IO_SPACE_BOUNDARY) {
@@ -111,5 +111,5 @@
  *
  */
-NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port)
+_NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port)
 {
 	if (port < (ioport16_t *) IO_SPACE_BOUNDARY) {
@@ -135,5 +135,5 @@
  *
  */
-NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
+_NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
 {
 	if (port < (ioport32_t *) IO_SPACE_BOUNDARY) {
@@ -159,5 +159,5 @@
  *
  */
-NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t val)
+_NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t val)
 {
 	if (port < (ioport8_t *) IO_SPACE_BOUNDARY) {
@@ -178,5 +178,5 @@
  *
  */
-NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t val)
+_NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t val)
 {
 	if (port < (ioport16_t *) IO_SPACE_BOUNDARY) {
@@ -197,5 +197,5 @@
  *
  */
-NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t val)
+_NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t val)
 {
 	if (port < (ioport32_t *) IO_SPACE_BOUNDARY) {
@@ -208,5 +208,5 @@
 }
 
-NO_TRACE static inline uint64_t read_rflags(void)
+_NO_TRACE static inline uint64_t read_rflags(void)
 {
 	uint64_t rflags;
@@ -221,5 +221,5 @@
 }
 
-NO_TRACE static inline void write_rflags(uint64_t rflags)
+_NO_TRACE static inline void write_rflags(uint64_t rflags)
 {
 	asm volatile (
@@ -237,5 +237,5 @@
  *
  */
-NO_TRACE static inline ipl_t interrupts_read(void)
+_NO_TRACE static inline ipl_t interrupts_read(void)
 {
 	return (ipl_t) read_rflags();
@@ -249,5 +249,5 @@
  *
  */
-NO_TRACE static inline ipl_t interrupts_enable(void)
+_NO_TRACE static inline ipl_t interrupts_enable(void)
 {
 	ipl_t ipl = interrupts_read();
@@ -265,5 +265,5 @@
  *
  */
-NO_TRACE static inline ipl_t interrupts_disable(void)
+_NO_TRACE static inline ipl_t interrupts_disable(void)
 {
 	ipl_t ipl = interrupts_read();
@@ -281,5 +281,5 @@
  *
  */
-NO_TRACE static inline void interrupts_restore(ipl_t ipl)
+_NO_TRACE static inline void interrupts_restore(ipl_t ipl)
 {
 	write_rflags((uint64_t) ipl);
@@ -291,5 +291,5 @@
  *
  */
-NO_TRACE static inline bool interrupts_disabled(void)
+_NO_TRACE static inline bool interrupts_disabled(void)
 {
 	return ((read_rflags() & RFLAGS_IF) == 0);
@@ -297,5 +297,5 @@
 
 /** Write to MSR */
-NO_TRACE static inline void write_msr(uint32_t msr, uint64_t value)
+_NO_TRACE static inline void write_msr(uint32_t msr, uint64_t value)
 {
 	asm volatile (
@@ -307,5 +307,5 @@
 }
 
-NO_TRACE static inline sysarg_t read_msr(uint32_t msr)
+_NO_TRACE static inline sysarg_t read_msr(uint32_t msr)
 {
 	uint32_t ax, dx;
@@ -325,5 +325,5 @@
  *
  */
-NO_TRACE static inline void invlpg(uintptr_t addr)
+_NO_TRACE static inline void invlpg(uintptr_t addr)
 {
 	asm volatile (
@@ -338,5 +338,5 @@
  *
  */
-NO_TRACE static inline void gdtr_load(ptr_16_64_t *gdtr_reg)
+_NO_TRACE static inline void gdtr_load(ptr_16_64_t *gdtr_reg)
 {
 	asm volatile (
@@ -351,5 +351,5 @@
  *
  */
-NO_TRACE static inline void gdtr_store(ptr_16_64_t *gdtr_reg)
+_NO_TRACE static inline void gdtr_store(ptr_16_64_t *gdtr_reg)
 {
 	asm volatile (
@@ -364,5 +364,5 @@
  *
  */
-NO_TRACE static inline void idtr_load(ptr_16_64_t *idtr_reg)
+_NO_TRACE static inline void idtr_load(ptr_16_64_t *idtr_reg)
 {
 	asm volatile (
@@ -376,5 +376,5 @@
  *
  */
-NO_TRACE static inline void tr_load(uint16_t sel)
+_NO_TRACE static inline void tr_load(uint16_t sel)
 {
 	asm volatile (
@@ -384,5 +384,5 @@
 }
 
-#define GEN_READ_REG(reg) NO_TRACE static inline sysarg_t read_ ##reg (void) \
+#define GEN_READ_REG(reg) _NO_TRACE static inline sysarg_t read_ ##reg (void) \
 	{ \
 		sysarg_t res; \
@@ -394,5 +394,5 @@
 	}
 
-#define GEN_WRITE_REG(reg) NO_TRACE static inline void write_ ##reg (sysarg_t regn) \
+#define GEN_WRITE_REG(reg) _NO_TRACE static inline void write_ ##reg (sysarg_t regn) \
 	{ \
 		asm volatile ( \
Index: kernel/arch/amd64/include/arch/cycle.h
===================================================================
--- kernel/arch/amd64/include/arch/cycle.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/amd64/include/arch/cycle.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,5 +38,5 @@
 #include <trace.h>
 
-NO_TRACE static inline uint64_t get_cycle(void)
+_NO_TRACE static inline uint64_t get_cycle(void)
 {
 	uint32_t lower;
Index: kernel/arch/amd64/include/arch/interrupt.h
===================================================================
--- kernel/arch/amd64/include/arch/interrupt.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/amd64/include/arch/interrupt.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -61,6 +61,7 @@
 /* NS16550 at COM1 */
 #define IRQ_NS16550   4
-#define IRQ_PIC_SPUR  7
+#define IRQ_PIC0_SPUR 7
 #define IRQ_MOUSE     12
+#define IRQ_PIC1_SPUR 15
 
 /* This one must have four least significant bits set to ones */
@@ -77,5 +78,6 @@
 #define VECTOR_PF                 (IVT_EXCBASE + EXC_PF)
 #define VECTOR_CLK                (IVT_IRQBASE + IRQ_CLK)
-#define VECTOR_PIC_SPUR           (IVT_IRQBASE + IRQ_PIC_SPUR)
+#define VECTOR_PIC0_SPUR          (IVT_IRQBASE + IRQ_PIC0_SPUR)
+#define VECTOR_PIC1_SPUR          (IVT_IRQBASE + IRQ_PIC1_SPUR)
 #define VECTOR_SYSCALL            IVT_FREEBASE
 #define VECTOR_TLB_SHOOTDOWN_IPI  (IVT_FREEBASE + 1)
@@ -84,5 +86,5 @@
 extern void (*disable_irqs_function)(uint16_t);
 extern void (*enable_irqs_function)(uint16_t);
-extern void (*eoi_function)(void);
+extern void (*eoi_function)(unsigned int);
 extern const char *irqs_info;
 
Index: kernel/arch/amd64/include/arch/istate.h
===================================================================
--- kernel/arch/amd64/include/arch/istate.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/amd64/include/arch/istate.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -47,10 +47,10 @@
 
 /** Return true if exception happened while in userspace */
-NO_TRACE static inline int istate_from_uspace(istate_t *istate)
+_NO_TRACE static inline int istate_from_uspace(istate_t *istate)
 {
 	return (istate->cs & RPL_USER) == RPL_USER;
 }
 
-NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
+_NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
     uintptr_t retaddr)
 {
@@ -58,10 +58,10 @@
 }
 
-NO_TRACE static inline uintptr_t istate_get_pc(istate_t *istate)
+_NO_TRACE static inline uintptr_t istate_get_pc(istate_t *istate)
 {
 	return istate->rip;
 }
 
-NO_TRACE static inline uintptr_t istate_get_fp(istate_t *istate)
+_NO_TRACE static inline uintptr_t istate_get_fp(istate_t *istate)
 {
 	return istate->rbp;
Index: kernel/arch/amd64/include/arch/mm/as.h
===================================================================
--- kernel/arch/amd64/include/arch/mm/as.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/amd64/include/arch/mm/as.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -40,4 +40,5 @@
 
 #define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH  0
+#define KERNEL_SEPARATE_PTL0_ARCH           0
 
 #define KERNEL_ADDRESS_SPACE_START_ARCH  UINT64_C(0xffff800000000000)
Index: kernel/arch/amd64/include/arch/mm/page.h
===================================================================
--- kernel/arch/amd64/include/arch/mm/page.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/amd64/include/arch/mm/page.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -207,5 +207,5 @@
 } __attribute__((packed)) pte_t;
 
-NO_TRACE static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
+_NO_TRACE static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
 {
 	pte_t *p = &pt[i];
@@ -220,5 +220,5 @@
 }
 
-NO_TRACE static inline void set_pt_addr(pte_t *pt, size_t i, uintptr_t a)
+_NO_TRACE static inline void set_pt_addr(pte_t *pt, size_t i, uintptr_t a)
 {
 	pte_t *p = &pt[i];
@@ -228,5 +228,5 @@
 }
 
-NO_TRACE static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
+_NO_TRACE static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
 {
 	pte_t *p = &pt[i];
@@ -245,5 +245,5 @@
 }
 
-NO_TRACE static inline void set_pt_present(pte_t *pt, size_t i)
+_NO_TRACE static inline void set_pt_present(pte_t *pt, size_t i)
 {
 	pte_t *p = &pt[i];
Index: kernel/arch/amd64/src/amd64.c
===================================================================
--- kernel/arch/amd64/src/amd64.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/amd64/src/amd64.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -45,9 +45,9 @@
 #include <arch/boot/boot.h>
 #include <arch/drivers/i8254.h>
-#include <arch/drivers/i8259.h>
 #include <arch/syscall.h>
 #include <genarch/acpi/acpi.h>
 #include <genarch/drivers/ega/ega.h>
 #include <genarch/drivers/i8042/i8042.h>
+#include <genarch/drivers/i8259/i8259.h>
 #include <genarch/drivers/ns16550/ns16550.h>
 #include <genarch/drivers/legacy/ia32/io.h>
@@ -120,5 +120,15 @@
 
 		/* PIC */
-		i8259_init();
+		i8259_init((i8259_t *) I8259_PIC0_BASE,
+		    (i8259_t *) I8259_PIC1_BASE, IVT_IRQBASE);
+
+		/*
+		 * Set the enable/disable IRQs handlers.
+		 * Set the End-of-Interrupt handler.
+		 */
+		enable_irqs_function = pic_enable_irqs;
+		disable_irqs_function = pic_disable_irqs;
+		eoi_function = pic_eoi;
+		irqs_info = "i8259";
 	}
 }
Index: kernel/arch/amd64/src/asm.S
===================================================================
--- kernel/arch/amd64/src/asm.S	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/amd64/src/asm.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -398,8 +398,5 @@
 	.asciz "Invalid instruction pointer."
 
-/** Print Unicode character to EGA display.
- *
- * If CONFIG_EGA is undefined or CONFIG_FB is defined
- * then this function does nothing.
+/** Print Unicode character to an early display device.
  *
  * Since the EGA can only display Extended ASCII (usually
@@ -413,4 +410,11 @@
  */
 FUNCTION_BEGIN(early_putwchar)
+
+#if (defined(CONFIG_L4RE_UVMM_EARLY_PRINT))
+	xorl %eax, %eax  /* RAX==0: uvmm's print hypercall */
+	mov %rdi, %rcx   /* RCX:    printed character */
+	vmcall
+#endif
+
 #if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB)))
 
Index: kernel/arch/amd64/src/interrupt.c
===================================================================
--- kernel/arch/amd64/src/interrupt.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/amd64/src/interrupt.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,5 +37,5 @@
 #include <log.h>
 #include <panic.h>
-#include <arch/drivers/i8259.h>
+#include <genarch/drivers/i8259/i8259.h>
 #include <halt.h>
 #include <cpu.h>
@@ -60,5 +60,5 @@
 void (*disable_irqs_function)(uint16_t irqmask) = NULL;
 void (*enable_irqs_function)(uint16_t irqmask) = NULL;
-void (*eoi_function)(void) = NULL;
+void (*eoi_function)(unsigned int) = NULL;
 const char *irqs_info = NULL;
 
@@ -91,8 +91,8 @@
 }
 
-static void trap_virtual_eoi(void)
+static void trap_virtual_eoi(unsigned int irq)
 {
 	if (eoi_function)
-		eoi_function();
+		eoi_function(irq);
 	else
 		panic("No eoi_function.");
@@ -157,5 +157,5 @@
 static void tlb_shootdown_ipi(unsigned int n, istate_t *istate)
 {
-	trap_virtual_eoi();
+	trap_virtual_eoi(0);
 	tlb_shootdown_ipi_recv();
 }
@@ -172,5 +172,5 @@
 	bool ack = false;
 	assert(inum < IRQ_COUNT);
-	assert((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1));
+	assert(inum != IRQ_PIC1);
 
 	irq_t *irq = irq_dispatch_and_lock(inum);
@@ -182,5 +182,5 @@
 		if (irq->preack) {
 			/* Send EOI before processing the interrupt */
-			trap_virtual_eoi();
+			trap_virtual_eoi(inum);
 			ack = true;
 		}
@@ -188,15 +188,27 @@
 		irq_spinlock_unlock(&irq->lock, false);
 	} else {
-		/*
-		 * Spurious interrupt.
-		 */
 #ifdef CONFIG_DEBUG
-		log(LF_ARCH, LVL_DEBUG, "cpu%u: spurious interrupt (inum=%u)",
-		    CPU->id, inum);
+		log(LF_ARCH, LVL_DEBUG, "cpu%u: unhandled IRQ %u", CPU->id,
+		    inum);
 #endif
 	}
 
 	if (!ack)
-		trap_virtual_eoi();
+		trap_virtual_eoi(inum);
+}
+
+static void pic_spurious(unsigned int n, istate_t *istate)
+{
+	unsigned int inum = n - IVT_IRQBASE;
+	if (!pic_is_spurious(inum)) {
+		/* This is actually not a spurious IRQ, so proceed as usual. */
+		irq_interrupt(n, istate);
+		return;
+	}
+	pic_handle_spurious(n);
+#ifdef CONFIG_DEBUG
+	log(LF_ARCH, LVL_DEBUG, "cpu%u: PIC spurious interrupt %u", CPU->id,
+	    inum);
+#endif
 }
 
@@ -209,5 +221,6 @@
 
 	for (i = 0; i < IRQ_COUNT; i++) {
-		if ((i != IRQ_PIC_SPUR) && (i != IRQ_PIC1))
+		if ((i != IRQ_PIC0_SPUR) && (i != IRQ_PIC1_SPUR) &&
+		    (i != IRQ_PIC1))
 			exc_register(IVT_IRQBASE + i, "irq", true,
 			    (iroutine_t) irq_interrupt);
@@ -218,4 +231,8 @@
 	exc_register(VECTOR_SS, "ss_fault", true, (iroutine_t) ss_fault);
 	exc_register(VECTOR_GP, "gp_fault", true, (iroutine_t) gp_fault);
+	exc_register(VECTOR_PIC0_SPUR, "pic0_spurious", true,
+	    (iroutine_t) pic_spurious);
+	exc_register(VECTOR_PIC1_SPUR, "pic1_spurious", true,
+	    (iroutine_t) pic_spurious);
 
 #ifdef CONFIG_SMP
Index: kernel/arch/arm32/include/arch/asm.h
===================================================================
--- kernel/arch/arm32/include/arch/asm.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/arm32/include/arch/asm.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -56,5 +56,5 @@
  * only for armv6+.
  */
-NO_TRACE static inline void cpu_sleep(void)
+_NO_TRACE static inline void cpu_sleep(void)
 {
 #ifdef PROCESSOR_ARCH_armv7_a
@@ -65,30 +65,30 @@
 }
 
-NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t v)
+_NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t v)
 {
 	*port = v;
 }
 
-NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t v)
+_NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t v)
 {
 	*port = v;
 }
 
-NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t v)
+_NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t v)
 {
 	*port = v;
 }
 
-NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
+_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)
+_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)
+_NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
 {
 	return *port;
@@ -102,5 +102,5 @@
  *
  */
-NO_TRACE static inline uintptr_t get_stack_base(void)
+_NO_TRACE static inline uintptr_t get_stack_base(void)
 {
 	uintptr_t v;
Index: kernel/arch/arm32/include/arch/context.h
===================================================================
--- kernel/arch/arm32/include/arch/context.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/arm32/include/arch/context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -40,4 +40,5 @@
 #include <arch/stack.h>
 #include <arch/context_struct.h>
+#include <arch/regutils.h>
 
 /* Put one item onto the stack to support get_stack_base() and align it up. */
@@ -49,4 +50,5 @@
 		(c)->sp = ((uintptr_t) (stack)) + (size) - SP_DELTA; \
 		(c)->fp = 0; \
+		(c)->cpu_mode = SUPERVISOR_MODE; \
 	} while (0)
 
Index: kernel/arch/arm32/include/arch/cycle.h
===================================================================
--- kernel/arch/arm32/include/arch/cycle.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/arm32/include/arch/cycle.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -47,5 +47,5 @@
  *
  */
-NO_TRACE static inline uint64_t get_cycle(void)
+_NO_TRACE static inline uint64_t get_cycle(void)
 {
 #ifdef PROCESSOR_ARCH_armv7_a
Index: kernel/arch/arm32/include/arch/istate.h
===================================================================
--- kernel/arch/arm32/include/arch/istate.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/arm32/include/arch/istate.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -55,5 +55,5 @@
  *
  */
-NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
+_NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
     uintptr_t retaddr)
 {
@@ -62,5 +62,5 @@
 
 /** Return true if exception happened while in userspace. */
-NO_TRACE static inline int istate_from_uspace(istate_t *istate)
+_NO_TRACE static inline int istate_from_uspace(istate_t *istate)
 {
 	return (istate->spsr & STATUS_REG_MODE_MASK) == USER_MODE;
@@ -68,10 +68,10 @@
 
 /** Return Program Counter member of given istate structure. */
-NO_TRACE static inline uintptr_t istate_get_pc(istate_t *istate)
+_NO_TRACE static inline uintptr_t istate_get_pc(istate_t *istate)
 {
 	return istate->pc;
 }
 
-NO_TRACE static inline uintptr_t istate_get_fp(istate_t *istate)
+_NO_TRACE static inline uintptr_t istate_get_fp(istate_t *istate)
 {
 	return istate->fp;
Index: kernel/arch/arm32/include/arch/mm/as.h
===================================================================
--- kernel/arch/arm32/include/arch/mm/as.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/arm32/include/arch/mm/as.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,4 +38,5 @@
 
 #define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH  0
+#define KERNEL_SEPARATE_PTL0_ARCH           0
 
 #define KERNEL_ADDRESS_SPACE_START_ARCH  UINT32_C(0x80000000)
Index: kernel/arch/arm32/include/arch/mm/page.h
===================================================================
--- kernel/arch/arm32/include/arch/mm/page.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/arm32/include/arch/mm/page.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -151,5 +151,5 @@
  * set_pt_level1_flags (kernel/arch/arm32/include/arch/mm/page_armv6.h)
  */
-NO_TRACE static inline void set_ptl0_addr(pte_t *pt)
+_NO_TRACE static inline void set_ptl0_addr(pte_t *pt)
 {
 	uint32_t val = (uint32_t)pt & TTBR_ADDR_MASK;
@@ -161,5 +161,5 @@
 }
 
-NO_TRACE static inline void set_ptl1_addr(pte_t *pt, size_t i, uintptr_t address)
+_NO_TRACE static inline void set_ptl1_addr(pte_t *pt, size_t i, uintptr_t address)
 {
 	pt[i].l0.coarse_table_addr = address >> 10;
@@ -167,5 +167,5 @@
 }
 
-NO_TRACE static inline void set_ptl3_addr(pte_t *pt, size_t i, uintptr_t address)
+_NO_TRACE static inline void set_ptl3_addr(pte_t *pt, size_t i, uintptr_t address)
 {
 	pt[i].l1.frame_base_addr = address >> 12;
Index: kernel/arch/arm32/include/arch/mm/page_armv4.h
===================================================================
--- kernel/arch/arm32/include/arch/mm/page_armv4.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/arm32/include/arch/mm/page_armv4.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -137,5 +137,5 @@
  *
  */
-NO_TRACE static inline int get_pt_level0_flags(pte_t *pt, size_t i)
+_NO_TRACE static inline int get_pt_level0_flags(pte_t *pt, size_t i)
 {
 	pte_level0_t *p = &pt[i].l0;
@@ -153,5 +153,5 @@
  *
  */
-NO_TRACE static inline int get_pt_level1_flags(pte_t *pt, size_t i)
+_NO_TRACE static inline int get_pt_level1_flags(pte_t *pt, size_t i)
 {
 	pte_level1_t *p = &pt[i].l1;
@@ -178,5 +178,5 @@
  *
  */
-NO_TRACE static inline void set_pt_level0_flags(pte_t *pt, size_t i, int flags)
+_NO_TRACE static inline void set_pt_level0_flags(pte_t *pt, size_t i, int flags)
 {
 	pte_level0_t *p = &pt[i].l0;
@@ -206,5 +206,5 @@
  *
  */
-NO_TRACE static inline void set_pt_level1_flags(pte_t *pt, size_t i, int flags)
+_NO_TRACE static inline void set_pt_level1_flags(pte_t *pt, size_t i, int flags)
 {
 	pte_level1_t *p = &pt[i].l1;
@@ -236,5 +236,5 @@
 }
 
-NO_TRACE static inline void set_pt_level0_present(pte_t *pt, size_t i)
+_NO_TRACE static inline void set_pt_level0_present(pte_t *pt, size_t i)
 {
 	pte_level0_t *p = &pt[i].l0;
@@ -245,5 +245,5 @@
 }
 
-NO_TRACE static inline void set_pt_level1_present(pte_t *pt, size_t i)
+_NO_TRACE static inline void set_pt_level1_present(pte_t *pt, size_t i)
 {
 	pte_level1_t *p = &pt[i].l1;
Index: kernel/arch/arm32/include/arch/mm/page_armv6.h
===================================================================
--- kernel/arch/arm32/include/arch/mm/page_armv6.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/arm32/include/arch/mm/page_armv6.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -164,5 +164,5 @@
  *
  */
-NO_TRACE static inline int get_pt_level0_flags(pte_t *pt, size_t i)
+_NO_TRACE static inline int get_pt_level0_flags(pte_t *pt, size_t i)
 {
 	const pte_level0_t *p = &pt[i].l0;
@@ -180,5 +180,5 @@
  *
  */
-NO_TRACE static inline int get_pt_level1_flags(pte_t *pt, size_t i)
+_NO_TRACE static inline int get_pt_level1_flags(pte_t *pt, size_t i)
 {
 	const pte_level1_t *p = &pt[i].l1;
@@ -206,5 +206,5 @@
  *
  */
-NO_TRACE static inline void set_pt_level0_flags(pte_t *pt, size_t i, int flags)
+_NO_TRACE static inline void set_pt_level0_flags(pte_t *pt, size_t i, int flags)
 {
 	pte_level0_t *p = &pt[i].l0;
@@ -239,5 +239,5 @@
  *
  */
-NO_TRACE static inline void set_pt_level1_flags(pte_t *pt, size_t i, int flags)
+_NO_TRACE static inline void set_pt_level1_flags(pte_t *pt, size_t i, int flags)
 {
 	pte_level1_t *p = &pt[i].l1;
@@ -297,5 +297,5 @@
 }
 
-NO_TRACE static inline void set_pt_level0_present(pte_t *pt, size_t i)
+_NO_TRACE static inline void set_pt_level0_present(pte_t *pt, size_t i)
 {
 	pte_level0_t *p = &pt[i].l0;
@@ -307,5 +307,5 @@
 }
 
-NO_TRACE static inline void set_pt_level1_present(pte_t *pt, size_t i)
+_NO_TRACE static inline void set_pt_level1_present(pte_t *pt, size_t i)
 {
 	pte_level1_t *p = &pt[i].l1;
Index: kernel/arch/arm32/src/mm/tlb.c
===================================================================
--- kernel/arch/arm32/src/mm/tlb.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/arm32/src/mm/tlb.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -76,5 +76,5 @@
 /** Invalidate single entry in TLB
  *
- * @param page Virtual adress of the page
+ * @param page Virtual address of the page
  */
 static inline void invalidate_page(uintptr_t page)
Index: kernel/arch/arm64/Makefile.inc
===================================================================
--- kernel/arch/arm64/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,68 @@
+#
+# Copyright (c) 2015 Petr Pavlu
+# 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_NAME = elf64-littleaarch64
+BFD_ARCH = aarch64
+BFD = binary
+
+COMMON_CFLAGS += -fno-omit-frame-pointer -march=armv8-a+nofp+nosimd \
+	-mgeneral-regs-only
+
+BITS = 64
+ENDIANESS = LE
+
+ARCH_SOURCES = \
+	arch/$(KARCH)/src/arm64.c \
+	arch/$(KARCH)/src/asm.S \
+	arch/$(KARCH)/src/context.S \
+	arch/$(KARCH)/src/cpu/cpu.c \
+	arch/$(KARCH)/src/debug/stacktrace.c \
+	arch/$(KARCH)/src/debug/stacktrace_asm.S \
+	arch/$(KARCH)/src/exception.c \
+	arch/$(KARCH)/src/fpu.S \
+	arch/$(KARCH)/src/fpu_context.c \
+	arch/$(KARCH)/src/interrupt.c \
+	arch/$(KARCH)/src/machine_func.c \
+	arch/$(KARCH)/src/mm/as.c \
+	arch/$(KARCH)/src/mm/frame.c \
+	arch/$(KARCH)/src/mm/km.c \
+	arch/$(KARCH)/src/mm/page.c \
+	arch/$(KARCH)/src/mm/tlb.c \
+	arch/$(KARCH)/src/smc.c \
+	arch/$(KARCH)/src/smp/ipi.c \
+	arch/$(KARCH)/src/smp/smp.c \
+	arch/$(KARCH)/src/start.S
+
+ifeq ($(MACHINE),virt)
+	ARCH_SOURCES += arch/$(KARCH)/src/mach/virt/virt.c
+endif
+
+ARCH_AUTOCHECK_HEADERS = \
+	arch/$(KARCH)/include/arch/context_struct.h \
+	arch/$(KARCH)/include/arch/fpu_context_struct.h \
+	arch/$(KARCH)/include/arch/istate_struct.h
Index: kernel/arch/arm64/_link.ld.in
===================================================================
--- kernel/arch/arm64/_link.ld.in	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/_link.ld.in	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,60 @@
+/*
+ * ARM64 linker script
+ *
+ *  kernel text
+ *  kernel data
+ *
+ */
+
+#include <arch/boot/boot.h>
+#include <arch/mm/km.h>
+
+#define LOAD_ADDRESS_V  (KM_ARM64_IDENTITY_START + BOOT_OFFSET)
+#define LOAD_ADDRESS_P  BOOT_OFFSET
+
+OUTPUT_ARCH(aarch64)
+ENTRY(kernel_image_start)
+
+SECTIONS {
+	kernel_load_address = LOAD_ADDRESS_V;
+
+	.image (LOAD_ADDRESS_V + SIZEOF_HEADERS) : AT (LOAD_ADDRESS_P + SIZEOF_HEADERS) {
+		. = ALIGN(16);
+		ktext_start = .;
+		*(K_TEXT_START)
+		*(.text .text.*);
+		ktext_end = .;
+
+		kdata_start = .;
+		*(K_DATA_START)
+		*(.data);                       /* initialized data */
+		*(.bss);                        /* uninitialized static variables */
+		*(COMMON);                      /* global variables */
+
+		*(.rodata*);
+		. = ALIGN(8);
+		symbol_table = .;
+		*(symtab.*);
+
+		kdata_end = .;
+	}
+
+#ifdef CONFIG_LINE_DEBUG
+	.comment 0 : { *(.comment); }
+	.debug_abbrev 0 : { *(.debug_abbrev); }
+	.debug_aranges 0 : { *(.debug_aranges); }
+	.debug_frame 0 : { *(.debug_frame); }
+	.debug_info 0 : { *(.debug_info); }
+	.debug_line 0 : { *(.debug_line); }
+	.debug_loc 0 : { *(.debug_loc); }
+	.debug_macinfo 0 : { *(.debug_macinfo); }
+	.debug_pubnames 0 : { *(.debug_pubnames); }
+	.debug_pubtypes 0 : { *(.debug_pubtypes); }
+	.debug_ranges 0 : { *(.debug_ranges); }
+	.debug_str 0 : { *(.debug_str); }
+#endif
+
+	/DISCARD/ : {
+		*(*);
+	}
+}
Index: kernel/arch/arm64/include/arch/arch.h
===================================================================
--- kernel/arch/arm64/include/arch/arch.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/arch.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ * @brief Various ARM64-specific macros.
+ */
+
+#ifndef KERN_arm64_ARCH_H_
+#define KERN_arm64_ARCH_H_
+
+#include <arch/boot/boot.h>
+
+extern void arm64_pre_main(void *entry, bootinfo_t *bootinfo);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/asm.h
===================================================================
--- kernel/arch/arm64/include/arch/asm.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/asm.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ * @brief Declarations of functions implemented in assembly.
+ */
+
+#ifndef KERN_arm64_ASM_H_
+#define KERN_arm64_ASM_H_
+
+#include <config.h>
+#include <trace.h>
+
+extern char exc_vector;
+
+/*
+ * Note: Function asm_delay_loop() is defined in arm64.c but declared here
+ * because the generic kernel code expects it in arch/asm.h.
+ */
+extern void asm_delay_loop(uint32_t usec);
+
+/** CPU specific way to sleep cpu. */
+_NO_TRACE static inline void cpu_sleep(void)
+{
+	asm volatile ("wfe");
+}
+
+/** Return base address of current stack.
+ *
+ * Return the base address of the current stack.
+ * The stack is assumed to be STACK_SIZE bytes long.
+ * The stack must start on page boundary.
+ */
+_NO_TRACE static inline uintptr_t get_stack_base(void)
+{
+	uintptr_t v;
+
+	asm volatile (
+	    "mov %[v], sp\n"
+	    "and %[v], %[v], %[size]\n"
+	    : [v] "=&r" (v)
+	    : [size] "r" (~((uint64_t) STACK_SIZE - 1))
+	);
+
+	return v;
+}
+
+/** Halts CPU. */
+_NO_TRACE static inline __attribute__((noreturn)) void cpu_halt(void)
+{
+	while (true)
+		;
+}
+
+/** Output byte to port.
+ *
+ * @param port Port to write to.
+ * @param val  Value to write.
+ */
+_NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t val)
+{
+	*port = val;
+}
+
+/** Output half-word to port.
+ *
+ * @param port Port to write to.
+ * @param val  Value to write.
+ */
+_NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t val)
+{
+	*port = val;
+}
+
+/** Output word to port.
+ *
+ * @param port Port to write to.
+ * @param val  Value to write.
+ */
+_NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t val)
+{
+	*port = val;
+}
+
+/** Get byte from port.
+ *
+ * @param port Port to read from.
+ * @return Value read.
+ */
+_NO_TRACE static inline uint8_t pio_read_8(const ioport8_t *port)
+{
+	return *port;
+}
+
+/** Get word from port.
+ *
+ * @param port Port to read from.
+ * @return Value read.
+ */
+_NO_TRACE static inline uint16_t pio_read_16(const ioport16_t *port)
+{
+	return *port;
+}
+
+/** Get double word from port.
+ *
+ * @param port Port to read from.
+ * @return Value read.
+ */
+_NO_TRACE static inline uint32_t pio_read_32(const ioport32_t *port)
+{
+	return *port;
+}
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/barrier.h
===================================================================
--- kernel/arch/arm64/include/arch/barrier.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/barrier.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ * @brief Memory barriers.
+ */
+
+#ifndef KERN_arm64_BARRIER_H_
+#define KERN_arm64_BARRIER_H_
+
+#include <stddef.h>
+
+#define COHERENCE_INVAL_MIN  4
+
+/** Ensure visibility of instruction updates for a multiprocessor.
+ *
+ * @param addr Address of the first instruction.
+ * @param size Size of the instruction block (in bytes).
+ */
+static inline void ensure_visibility(void *addr, size_t len)
+{
+	size_t i;
+
+	/*
+	 * Clean to Point of Unification to make the new instructions visible to
+	 * the instruction cache.
+	 */
+	for (i = 0; i < len; i += COHERENCE_INVAL_MIN)
+		asm volatile (
+		    "dc cvau, %[addr]\n"
+		    : : [addr] "r" ((char *) addr + i)
+		);
+
+	/* Ensure completion on all PEs. */
+	asm volatile ("dsb ish" ::: "memory");
+
+	/* Ensure instruction cache/branch predictor discards stale data. */
+	for (i = 0; i < len; i += COHERENCE_INVAL_MIN)
+		asm volatile (
+		    "ic ivau, %[addr]\n"
+		    : : [addr] "r" ((char *) addr + i)
+		);
+
+	/* Ensure completion on all PEs. */
+	asm volatile ("dsb ish" ::: "memory");
+
+	/* Synchronize context on this PE. */
+	asm volatile ("isb");
+}
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/boot/boot.h
===================================================================
--- kernel/arch/arm64/include/arch/boot/boot.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/boot/boot.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ * @brief Shared interface between the bootcode and the kernel.
+ */
+
+#ifndef KERN_arm64_BOOT_H_
+#define KERN_arm64_BOOT_H_
+
+#define BOOT_OFFSET  0x80000
+
+#ifndef __ASSEMBLER__
+#include <stddef.h>
+
+#define BOOTINFO_TASK_NAME_BUFLEN  32
+#define TASKMAP_MAX_RECORDS        32
+#define MEMMAP_MAX_RECORDS        128
+
+/** Task structure. */
+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];
+} utask_t;
+
+/** Task map structure. */
+typedef struct {
+	/** Number of boot tasks. */
+	size_t cnt;
+	/** Boot task data. */
+	utask_t tasks[TASKMAP_MAX_RECORDS];
+} taskmap_t;
+
+/** Memory zone types. */
+typedef enum {
+	/** Unusuable memory. */
+	MEMTYPE_UNUSABLE,
+	/** Usable memory. */
+	MEMTYPE_AVAILABLE,
+	/** Memory that can be used after ACPI is enabled. */
+	MEMTYPE_ACPI_RECLAIM
+} memtype_t;
+
+/** Memory area. */
+typedef struct {
+	/** Type of the memory. */
+	memtype_t type;
+	/** Address of the area. */
+	void *start;
+	/** Size of the area. */
+	size_t size;
+} memzone_t;
+
+/** System memory map. */
+typedef struct {
+	/** Number of memory zones. */
+	size_t cnt;
+	/** Memory zones. */
+	memzone_t zones[MEMMAP_MAX_RECORDS];
+} memmap_t;
+
+/** Bootinfo structure. */
+typedef struct {
+	/** Task map. */
+	taskmap_t taskmap;
+	/** Memory map. */
+	memmap_t memmap;
+} bootinfo_t;
+
+#endif /* __ASSEMBLER__ */
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/context.h
===================================================================
--- kernel/arch/arm64/include/arch/context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ * @brief Thread context.
+ */
+
+#ifndef KERN_arm64_CONTEXT_H_
+#define KERN_arm64_CONTEXT_H_
+
+#include <align.h>
+#include <arch/context_struct.h>
+#include <arch/stack.h>
+
+/* Put one item onto the stack to support get_stack_base() and align it up. */
+#define SP_DELTA  (0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
+
+#define context_set(c, _pc, stack, size) \
+	do { \
+		(c)->pc = (uint64_t) (_pc); \
+		(c)->sp = ((uint64_t) (stack)) + (size) - SP_DELTA; \
+		/* Set frame pointer too. */ \
+		(c)->x29 = 0; \
+	} while (0)
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/context_struct.h
===================================================================
--- kernel/arch/arm64/include/arch/context_struct.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/context_struct.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * All rights preserved.
+ *
+ * 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_ARCH_CONTEXT_STRUCT_H_
+#define KERN_ARCH_CONTEXT_STRUCT_H_
+
+#define CONTEXT_OFFSET_SP   0x00
+#define CONTEXT_OFFSET_PC   0x08
+#define CONTEXT_OFFSET_X19  0x10
+#define CONTEXT_OFFSET_X20  0x18
+#define CONTEXT_OFFSET_X21  0x20
+#define CONTEXT_OFFSET_X22  0x28
+#define CONTEXT_OFFSET_X23  0x30
+#define CONTEXT_OFFSET_X24  0x38
+#define CONTEXT_OFFSET_X25  0x40
+#define CONTEXT_OFFSET_X26  0x48
+#define CONTEXT_OFFSET_X27  0x50
+#define CONTEXT_OFFSET_X28  0x58
+#define CONTEXT_OFFSET_X29  0x60
+#define CONTEXT_OFFSET_IPL  0x68
+#define CONTEXT_SIZE        0x70
+
+#ifndef __ASSEMBLER__
+
+#include <typedefs.h>
+
+/*
+ * Thread context containing registers that must be preserved across function
+ * calls.
+ */
+typedef struct context {
+	uint64_t sp;
+	uint64_t pc;
+	uint64_t x19;
+	uint64_t x20;
+	uint64_t x21;
+	uint64_t x22;
+	uint64_t x23;
+	uint64_t x24;
+	uint64_t x25;
+	uint64_t x26;
+	uint64_t x27;
+	uint64_t x28;
+	uint64_t x29;
+	ipl_t ipl;
+} context_t;
+
+#endif
+#endif
Index: kernel/arch/arm64/include/arch/cpu.h
===================================================================
--- kernel/arch/arm64/include/arch/cpu.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/cpu.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ * @brief CPU identification.
+ */
+
+#ifndef KERN_arm64_CPU_H_
+#define KERN_arm64_CPU_H_
+
+/** Struct representing ARM CPU identification. */
+typedef struct {
+	/** Implementer (vendor) number. */
+	uint32_t implementer;
+
+	/** Variant number. */
+	uint32_t variant;
+
+	/** Primary part number. */
+	uint32_t partnum;
+
+	/** Revision number. */
+	uint32_t revision;
+} cpu_arch_t;
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/cycle.h
===================================================================
--- kernel/arch/arm64/include/arch/cycle.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/cycle.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ * @brief Information about a current cycle.
+ */
+
+#ifndef KERN_arm64_CYCLE_H_
+#define KERN_arm64_CYCLE_H_
+
+#include <arch/asm.h>
+#include <trace.h>
+
+/** Get a current cycle.
+ *
+ * No instruction exists on ARM64 to get the actual CPU cycle. The function
+ * instead returns the value of the virtual counter.
+ */
+_NO_TRACE static inline uint64_t get_cycle(void)
+{
+	return CNTVCT_EL0_read();
+}
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/exception.h
===================================================================
--- kernel/arch/arm64/include/arch/exception.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/exception.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2016 Petr Pavlu
+ *
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ * @brief Exception declarations.
+ */
+
+#ifndef KERN_arm64_EXCEPTION_H_
+#define KERN_arm64_EXCEPTION_H_
+
+/* Exception numbers. */
+
+/** Current Exception level with SP_EL0, Synchronous. */
+#define EXC_CURRENT_EL_SP_SEL0_SYNCH    0
+/** Current Exception level with SP_EL0, IRQ or vIRQ. */
+#define EXC_CURRENT_EL_SP_SEL0_IRQ      1
+/** Current Exception level with SP_EL0, FIQ or vFIQ. */
+#define EXC_CURRENT_EL_SP_SEL0_FIQ      2
+/** Current Exception level with SP_EL0, SError or vSError. */
+#define EXC_CURRENT_EL_SP_SEL0_SERROR   3
+/** Current Exception level with SP_ELx, x > 0, Synchronous. */
+#define EXC_CURRENT_EL_SP_SELX_SYNCH    4
+/** Current Exception level with SP_ELx, x > 0, IRQ or vIRQ. */
+#define EXC_CURRENT_EL_SP_SELX_IRQ      5
+/** Current Exception level with SP_ELx, x > 0, FIQ or vFIQ. */
+#define EXC_CURRENT_EL_SP_SELX_FIQ      6
+/** Current Exception level with SP_ELx, x > 0, SError or vSError. */
+#define EXC_CURRENT_EL_SP_SELX_SERROR   7
+/** Lower Exception level, where the implemented level immediately lower than
+ * the target level is using AArch64, Synchronous.
+ */
+#define EXC_LOWER_EL_AARCH64_SYNCH      8
+/** Lower Exception level, where the implemented level immediately lower than
+ * the target level is using AArch64, IRQ or vIRQ.
+ */
+#define EXC_LOWER_EL_AARCH64_IRQ        9
+/** Lower Exception level, where the implemented level immediately lower than
+ * the target level is using AArch64, FIQ or vFIQ.
+ */
+#define EXC_LOWER_EL_AARCH64_FIQ       10
+/** Lower Exception level, where the implemented level immediately lower than
+ * the target level is using AArch64, SError or vSError.
+ */
+#define EXC_LOWER_EL_AARCH64_SERROR    11
+/** Lower Exception level, where the implemented level immediately lower than
+ * the target level is using AArch32, Synchronous.
+ */
+#define EXC_LOWER_EL_AARCH32_SYNCH     12
+/** Lower Exception level, where the implemented level immediately lower than
+ * the target level is using AArch32, IRQ or vIRQ.
+ */
+#define EXC_LOWER_EL_AARCH32_IRQ       13
+/** Lower Exception level, where the implemented level immediately lower than
+ * the target level is using AArch32, FIQ or vFIQ.
+ */
+#define EXC_LOWER_EL_AARCH32_FIQ       14
+/** Lower Exception level, where the implemented level immediately lower than
+ * the target level is using AArch32, SError or vSError.
+ */
+#define EXC_LOWER_EL_AARCH32_SERROR    15
+
+#ifndef __ASSEMBLER__
+extern void exception_init(void);
+#endif /* __ASSEMBLER__ */
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/faddr.h
===================================================================
--- kernel/arch/arm64/include/arch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ * @brief Function address conversion.
+ */
+
+#ifndef KERN_arm64_FADDR_H_
+#define KERN_arm64_FADDR_H_
+
+#include <typedefs.h>
+
+/** Calculate absolute address of function referenced by fptr pointer.
+ *
+ * @param fptr Function pointer.
+ */
+#define FADDR(fptr)  ((uintptr_t) (fptr))
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/fpu_context.h
===================================================================
--- kernel/arch/arm64/include/arch/fpu_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/fpu_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ * @brief FPU context.
+ */
+
+#ifndef KERN_arm64_FPU_CONTEXT_H_
+#define KERN_arm64_FPU_CONTEXT_H_
+
+#include <arch/fpu_context_struct.h>
+
+#define FPU_CONTEXT_ALIGN  16
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/fpu_context_struct.h
===================================================================
--- kernel/arch/arm64/include/arch/fpu_context_struct.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/fpu_context_struct.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2018 Petr Pavlu
+ * All rights preserved.
+ *
+ * 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_ARCH_FPU_CONTEXT_STRUCT_H_
+#define KERN_ARCH_FPU_CONTEXT_STRUCT_H_
+
+#define FPU_CONTEXT_OFFSET_VREGS  0x000
+#define FPU_CONTEXT_OFFSET_FPCR   0x200
+#define FPU_CONTEXT_OFFSET_FPSR   0x204
+#define FPU_CONTEXT_SIZE          0x210
+
+#ifndef __ASSEMBLER__
+
+#include <typedefs.h>
+#include <_bits/int128_t.h>
+
+/** ARM64 FPU context. */
+typedef struct fpu_context {
+	uint128_t vregs[32];
+	uint32_t fpcr;
+	uint32_t fpsr;
+} fpu_context_t;
+
+#endif
+#endif
Index: kernel/arch/arm64/include/arch/interrupt.h
===================================================================
--- kernel/arch/arm64/include/arch/interrupt.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/interrupt.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64_interrupt
+ * @{
+ */
+/** @file
+ * @brief Declarations of interrupt controlling routines.
+ */
+
+#ifndef KERN_arm64_INTERRUPT_H_
+#define KERN_arm64_INTERRUPT_H_
+
+#include <arch/istate.h>
+#include <stdbool.h>
+#include <typedefs.h>
+
+/** Size of exception table. */
+#define IVT_ITEMS  16
+
+/** Index of the first item in exception table. */
+#define IVT_FIRST  0
+
+/* REVISIT */
+/* This needs to be defined for inter-architecture API portability. */
+#define VECTOR_TLB_SHOOTDOWN_IPI  0
+
+extern ipl_t interrupts_disable(void);
+extern ipl_t interrupts_enable(void);
+extern void interrupts_restore(ipl_t ipl);
+extern ipl_t interrupts_read(void);
+extern bool interrupts_disabled(void);
+extern void interrupt_init(void);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/istate.h
===================================================================
--- kernel/arch/arm64/include/arch/istate.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/istate.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ *
+ * 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 kernel_arm64_interrupt
+ * @{
+ */
+
+#ifndef KERN_arm64_ISTATE_H_
+#define KERN_arm64_ISTATE_H_
+
+#include <trace.h>
+
+#ifdef KERNEL
+
+#include <arch/istate_struct.h>
+#include <arch/regutils.h>
+
+#else /* KERNEL */
+
+#include <libarch/istate_struct.h>
+#include <libarch/regutils.h>
+
+#endif /* KERNEL */
+
+/** Set Program Counter member of given istate structure.
+ *
+ * @param istate  istate structure
+ * @param retaddr new value of istate's PC member
+ */
+_NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
+    uintptr_t retaddr)
+{
+	istate->pc = retaddr;
+}
+
+/** Return true if exception happened while in userspace. */
+_NO_TRACE static inline int istate_from_uspace(istate_t *istate)
+{
+	return (istate->spsr & SPSR_MODE_MASK) >> SPSR_MODE_SHIFT ==
+	    SPSR_MODE_ARM64_EL0T;
+}
+
+/** Return Program Counter member of given istate structure. */
+_NO_TRACE static inline uintptr_t istate_get_pc(istate_t *istate)
+{
+	return istate->pc;
+}
+
+/** Return Frame Pointer member of given istate structure. */
+_NO_TRACE static inline uintptr_t istate_get_fp(istate_t *istate)
+{
+	return istate->x29;
+}
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/istate_struct.h
===================================================================
--- kernel/arch/arm64/include/arch/istate_struct.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/istate_struct.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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_ARCH_ISTATE_STRUCT_H_
+#define KERN_ARCH_ISTATE_STRUCT_H_
+
+#define ISTATE_OFFSET_SPSR   0x00
+#define ISTATE_OFFSET_SP     0x08
+#define ISTATE_OFFSET_PC     0x10
+#define ISTATE_OFFSET_TPIDR  0x18
+#define ISTATE_OFFSET_X0     0x20
+#define ISTATE_OFFSET_X1     0x28
+#define ISTATE_OFFSET_X2     0x30
+#define ISTATE_OFFSET_X3     0x38
+#define ISTATE_OFFSET_X4     0x40
+#define ISTATE_OFFSET_X5     0x48
+#define ISTATE_OFFSET_X6     0x50
+#define ISTATE_OFFSET_X7     0x58
+#define ISTATE_OFFSET_X8     0x60
+#define ISTATE_OFFSET_X9     0x68
+#define ISTATE_OFFSET_X10    0x70
+#define ISTATE_OFFSET_X11    0x78
+#define ISTATE_OFFSET_X12    0x80
+#define ISTATE_OFFSET_X13    0x88
+#define ISTATE_OFFSET_X14    0x90
+#define ISTATE_OFFSET_X15    0x98
+#define ISTATE_OFFSET_X16    0xa0
+#define ISTATE_OFFSET_X17    0xa8
+#define ISTATE_OFFSET_X18    0xb0
+#define ISTATE_OFFSET_X19    0xb8
+#define ISTATE_OFFSET_X20    0xc0
+#define ISTATE_OFFSET_X21    0xc8
+#define ISTATE_OFFSET_X22    0xd0
+#define ISTATE_OFFSET_X23    0xd8
+#define ISTATE_OFFSET_X24    0xe0
+#define ISTATE_OFFSET_X25    0xe8
+#define ISTATE_OFFSET_X26    0xf0
+#define ISTATE_OFFSET_X27    0xf8
+#define ISTATE_OFFSET_X28    0x100
+#define ISTATE_OFFSET_X29    0x108
+#define ISTATE_OFFSET_X30    0x110
+#define ISTATE_SIZE          0x118
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+typedef struct istate {
+	uint64_t spsr;
+	uint64_t sp;
+	uint64_t pc;
+	uint64_t tpidr;
+	uint64_t x0;
+	uint64_t x1;
+	uint64_t x2;
+	uint64_t x3;
+	uint64_t x4;
+	uint64_t x5;
+	uint64_t x6;
+	uint64_t x7;
+	uint64_t x8;
+	uint64_t x9;
+	uint64_t x10;
+	uint64_t x11;
+	uint64_t x12;
+	uint64_t x13;
+	uint64_t x14;
+	uint64_t x15;
+	uint64_t x16;
+	uint64_t x17;
+	uint64_t x18;
+	uint64_t x19;
+	uint64_t x20;
+	uint64_t x21;
+	uint64_t x22;
+	uint64_t x23;
+	uint64_t x24;
+	uint64_t x25;
+	uint64_t x26;
+	uint64_t x27;
+	uint64_t x28;
+	/* Frame Pointer. */
+	uint64_t x29;
+	/* Link Register. */
+	uint64_t x30;
+} istate_t;
+
+#endif
+#endif
Index: kernel/arch/arm64/include/arch/mach/virt/virt.h
===================================================================
--- kernel/arch/arm64/include/arch/mach/virt/virt.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/mach/virt/virt.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 Petr Pavlu
+ * 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 kernel_arm64_virt
+ * @brief QEMU virt platform.
+ * @ingroup kernel_arm64
+ * @{
+ */
+/** @file
+ * @brief QEMU virt platform driver.
+ */
+
+#ifndef KERN_arm64_virt_H_
+#define KERN_arm64_virt_H_
+
+#include <arch/machine_func.h>
+
+extern struct arm_machine_ops virt_machine_ops;
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/machine_func.h
===================================================================
--- kernel/arch/arm64/include/arch/machine_func.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/machine_func.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2016 Petr Pavlu
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ * @brief Declarations of machine specific functions.
+ *
+ * These functions enable to differentiate more kinds of ARM platforms.
+ */
+
+#ifndef KERN_arm64_MACHINE_FUNC_H_
+#define KERN_arm64_MACHINE_FUNC_H_
+
+#include <arch/istate.h>
+#include <typedefs.h>
+
+struct arm_machine_ops {
+	void (*machine_init)(void);
+	void (*machine_irq_exception)(unsigned int, istate_t *);
+	void (*machine_output_init)(void);
+	void (*machine_input_init)(void);
+	inr_t (*machine_enable_vtimer_irq)(void);
+	size_t (*machine_get_irq_count)(void);
+	const char *(*machine_get_platform_name)(void);
+};
+
+extern void machine_ops_init(void);
+extern void machine_init(void);
+void machine_irq_exception(unsigned int, istate_t *);
+extern void machine_output_init(void);
+extern void machine_input_init(void);
+extern inr_t machine_enable_vtimer_irq(void);
+extern size_t machine_get_irq_count(void);
+extern const char *machine_get_platform_name(void);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/mm/as.h
===================================================================
--- kernel/arch/arm64/include/arch/mm/as.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/mm/as.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64_mm
+ * @{
+ */
+/** @file
+ * @brief Address space manipulating functions declarations.
+ */
+
+#ifndef KERN_arm64_AS_H_
+#define KERN_arm64_AS_H_
+
+#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH  0
+#define KERNEL_SEPARATE_PTL0_ARCH           1
+
+#define KERNEL_ADDRESS_SPACE_START_ARCH  UINT64_C(0xffff000000000000)
+#define KERNEL_ADDRESS_SPACE_END_ARCH    UINT64_C(0xffffffffffffffff)
+#define USER_ADDRESS_SPACE_START_ARCH    UINT64_C(0x0000000000000000)
+#define USER_ADDRESS_SPACE_END_ARCH      UINT64_C(0x0000ffffffffffff)
+
+typedef struct {
+} as_arch_t;
+
+#include <genarch/mm/as_pt.h>
+
+#define as_constructor_arch(as, flags)  ((void)as, (void)flags, EOK)
+#define as_destructor_arch(as)          ((void)as, 0)
+#define as_create_arch(as, flags)       ((void)as, (void)flags, EOK)
+#define as_deinstall_arch(as)
+#define as_invalidate_translation_cache(as, page, cnt)
+
+extern void as_arch_init(void);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/mm/asid.h
===================================================================
--- kernel/arch/arm64/include/arch/mm/asid.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/mm/asid.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64_mm
+ * @{
+ */
+/** @file
+ * @brief ASIDs related declarations.
+ */
+
+#ifndef KERN_arm64_ASID_H_
+#define KERN_arm64_ASID_H_
+
+#include <stdint.h>
+
+/*
+ * The ASID size is in VMSAv8-64 an implementation defined choice of 8 or 16
+ * bits. The actual size can be obtained by reading ID_AA64MMFR0_EL1.ASIDBits
+ * but for simplicity, HelenOS currently defaults to 8 bits.
+ */
+typedef uint8_t asid_t;
+
+#define ASID_MAX_ARCH  255
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/mm/frame.h
===================================================================
--- kernel/arch/arm64/include/arch/mm/frame.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/mm/frame.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64_mm
+ * @{
+ */
+/** @file
+ * @brief Frame related declarations.
+ */
+
+#ifndef KERN_arm64_FRAME_H_
+#define KERN_arm64_FRAME_H_
+
+#include <arch/boot/boot.h>
+
+#define FRAME_WIDTH  12  /* 4KB frames */
+#define FRAME_SIZE   (1 << FRAME_WIDTH)
+
+#define FRAME_LOWPRIO  0
+
+#ifndef __ASSEMBLER__
+
+extern void frame_low_arch_init(void);
+extern void frame_high_arch_init(void);
+extern void physmem_print(void);
+
+extern memmap_t memmap;
+
+#endif /* __ASSEMBLER__ */
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/mm/km.h
===================================================================
--- kernel/arch/arm64/include/arch/mm/km.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/mm/km.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64_mm
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_arm64_KM_H_
+#define KERN_arm64_KM_H_
+
+#ifndef __ASSEMBLER__
+
+#include <stdbool.h>
+#include <typedefs.h>
+
+#define KM_ARM64_IDENTITY_START  UINT64_C(0xffffffff80000000)
+#define KM_ARM64_IDENTITY_SIZE   UINT64_C(0x0000000080000000)
+
+#define KM_ARM64_NON_IDENTITY_START  UINT64_C(0xffff000000000000)
+#define KM_ARM64_NON_IDENTITY_SIZE   UINT64_C(0x0000ffff80000000)
+
+extern void km_identity_arch_init(void);
+extern void km_non_identity_arch_init(void);
+extern bool km_is_non_identity_arch(uintptr_t);
+
+#else /* __ASSEMBLER__ */
+
+#define KM_ARM64_IDENTITY_START  0xffffffff80000000
+#define KM_ARM64_IDENTITY_SIZE   0x0000000080000000
+
+#define KM_ARM64_NON_IDENTITY_START  0xffff000000000000
+#define KM_ARM64_NON_IDENTITY_SIZE   0x0000ffff80000000
+
+#endif /* __ASSEMBLER__ */
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/mm/page.h
===================================================================
--- kernel/arch/arm64/include/arch/mm/page.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/mm/page.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,422 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64_mm
+ * @{
+ */
+/** @file
+ * @brief Paging related declarations.
+ */
+
+#ifndef KERN_arm64_PAGE_H_
+#define KERN_arm64_PAGE_H_
+
+#include <arch/mm/frame.h>
+#include <mm/mm.h>
+#include <trace.h>
+
+#ifndef __ASSEMBLER__
+#include <typedefs.h>
+#endif /* __ASSEMBLER__ */
+
+#define PAGE_WIDTH  FRAME_WIDTH
+#define PAGE_SIZE   FRAME_SIZE
+
+#ifndef __ASSEMBLER__
+
+extern uintptr_t physmem_base;
+
+#define KA2PA(x) \
+	(((uintptr_t) (x)) - UINT64_C(0xffffffff80000000) + physmem_base)
+#define PA2KA(x) \
+	(((uintptr_t) (x)) + UINT64_C(0xffffffff80000000) - physmem_base)
+
+#endif /* __ASSEMBLER__ */
+
+/** Log2 size of each translation table entry. */
+#define PTL_ENTRY_SIZE_SHIFT  3
+
+/* Number of entries in each level. */
+#define PTL0_ENTRIES_ARCH  512
+#define PTL1_ENTRIES_ARCH  512
+#define PTL2_ENTRIES_ARCH  512
+#define PTL3_ENTRIES_ARCH  512
+
+/* 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
+
+/* Starting bit of virtual address portion translated in each level. */
+#define PTL0_VA_SHIFT  39
+#define PTL1_VA_SHIFT  30
+#define PTL2_VA_SHIFT  21
+#define PTL3_VA_SHIFT  12
+
+/* Size mask of virtual address portion translated in each level. */
+#define PTL0_VA_MASK  0x1ff
+#define PTL1_VA_MASK  0x1ff
+#define PTL2_VA_MASK  0x1ff
+#define PTL3_VA_MASK  0x1ff
+
+/* Macros calculating indices into page tables for each level. */
+#define PTL0_INDEX_ARCH(vaddr)  (((vaddr) >> PTL0_VA_SHIFT) & PTL0_VA_MASK)
+#define PTL1_INDEX_ARCH(vaddr)  (((vaddr) >> PTL1_VA_SHIFT) & PTL1_VA_MASK)
+#define PTL2_INDEX_ARCH(vaddr)  (((vaddr) >> PTL2_VA_SHIFT) & PTL2_VA_MASK)
+#define PTL3_INDEX_ARCH(vaddr)  (((vaddr) >> PTL3_VA_SHIFT) & PTL3_VA_MASK)
+
+/* Get PTE address accessors for each level. */
+#define GET_PTL1_ADDRESS_ARCH(ptl0, i) \
+	((pte_t *) (((uintptr_t) ((pte_t *) (ptl0))[(i)].output_address) << 12))
+#define GET_PTL2_ADDRESS_ARCH(ptl1, i) \
+	((pte_t *) (((uintptr_t) ((pte_t *) (ptl1))[(i)].output_address) << 12))
+#define GET_PTL3_ADDRESS_ARCH(ptl2, i) \
+	((pte_t *) (((uintptr_t) ((pte_t *) (ptl2))[(i)].output_address) << 12))
+#define GET_FRAME_ADDRESS_ARCH(ptl3, i) \
+	(((uintptr_t) ((pte_t *) (ptl3))[(i)].output_address) << 12)
+
+/*
+ * Set PTE address accessors for each level. Setting of the level 0 table is
+ * ignored because it must be done only by calling as_install_arch() which also
+ * changes ASID.
+ */
+#define SET_PTL0_ADDRESS_ARCH(ptl0)
+#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \
+	(((pte_t *) (ptl0))[(i)].output_address = (a) >> 12)
+#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a) \
+	(((pte_t *) (ptl1))[(i)].output_address = (a) >> 12)
+#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a) \
+	(((pte_t *) (ptl2))[(i)].output_address = (a) >> 12)
+#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \
+	(((pte_t *) (ptl3))[(i)].output_address = (a) >> 12)
+
+/* Get PTE flags accessors for each level. */
+#define GET_PTL1_FLAGS_ARCH(ptl0, i) \
+	get_pt_level012_flags((pte_t *) (ptl0), (size_t) (i))
+#define GET_PTL2_FLAGS_ARCH(ptl1, i) \
+	get_pt_level012_flags((pte_t *) (ptl1), (size_t) (i))
+#define GET_PTL3_FLAGS_ARCH(ptl2, i) \
+	get_pt_level012_flags((pte_t *) (ptl2), (size_t) (i))
+#define GET_FRAME_FLAGS_ARCH(ptl3, i) \
+	get_pt_level3_flags((pte_t *) (ptl3), (size_t) (i))
+
+/* Set PTE flags accessors for each level. */
+#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \
+	set_pt_level012_flags((pte_t *) (ptl0), (size_t) (i), (x))
+#define SET_PTL2_FLAGS_ARCH(ptl1, i, x) \
+	set_pt_level012_flags((pte_t *) (ptl1), (size_t) (i), (x))
+#define SET_PTL3_FLAGS_ARCH(ptl2, i, x) \
+	set_pt_level012_flags((pte_t *) (ptl2), (size_t) (i), (x))
+#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
+	set_pt_level3_flags((pte_t *) (ptl3), (size_t) (i), (x))
+
+/* Set PTE present bit accessors for each level. */
+#define SET_PTL1_PRESENT_ARCH(ptl0, i) \
+	set_pt_present((pte_t *) (ptl0), (size_t) (i))
+#define SET_PTL2_PRESENT_ARCH(ptl1, i) \
+	set_pt_present((pte_t *) (ptl1), (size_t) (i))
+#define SET_PTL3_PRESENT_ARCH(ptl2, i) \
+	set_pt_present((pte_t *) (ptl2), (size_t) (i))
+#define SET_FRAME_PRESENT_ARCH(ptl3, i) \
+	set_pt_present((pte_t *) (ptl3), (size_t) (i))
+
+/* Macros for querying the last-level PTE entries. */
+#define PTE_VALID_ARCH(pte) \
+	(((pte_t *) (pte))->valid != 0)
+#define PTE_PRESENT_ARCH(pte) \
+	(((pte_t *) (pte))->valid != 0)
+#define PTE_GET_FRAME_ARCH(pte) \
+	(((uintptr_t) ((pte_t *) (pte))->output_address) << FRAME_WIDTH)
+#define PTE_WRITABLE_ARCH(pte) \
+	get_pt_writable((pte_t *) (pte))
+#define PTE_EXECUTABLE_ARCH(pte) \
+	get_pt_executable((pte_t *) (pte))
+
+/* Level 3 access permissions. */
+
+/** Data access permission. User mode: no access, privileged mode: read/write.
+ */
+#define PTE_AP_USER_NO_KERNEL_FULL  0
+
+/** Data access permission. User mode: read/write, privileged mode: read/write.
+ */
+#define PTE_AP_USER_FULL_KERNEL_FULL  1
+
+/** Data access permission. User mode: no access, privileged mode: read only. */
+#define PTE_AP_USER_NO_KERNEL_LIMITED  2
+
+/** Data access permission. User mode: read only, privileged mode: read only. */
+#define PTE_AP_USER_LIMITED_KERNEL_LIMITED  3
+
+/*
+ * Memory types. MAIR_EL1 index 0 is unused, which assures that if a page
+ * table entry is non-null then it is valid (PTE_VALID_ARCH() returns true).
+ */
+
+/** Write-Back Cacheable Normal memory, Inner shareable, Read-write cache
+ * allocation. Defined in MAIR_EL1 index 1.
+ */
+#define MAIR_EL1_NORMAL_MEMORY_ATTR  0xff
+#define MAIR_EL1_NORMAL_MEMORY_INDEX  1
+
+/** Device-nGnRE memory (Device non-Gathering, non-Reordering, Early Write
+ * Acknowledgement). Equivalent to the Device memory type in earlier versions of
+ * the architecture. Defined in MAIR_EL1 index 2.
+ */
+#define MAIR_EL1_DEVICE_MEMORY_ATTR  0x04
+#define MAIR_EL1_DEVICE_MEMORY_INDEX  2
+
+/** Bit width of one memory attribute field in MAIR_EL1. */
+#define MAIR_EL1_ATTR_SHIFT  8
+
+/* Level 0, 1, 2 descriptor types. */
+
+/** Block descriptor (valid in level 0, 1, 2 page translation tables). */
+#define PTE_L012_TYPE_BLOCK  0
+
+/** Next-table descriptor (valid in level 0, 1, 2 page translation tables). */
+#define PTE_L012_TYPE_TABLE  1
+
+/* Level 3 descriptor types. */
+
+/** Page descriptor (valid in level 3 page translation tables). */
+#define PTE_L3_TYPE_PAGE  1
+
+/** HelenOS descriptor type. Table for level 0, 1, 2 page translation tables,
+ * page for level 3 tables. Block descriptors are not used by HelenOS during
+ * normal processing.
+ */
+#define PTE_L0123_TYPE_HELENOS  1
+
+/* Page table entry access macros. */
+
+/** Shift to access the next-level table address in a page table entry. */
+#define PTE_NEXT_LEVEL_ADDRESS_SHIFT  12
+
+/** Shift to access the resulting address in a page table entry. */
+#define PTE_OUTPUT_ADDRESS_SHIFT  12
+
+/** Shift to access the access bit in a page table entry. */
+#define PTE_ACCESS_SHIFT  10
+
+/** Shift to access the attr_index field in a page table entry. */
+#define PTE_ATTR_INDEX_SHIFT  2
+
+/** Shift to access the type bit in a page table entry. */
+#define PTE_TYPE_SHIFT  1
+
+/** Shift to access the present bit in a page table entry. */
+#define PTE_PRESENT_SHIFT  0
+
+/** The present bit in a page table entry. */
+#define PTE_PRESENT_FLAG  (1 << PTE_PRESENT_SHIFT)
+
+#ifndef __ASSEMBLER__
+
+#include <arch/interrupt.h>
+
+/** Page Table Entry.
+ *
+ * HelenOS model:
+ * * Level 0, 1, 2 translation tables hold next-level table descriptors. Block
+ *   descriptors are not used during normal processing.
+ * * Level 3 tables store 4kB page descriptors.
+ */
+typedef struct {
+	/* Common bits. */
+	/** Flag indicating entry contains valid data and can be used for page
+	 * translation.
+	 *
+	 * Note: The flag is called `valid' in the official ARM terminology
+	 * but it has the `present' (valid+active) sense in HelenOS.
+	 */
+	unsigned valid : 1;
+	unsigned type : 1;
+
+	/* Lower block and page attributes. */
+	unsigned attr_index : 3;
+	unsigned non_secure : 1;
+	unsigned access_permission : 2;
+	unsigned shareability : 2;
+	unsigned access : 1;
+	unsigned not_global : 1;
+
+	/* Common output address. */
+	uint64_t output_address : 36;
+
+	unsigned : 4;
+
+	/* Upper block and page attributes. */
+	unsigned contiguous : 1;
+	unsigned privileged_execute_never : 1;
+	unsigned unprivileged_execute_never : 1;
+
+	unsigned : 4;
+
+	/* Next-level table attributes. */
+	unsigned privileged_execute_never_table : 1;
+	unsigned unprivileged_execute_never_table : 1;
+	unsigned access_permission_table : 2;
+	unsigned non_secure_table : 1;
+} __attribute__((packed)) pte_t;
+
+/** Returns level 0, 1, 2 page table entry flags.
+ *
+ * @param pt Level 0, 1, 2 page table.
+ * @param i  Index of the entry to return.
+ */
+_NO_TRACE static inline unsigned int get_pt_level012_flags(pte_t *pt, size_t i)
+{
+	pte_t *p = &pt[i];
+
+	return (1 << PAGE_CACHEABLE_SHIFT) |
+	    (!p->valid << PAGE_PRESENT_SHIFT) | (1 << PAGE_USER_SHIFT) |
+	    (1 << PAGE_READ_SHIFT) | (1 << PAGE_WRITE_SHIFT) |
+	    (1 << PAGE_EXEC_SHIFT);
+}
+
+/** Returns level 3 page table entry flags.
+ *
+ * @param pt Level 3 page table.
+ * @param i  Index of the entry to return.
+ */
+_NO_TRACE static inline unsigned int get_pt_level3_flags(pte_t *pt, size_t i)
+{
+	pte_t *p = &pt[i];
+
+	int cacheable = (p->attr_index == MAIR_EL1_NORMAL_MEMORY_INDEX);
+	int user = (p->access_permission == PTE_AP_USER_FULL_KERNEL_FULL ||
+	    p->access_permission == PTE_AP_USER_LIMITED_KERNEL_LIMITED);
+	int write = (p->access_permission == PTE_AP_USER_FULL_KERNEL_FULL ||
+	    p->access_permission == PTE_AP_USER_NO_KERNEL_FULL);
+	int exec = ((user && !p->unprivileged_execute_never) ||
+	    (!user && !p->privileged_execute_never));
+
+	return (cacheable << PAGE_CACHEABLE_SHIFT) |
+	    (!p->valid << PAGE_PRESENT_SHIFT) | (user << PAGE_USER_SHIFT) |
+	    (1 << PAGE_READ_SHIFT) | (write << PAGE_WRITE_SHIFT) |
+	    (exec << PAGE_EXEC_SHIFT) | (!p->not_global << PAGE_GLOBAL_SHIFT);
+}
+
+/** Sets flags of level 0, 1, 2 page table entry.
+ *
+ * @param pt    Level 0, 1, 2 page table.
+ * @param i     Index of the entry to be changed.
+ * @param flags New flags.
+ */
+_NO_TRACE static inline void set_pt_level012_flags(pte_t *pt, size_t i,
+    int flags)
+{
+	pte_t *p = &pt[i];
+
+	p->valid = (flags & PAGE_PRESENT) != 0;
+	p->type = PTE_L012_TYPE_TABLE;
+}
+
+/** Sets flags of level 3 page table entry.
+ *
+ * @param pt    Level 3 page table.
+ * @param i     Index of the entry to be changed.
+ * @param flags New flags.
+ */
+_NO_TRACE static inline void set_pt_level3_flags(pte_t *pt, size_t i,
+    int flags)
+{
+	pte_t *p = &pt[i];
+
+	if (flags & PAGE_CACHEABLE)
+		p->attr_index = MAIR_EL1_NORMAL_MEMORY_INDEX;
+	else
+		p->attr_index = MAIR_EL1_DEVICE_MEMORY_INDEX;
+	p->valid = (flags & PAGE_PRESENT) != 0;
+	p->type = PTE_L3_TYPE_PAGE;
+
+	/* Translate page permissions to access permissions. */
+	if (flags & PAGE_USER) {
+		if (flags & PAGE_WRITE)
+			p->access_permission = PTE_AP_USER_FULL_KERNEL_FULL;
+		else
+			p->access_permission =
+			    PTE_AP_USER_LIMITED_KERNEL_LIMITED;
+	} else {
+		if (flags & PAGE_WRITE)
+			p->access_permission = PTE_AP_USER_NO_KERNEL_FULL;
+		else
+			p->access_permission = PTE_AP_USER_NO_KERNEL_LIMITED;
+	}
+	p->access = 1;
+	p->unprivileged_execute_never = p->privileged_execute_never =
+	    (flags & PAGE_EXEC) == 0;
+
+	p->not_global = (flags & PAGE_GLOBAL) == 0;
+}
+
+/** Sets the present flag of page table entry.
+ *
+ * @param pt Level 0, 1, 2, 3 page table.
+ * @param i  Index of the entry to be changed.
+ */
+_NO_TRACE static inline void set_pt_present(pte_t *pt, size_t i)
+{
+	pte_t *p = &pt[i];
+
+	p->valid = 1;
+}
+
+/** Gets the executable flag of page table entry.
+ *
+ * @param pte Page table entry.
+ */
+_NO_TRACE static inline bool get_pt_executable(pte_t *pte)
+{
+	if (pte->access_permission == PTE_AP_USER_NO_KERNEL_FULL ||
+	    pte->access_permission == PTE_AP_USER_NO_KERNEL_LIMITED)
+		return pte->privileged_execute_never;
+	else
+		return pte->unprivileged_execute_never;
+}
+
+/** Gets the writable flag of page table entry.
+ *
+ * @param pte Page table entry.
+ */
+_NO_TRACE static inline bool get_pt_writable(pte_t *pte)
+{
+	return pte->access_permission == PTE_AP_USER_FULL_KERNEL_FULL ||
+	    pte->access_permission == PTE_AP_USER_NO_KERNEL_FULL;
+}
+
+extern void page_arch_init(void);
+
+#endif /* __ASSEMBLER__ */
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/mm/tlb.h
===================================================================
--- kernel/arch/arm64/include/arch/mm/tlb.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/mm/tlb.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64_mm
+ * @{
+ */
+/** @file
+ * @brief TLB related declarations.
+ */
+
+#ifndef KERN_arm64_TLB_H_
+#define KERN_arm64_TLB_H_
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/proc/task.h
===================================================================
--- kernel/arch/arm64/include/arch/proc/task.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/proc/task.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64_proc
+ * @{
+ */
+/** @file
+ * @brief Task related declarations.
+ */
+
+#ifndef KERN_arm64_TASK_H_
+#define KERN_arm64_TASK_H_
+
+typedef struct {
+} task_arch_t;
+
+#define task_create_arch(t)
+#define task_destroy_arch(t)
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/proc/thread.h
===================================================================
--- kernel/arch/arm64/include/arch/proc/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/proc/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64_proc
+ * @{
+ */
+/** @file
+ * @brief Thread related declarations.
+ */
+
+#ifndef KERN_arm64_THREAD_H_
+#define KERN_arm64_THREAD_H_
+
+typedef struct {
+} thread_arch_t;
+
+#define thr_constructor_arch(t)
+#define thr_destructor_arch(t)
+#define thread_create_arch(t, flags) (EOK)
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/regutils.h
===================================================================
--- kernel/arch/arm64/include/arch/regutils.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/regutils.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ * @brief Utilities for convenient manipulation with ARM registers.
+ */
+
+#ifndef KERN_arm64_REGUTILS_H_
+#define KERN_arm64_REGUTILS_H_
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+#define SPECIAL_REG_GEN_READ(name) \
+	static inline uint64_t name##_read(void) \
+	{ \
+		uint64_t res; \
+		asm volatile ( \
+		    "mrs %[res], " #name \
+		    : [res] "=r" (res) \
+		); \
+		return res; \
+	}
+
+#define SPECIAL_REG_GEN_WRITE(name) \
+	static inline void name##_write(uint64_t regn) \
+	{ \
+		asm volatile ( \
+		    "msr " #name ", %[regn]\n" \
+		    "isb\n" \
+		    :: [regn] "r" (regn) \
+		); \
+	}
+
+#define UWORD64(c)  UINT64_C(c)
+
+#else /* __ASSEMBLER__ */
+
+#define SPECIAL_REG_GEN_READ(name)
+#define SPECIAL_REG_GEN_WRITE(name)
+#define UWORD64(c)  c
+
+#endif /* __ASSEMBLER__*/
+
+/* CNTFRQ_EL0 */
+SPECIAL_REG_GEN_READ(CNTFRQ_EL0);
+
+/* CNTVCT_EL0 */
+SPECIAL_REG_GEN_READ(CNTVCT_EL0);
+
+/* CNTV_CTL_EL0 */
+SPECIAL_REG_GEN_READ(CNTV_CTL_EL0);
+SPECIAL_REG_GEN_WRITE(CNTV_CTL_EL0);
+#define CNTV_CTL_ENABLE_SHIFT  0
+#define CNTV_CTL_ENABLE_FLAG  (UWORD64(1) << CNTV_CTL_ENABLE_SHIFT)
+#define CNTV_CTL_IMASK_SHIFT  1
+#define CNTV_CTL_IMASK_FLAG  (UWORD64(1) << CNTV_CTL_IMASK_SHIFT)
+
+/* CNTV_CVAL_EL0 */
+SPECIAL_REG_GEN_READ(CNTV_CVAL_EL0);
+SPECIAL_REG_GEN_WRITE(CNTV_CVAL_EL0);
+
+/* CPACR_EL1 */
+SPECIAL_REG_GEN_READ(CPACR_EL1);
+SPECIAL_REG_GEN_WRITE(CPACR_EL1);
+#define CPACR_FPEN_SHIFT  20
+#define CPACR_FPEN_MASK  (UWORD64(0x3) << CPACR_FPEN_SHIFT)
+#define CPACR_FPEN_TRAP_ALL  0x0
+#define CPACR_FPEN_TRAP_NONE  0x3
+
+/* CurrentEL */
+SPECIAL_REG_GEN_READ(CurrentEL);
+#define CURRENT_EL_EL0  0x0
+#define CURRENT_EL_EL1  0x4
+#define CURRENT_EL_EL2  0x8
+#define CURRENT_EL_EL3  0xc
+
+/* DAIF */
+SPECIAL_REG_GEN_READ(DAIF);
+SPECIAL_REG_GEN_WRITE(DAIF);
+#define DAIF_IRQ_SHIFT  7
+#define DAIF_IRQ_FLAG  (UWORD64(1) << DAIF_IRQ_SHIFT)
+
+/* ELR */
+SPECIAL_REG_GEN_WRITE(ELR_EL1);
+
+/* ESR */
+SPECIAL_REG_GEN_READ(ESR_EL1);
+#define ESR_EC_SHIFT  26
+#define ESR_EC_MASK  (UWORD64(0x3f) << ESR_EC_SHIFT)
+
+/** Exception from access to Advanced SIMD or floating-point functionality. */
+#define ESR_EC_FP  0x07
+/** Exception from SVC instruction execution. */
+#define ESR_EC_SVC  0x15
+
+/** Instruction abort from Lower Exception level. */
+#define ESR_EC_IA_LOWER_EL  0x20
+/** Data abort from Lower Exception level. */
+#define ESR_EC_DA_LOWER_EL  0x24
+/** Data abort from Current Exception level. */
+#define ESR_EC_DA_CURRENT_EL  0x25
+
+/** Instruction/data Fault Status Code. */
+#define ESR_IDFSC_SHIFT  0
+#define ESR_IDFSC_MASK  (UWORD64(0x3f) << ESR_IDFSC_SHIFT)
+
+/** Instruction/data abort, translation fault, zeroth level. */
+#define ESR_IDA_IDFSC_TF0  0x4
+/** Instruction/data abort, translation fault, first level. */
+#define ESR_IDA_IDFSC_TF1  0x5
+/** Instruction/data abort, translation fault, second level. */
+#define ESR_IDA_IDFSC_TF2  0x6
+/** Instruction/data abort, translation fault, third level. */
+#define ESR_IDA_IDFSC_TF3  0x7
+
+/** Data abort, Write not Read. */
+#define ESR_DA_WNR_SHIFT  6
+#define ESR_DA_WNR_FLAG  (UWORD64(1) << ESR_DA_WNR_SHIFT)
+
+/* FAR */
+SPECIAL_REG_GEN_READ(FAR_EL1);
+
+/* MIDR_EL1 */
+SPECIAL_REG_GEN_READ(MIDR_EL1);
+#define MIDR_REVISION_SHIFT  0
+#define MIDR_REVISION_MASK  (UWORD64(0xf) << MIDR_REVISION_SHIFT)
+#define MIDR_PARTNUM_SHIFT  4
+#define MIDR_PARTNUM_MASK  (UWORD64(0xfff) << MIDR_PARTNUM_SHIFT)
+#define MIDR_VARIANT_SHIFT  20
+#define MIDR_VARIANT_MASK  (UWORD64(0xf) << MIDR_VARIANT_SHIFT)
+#define MIDR_IMPLEMENTER_SHIFT  24
+#define MIDR_IMPLEMENTER_MASK  (UWORD64(0xff) << MIDR_IMPLEMENTER_SHIFT)
+
+/* SCTLR */
+#define SCTLR_M_SHIFT  0
+#define SCTLR_M_FLAG  (UWORD64(1) << SCTLR_M_SHIFT)
+
+/* SP */
+SPECIAL_REG_GEN_WRITE(SP_EL0);
+
+/* SPSR */
+SPECIAL_REG_GEN_READ(SPSR_EL1);
+SPECIAL_REG_GEN_WRITE(SPSR_EL1);
+#define SPSR_MODE_SHIFT  0
+#define SPSR_MODE_MASK  (UWORD64(0x1f) << SPSR_MODE_SHIFT)
+#define SPSR_MODE_ARM64_EL0T  0x00  /* ARM64, Exception Level 0, SP_EL0 */
+
+/* TPIDR */
+SPECIAL_REG_GEN_WRITE(TPIDR_EL0);
+
+/* TTBR */
+SPECIAL_REG_GEN_WRITE(TTBR0_EL1);
+SPECIAL_REG_GEN_WRITE(TTBR1_EL1);
+#define TTBR0_ASID_SHIFT  48
+
+/* VBAR */
+SPECIAL_REG_GEN_WRITE(VBAR_EL1);
+
+/* TLBI VAE1IS and TLBI ASIDE1IS parameter. */
+#define TLBI_ASID_SHIFT  48
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/stack.h
===================================================================
--- kernel/arch/arm64/include/arch/stack.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/stack.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ * @brief Stack constants.
+ */
+
+#ifndef KERN_arm64_STACK_H_
+#define KERN_arm64_STACK_H_
+
+#include <config.h>
+
+#define MEM_STACK_SIZE  STACK_SIZE
+
+/** Size of a stack item. */
+#define STACK_ITEM_SIZE	 8
+
+/** Required stack alignment. */
+#define STACK_ALIGNMENT	 16
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/include/arch/types.h
===================================================================
--- kernel/arch/arm64/include/arch/types.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/include/arch/types.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_arm64_TYPES_H_
+#define KERN_arm64_TYPES_H_
+
+#include <_bits/all.h>
+
+typedef struct {
+} fncptr_t;
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm64/src/arm64.c
===================================================================
--- kernel/arch/arm64/src/arm64.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/src/arm64.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ * @brief ARM64 architecture specific functions.
+ */
+
+#include <abi/errno.h>
+#include <arch.h>
+#include <arch/arch.h>
+#include <arch/asm.h>
+#include <arch/exception.h>
+#include <arch/machine_func.h>
+#include <interrupt.h>
+#include <proc/scheduler.h>
+#include <syscall/syscall.h>
+#include <sysinfo/sysinfo.h>
+#include <userspace.h>
+
+static void arm64_post_mm_init(void);
+static void arm64_post_smp_init(void);
+
+arch_ops_t arm64_ops = {
+	.post_mm_init = arm64_post_mm_init,
+	.post_smp_init = arm64_post_smp_init,
+};
+
+arch_ops_t *arch_ops = &arm64_ops;
+
+/** Perform ARM64 specific initialization before main_bsp() is called. */
+void arm64_pre_main(void *entry __attribute__((unused)), bootinfo_t *bootinfo)
+{
+	/* Copy init task info. */
+	init.cnt = min3(bootinfo->taskmap.cnt, TASKMAP_MAX_RECORDS,
+	    CONFIG_INIT_TASKS);
+
+	size_t i;
+	for (i = 0; i < init.cnt; i++) {
+		init.tasks[i].paddr =
+		    (uintptr_t) bootinfo->taskmap.tasks[i].addr;
+		init.tasks[i].size = bootinfo->taskmap.tasks[i].size;
+		str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
+		    bootinfo->taskmap.tasks[i].name);
+	}
+
+	/* Copy physical memory map. */
+	memmap.cnt = min(bootinfo->memmap.cnt, MEMMAP_MAX_RECORDS);
+	for (i = 0; i < memmap.cnt; i++) {
+		memmap.zones[i].type = bootinfo->memmap.zones[i].type;
+		memmap.zones[i].start = bootinfo->memmap.zones[i].start;
+		memmap.zones[i].size = bootinfo->memmap.zones[i].size;
+	}
+
+	/* Initialize machine_ops pointer. */
+	machine_ops_init();
+}
+
+/** Perform ARM64 specific tasks needed before the memory management is
+ * initialized.
+ */
+void arm64_post_mm_init(void)
+{
+	if (config.cpu_active != 1)
+		return;
+
+	/* Do machine-specific initialization. */
+	machine_init();
+
+	/* Initialize exception dispatch table. */
+	exception_init();
+	interrupt_init();
+
+	/* Merge all memory zones to 1 big zone. */
+	zone_merge_all();
+
+	/* Initialize output device. */
+	machine_output_init();
+}
+
+/** Perform ARM64 specific tasks needed after the multiprocessing is
+ * initialized.
+ */
+void arm64_post_smp_init(void)
+{
+	/* Set platform name. */
+	const char *platform = machine_get_platform_name();
+
+	sysinfo_set_item_data("platform", NULL, (void *) platform,
+	    str_size(platform));
+
+	/* Initialize input device. */
+	machine_input_init();
+}
+
+/** Calibrate delay loop.
+ *
+ * On ARM64, we implement delay() by waiting for the CNTVCT_EL0 register to
+ * reach a pre-computed value, as opposed to performing some pre-computed amount
+ * of instructions of known duration. We set the delay_loop_const to 1 in order
+ * to neutralize the multiplication done by delay().
+ */
+void calibrate_delay_loop(void)
+{
+	CPU->delay_loop_const = 1;
+}
+
+/** Wait several microseconds.
+ *
+ * @param t Microseconds to wait.
+ */
+void asm_delay_loop(uint32_t usec)
+{
+	uint64_t stop = CNTVCT_EL0_read() + usec * CNTFRQ_EL0_read() / 1000000;
+
+	while (CNTVCT_EL0_read() < stop)
+		;
+}
+
+/** Change processor mode.
+ *
+ * @param kernel_uarg Userspace settings (entry point, stack, ...).
+ */
+void userspace(uspace_arg_t *kernel_uarg)
+{
+	/* Prepare return to EL0. */
+	SPSR_EL1_write((SPSR_EL1_read() & ~SPSR_MODE_MASK) |
+	    SPSR_MODE_ARM64_EL0T);
+
+	/* Set program entry. */
+	ELR_EL1_write((uint64_t) kernel_uarg->uspace_entry);
+
+	/* Set user stack. */
+	SP_EL0_write(((uint64_t) kernel_uarg->uspace_stack +
+	    kernel_uarg->uspace_stack_size));
+
+	/* Clear Thread ID register. */
+	TPIDR_EL0_write(0);
+
+	asm volatile (
+	    /*
+	     * Clear all general-purpose registers, except x0 that holds an
+	     * argument for the user space.
+	     */
+	    "mov x0, %[uspace_uarg]\n"
+	    "mov x1, #0\n"
+	    "mov x2, #0\n"
+	    "mov x3, #0\n"
+	    "mov x4, #0\n"
+	    "mov x5, #0\n"
+	    "mov x6, #0\n"
+	    "mov x7, #0\n"
+	    "mov x8, #0\n"
+	    "mov x9, #0\n"
+	    "mov x10, #0\n"
+	    "mov x11, #0\n"
+	    "mov x12, #0\n"
+	    "mov x13, #0\n"
+	    "mov x14, #0\n"
+	    "mov x15, #0\n"
+	    "mov x16, #0\n"
+	    "mov x17, #0\n"
+	    "mov x18, #0\n"
+	    "mov x19, #0\n"
+	    "mov x20, #0\n"
+	    "mov x21, #0\n"
+	    "mov x22, #0\n"
+	    "mov x23, #0\n"
+	    "mov x24, #0\n"
+	    "mov x25, #0\n"
+	    "mov x26, #0\n"
+	    "mov x27, #0\n"
+	    "mov x28, #0\n"
+	    "mov x29, #0\n"
+	    "mov x30, #0\n"
+	    "eret\n"
+	    :: [uspace_uarg] "r" (kernel_uarg->uspace_uarg)
+	);
+
+	unreachable();
+}
+
+/** Perform ARM64 specific tasks needed before the new task is run. */
+void before_task_runs_arch(void)
+{
+}
+
+/** Perform ARM64 specific tasks needed before the new thread is scheduled.
+ */
+void before_thread_runs_arch(void)
+{
+}
+
+/** Perform ARM64 specific tasks before a thread stops running. */
+void after_thread_ran_arch(void)
+{
+}
+
+/** Reboot the system. */
+void arch_reboot(void)
+{
+	/* Not implemented. */
+	while (true)
+		;
+}
+
+/** 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;
+}
+
+/** Perform ARM64 specific tasks to initialize IRQ processing. */
+void irq_initialize_arch(irq_t *irq __attribute__((unused)))
+{
+}
+
+/** @}
+ */
Index: kernel/arch/arm64/src/asm.S
===================================================================
--- kernel/arch/arm64/src/asm.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/src/asm.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 <abi/asmtool.h>
+#include <arch/exception.h>
+#include <arch/istate_struct.h>
+
+.text
+
+FUNCTION_BEGIN(memcpy_from_uspace)
+FUNCTION_BEGIN(memcpy_to_uspace)
+	/* Simple (un-optimized) memcpy(). */
+	cbz x2, 2f
+	mov x3, x0
+1:
+	ldrb w4, [x1], #1
+	strb w4, [x3], #1
+	subs x2, x2, #1
+	b.ne 1b
+
+2:
+	ret
+FUNCTION_END(memcpy_from_uspace)
+FUNCTION_END(memcpy_to_uspace)
+
+FUNCTION_BEGIN(memcpy_from_uspace_failover_address)
+FUNCTION_BEGIN(memcpy_to_uspace_failover_address)
+	mov x0, #0
+	ret
+FUNCTION_END(memcpy_from_uspace_failover_address)
+FUNCTION_END(memcpy_to_uspace_failover_address)
+
+FUNCTION_BEGIN(early_putwchar)
+	ret
+FUNCTION_END(early_putwchar)
+
+/* Static checks for the istate_t save/load. */
+#if ISTATE_OFFSET_X0 + 8 != ISTATE_OFFSET_X1
+#error x0 and x1 are not successive in istate_t
+#endif
+#if ISTATE_OFFSET_X2 + 8 != ISTATE_OFFSET_X3
+#error x2 and x3 are not successive in istate_t
+#endif
+#if ISTATE_OFFSET_X4 + 8 != ISTATE_OFFSET_X5
+#error x4 and x5 are not successive in istate_t
+#endif
+#if ISTATE_OFFSET_X6 + 8 != ISTATE_OFFSET_X7
+#error x6 and x7 are not successive in istate_t
+#endif
+#if ISTATE_OFFSET_X8 + 8 != ISTATE_OFFSET_X9
+#error x8 and x9 are not successive in istate_t
+#endif
+#if ISTATE_OFFSET_X10 + 8 != ISTATE_OFFSET_X11
+#error x10 and x11 are not successive in istate_t
+#endif
+#if ISTATE_OFFSET_X12 + 8 != ISTATE_OFFSET_X13
+#error x12 and x13 are not successive in istate_t
+#endif
+#if ISTATE_OFFSET_X14 + 8 != ISTATE_OFFSET_X15
+#error x14 and x15 are not successive in istate_t
+#endif
+#if ISTATE_OFFSET_X16 + 8 != ISTATE_OFFSET_X17
+#error x16 and x17 are not successive in istate_t
+#endif
+#if ISTATE_OFFSET_X18 + 8 != ISTATE_OFFSET_X19
+#error x18 and x19 are not successive in istate_t
+#endif
+#if ISTATE_OFFSET_X20 + 8 != ISTATE_OFFSET_X21
+#error x20 and x21 are not successive in istate_t
+#endif
+#if ISTATE_OFFSET_X22 + 8 != ISTATE_OFFSET_X23
+#error x22 and x23 are not successive in istate_t
+#endif
+#if ISTATE_OFFSET_X24 + 8 != ISTATE_OFFSET_X25
+#error x24 and x25 are not successive in istate_t
+#endif
+#if ISTATE_OFFSET_X26 + 8 != ISTATE_OFFSET_X27
+#error x26 and x27 are not successive in istate_t
+#endif
+#if ISTATE_OFFSET_X28 + 8 != ISTATE_OFFSET_X29
+#error x28 and x29 are not successive in istate_t
+#endif
+#if ISTATE_OFFSET_SPSR + 8 != ISTATE_OFFSET_SP
+#error spsr and sp are not successive in istate_t
+#endif
+#if ISTATE_OFFSET_PC + 8 != ISTATE_OFFSET_TPIDR
+#error pc and tpidr are not successive in istate_t
+#endif
+
+/* Exception vector. */
+.macro handler i
+handler_\i:
+	/*
+	 * Initial code for each handler, at maximum 128 bytes (32
+	 * instructions).
+	 */
+
+	/* Save current state. */
+	sub sp, sp, #ISTATE_SIZE                /* 0x00 */
+	stp x0, x1, [sp, #ISTATE_OFFSET_X0]     /* 0x04 */
+	stp x2, x3, [sp, #ISTATE_OFFSET_X2]     /* 0x08 */
+	stp x4, x5, [sp, #ISTATE_OFFSET_X4]     /* 0x0c */
+	stp x6, x7, [sp, #ISTATE_OFFSET_X6]     /* 0x10 */
+	stp x8, x9, [sp, #ISTATE_OFFSET_X8]     /* 0x14 */
+	stp x10, x11, [sp, #ISTATE_OFFSET_X10]  /* 0x18 */
+	stp x12, x13, [sp, #ISTATE_OFFSET_X12]  /* 0x1c */
+	stp x14, x15, [sp, #ISTATE_OFFSET_X14]  /* 0x20 */
+	stp x16, x17, [sp, #ISTATE_OFFSET_X16]  /* 0x24 */
+	stp x18, x19, [sp, #ISTATE_OFFSET_X18]  /* 0x28 */
+	stp x20, x21, [sp, #ISTATE_OFFSET_X20]  /* 0x2c */
+	stp x22, x23, [sp, #ISTATE_OFFSET_X22]  /* 0x30 */
+	stp x24, x25, [sp, #ISTATE_OFFSET_X24]  /* 0x34 */
+	stp x26, x27, [sp, #ISTATE_OFFSET_X26]  /* 0x38 */
+	stp x28, x29, [sp, #ISTATE_OFFSET_X28]  /* 0x3c */
+	str x30, [sp, #ISTATE_OFFSET_X30]       /* 0x40 */
+
+	mrs x0, spsr_el1                        /* 0x44 */
+	mrs x1, sp_el0                          /* 0x48 */
+	stp x0, x1, [sp, #ISTATE_OFFSET_SPSR]   /* 0x4c */
+
+	mrs x0, elr_el1                         /* 0x50 */
+	mrs x1, tpidr_el0                       /* 0x54 */
+	stp x0, x1, [sp, #ISTATE_OFFSET_PC]     /* 0x58 */
+
+	mov x0, #\i                             /* 0x5c */
+	mov x1, sp                              /* 0x60 */
+	bl exc_dispatch                         /* 0x64 */
+
+	/* Restore previous state. */
+	ldp x0, x1, [sp, #ISTATE_OFFSET_SPSR]   /* 0x68 */
+	msr spsr_el1, x0                        /* 0x6c */
+	msr sp_el0, x1                          /* 0x70 */
+
+	ldp x0, x1, [sp, #ISTATE_OFFSET_PC]     /* 0x74 */
+	msr elr_el1, x0                         /* 0x78 */
+	b exc_restore_end                       /* 0x7c */
+.endm
+
+exc_restore_end:
+	/* Restore remaining registers and return from the exception handler. */
+	msr tpidr_el0, x1
+	ldp x0, x1, [sp, #ISTATE_OFFSET_X0]
+	ldp x2, x3, [sp, #ISTATE_OFFSET_X2]
+	ldp x4, x5, [sp, #ISTATE_OFFSET_X4]
+	ldp x6, x7, [sp, #ISTATE_OFFSET_X6]
+	ldp x8, x9, [sp, #ISTATE_OFFSET_X8]
+	ldp x10, x11, [sp, #ISTATE_OFFSET_X10]
+	ldp x12, x13, [sp, #ISTATE_OFFSET_X12]
+	ldp x14, x15, [sp, #ISTATE_OFFSET_X14]
+	ldp x16, x17, [sp, #ISTATE_OFFSET_X16]
+	ldp x18, x19, [sp, #ISTATE_OFFSET_X18]
+	ldp x20, x21, [sp, #ISTATE_OFFSET_X20]
+	ldp x22, x23, [sp, #ISTATE_OFFSET_X22]
+	ldp x24, x25, [sp, #ISTATE_OFFSET_X24]
+	ldp x26, x27, [sp, #ISTATE_OFFSET_X26]
+	ldp x28, x29, [sp, #ISTATE_OFFSET_X28]
+	ldr x30, [sp, #ISTATE_OFFSET_X30]
+	add sp, sp, #ISTATE_SIZE
+	eret
+
+.align 11
+SYMBOL(exc_vector)
+.org exc_vector + 0x000
+	handler EXC_CURRENT_EL_SP_SEL0_SYNCH
+.org exc_vector + 0x080
+	handler EXC_CURRENT_EL_SP_SEL0_IRQ
+.org exc_vector + 0x100
+	handler EXC_CURRENT_EL_SP_SEL0_FIQ
+.org exc_vector + 0x180
+	handler EXC_CURRENT_EL_SP_SEL0_SERROR
+.org exc_vector + 0x200
+	handler EXC_CURRENT_EL_SP_SELX_SYNCH
+.org exc_vector + 0x280
+	handler EXC_CURRENT_EL_SP_SELX_IRQ
+.org exc_vector + 0x300
+	handler EXC_CURRENT_EL_SP_SELX_FIQ
+.org exc_vector + 0x380
+	handler EXC_CURRENT_EL_SP_SELX_SERROR
+.org exc_vector + 0x400
+	handler EXC_LOWER_EL_AARCH64_SYNCH
+.org exc_vector + 0x480
+	handler EXC_LOWER_EL_AARCH64_IRQ
+.org exc_vector + 0x500
+	handler EXC_LOWER_EL_AARCH64_FIQ
+.org exc_vector + 0x580
+	handler EXC_LOWER_EL_AARCH64_SERROR
+.org exc_vector + 0x600
+	handler EXC_LOWER_EL_AARCH32_SYNCH
+.org exc_vector + 0x680
+	handler EXC_LOWER_EL_AARCH32_IRQ
+.org exc_vector + 0x700
+	handler EXC_LOWER_EL_AARCH32_FIQ
+.org exc_vector + 0x780
+	handler EXC_LOWER_EL_AARCH32_SERROR
+.org exc_vector + 0x800
Index: kernel/arch/arm64/src/context.S
===================================================================
--- kernel/arch/arm64/src/context.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/src/context.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 <abi/asmtool.h>
+#include <arch/context_struct.h>
+
+.text
+
+/* Static checks for the context_t save/load. */
+#if CONTEXT_OFFSET_SP + 8 != CONTEXT_OFFSET_PC
+#error sp and pc are not successive in context_t
+#endif
+#if CONTEXT_OFFSET_X19 + 8 != CONTEXT_OFFSET_X20
+#error x19 and x20 are not successive in context_t
+#endif
+#if CONTEXT_OFFSET_X21 + 8 != CONTEXT_OFFSET_X22
+#error x21 and x22 are not successive in context_t
+#endif
+#if CONTEXT_OFFSET_X23 + 8 != CONTEXT_OFFSET_X24
+#error x23 and x24 are not successive in context_t
+#endif
+#if CONTEXT_OFFSET_X25 + 8 != CONTEXT_OFFSET_X26
+#error x25 and x26 are not successive in context_t
+#endif
+#if CONTEXT_OFFSET_X27 + 8 != CONTEXT_OFFSET_X28
+#error x27 and x28 are not successive in context_t
+#endif
+
+FUNCTION_BEGIN(context_save_arch)
+	/* Save callee-saved registers into context_t pointed by x0. */
+	mov x1, sp
+	stp x1, x30, [x0, #CONTEXT_OFFSET_SP]
+	stp x19, x20, [x0, #CONTEXT_OFFSET_X19]
+	stp x21, x22, [x0, #CONTEXT_OFFSET_X21]
+	stp x23, x24, [x0, #CONTEXT_OFFSET_X23]
+	stp x25, x26, [x0, #CONTEXT_OFFSET_X25]
+	stp x27, x28, [x0, #CONTEXT_OFFSET_X27]
+	str x29, [x0, #CONTEXT_OFFSET_X29]
+
+	/* Return 1. */
+	mov x0, #1
+	ret
+FUNCTION_END(context_save_arch)
+
+FUNCTION_BEGIN(context_restore_arch)
+	/* Restore callee-saved registers from context_t pointed by x0. */
+	ldp x1, x30, [x0, #CONTEXT_OFFSET_SP]
+	mov sp, x1
+	ldp x19, x20, [x0, #CONTEXT_OFFSET_X19]
+	ldp x21, x22, [x0, #CONTEXT_OFFSET_X21]
+	ldp x23, x24, [x0, #CONTEXT_OFFSET_X23]
+	ldp x25, x26, [x0, #CONTEXT_OFFSET_X25]
+	ldp x27, x28, [x0, #CONTEXT_OFFSET_X27]
+	ldr x29, [x0, #CONTEXT_OFFSET_X29]
+
+	/* Return 0. */
+	mov x0, #0
+	ret
+FUNCTION_END(context_restore_arch)
Index: kernel/arch/arm64/src/cpu/cpu.c
===================================================================
--- kernel/arch/arm64/src/cpu/cpu.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/src/cpu/cpu.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ * @brief CPU identification.
+ */
+
+#include <arch/regutils.h>
+#include <cpu.h>
+#include <typedefs.h>
+
+/** Decode implementer (vendor) name. */
+static const char *implementer(uint32_t id)
+{
+	switch (id) {
+	case 0x41:
+		return "ARM Limited";
+	case 0x42:
+		return "Broadcom Corporation";
+	case 0x43:
+		return "Cavium Inc.";
+	case 0x44:
+		return "Digital Equipment Corporation";
+	case 0x49:
+		return "Infineon Technologies AG";
+	case 0x4d:
+		return "Motorola or Freescale Semiconductor Inc.";
+	case 0x4e:
+		return "NVIDIA Corporation";
+	case 0x50:
+		return "Applied Micro Circuits Corporation";
+	case 0x51:
+		return "Qualcomm Inc.";
+	case 0x56:
+		return "Marvell International Ltd.";
+	case 0x69:
+		return "Intel Corporation";
+	}
+	return "Unknown implementer";
+}
+
+/** Perform ARM64-specific tasks needed for CPU initialization. */
+void cpu_arch_init(void)
+{
+}
+
+/** Retrieve processor identification and stores it to #CPU.arch */
+void cpu_identify(void)
+{
+	uint64_t midr = MIDR_EL1_read();
+
+	CPU->arch.implementer =
+	    (midr & MIDR_IMPLEMENTER_MASK) >> MIDR_IMPLEMENTER_SHIFT;
+	CPU->arch.variant = (midr & MIDR_VARIANT_MASK) >> MIDR_VARIANT_SHIFT;
+	CPU->arch.partnum = (midr & MIDR_PARTNUM_MASK) >> MIDR_PARTNUM_SHIFT;
+	CPU->arch.revision = (midr & MIDR_REVISION_MASK) >> MIDR_REVISION_SHIFT;
+}
+
+/** Print CPU identification. */
+void cpu_print_report(cpu_t *m)
+{
+	printf("cpu%d: vendor=%s, variant=%" PRIx32 ", part number=%" PRIx32
+	    ", revision=%" PRIx32 "\n",
+	    m->id, implementer(m->arch.implementer), m->arch.variant,
+	    m->arch.partnum, m->arch.revision);
+}
+
+/** @}
+ */
Index: kernel/arch/arm64/src/debug/stacktrace.c
===================================================================
--- kernel/arch/arm64/src/debug/stacktrace.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/src/debug/stacktrace.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ */
+
+#include <stacktrace.h>
+#include <syscall/copy.h>
+#include <typedefs.h>
+
+#define FRAME_OFFSET_FP_PREV  0
+#define FRAME_OFFSET_RA       1
+
+bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx)
+{
+	return ctx->fp != 0;
+}
+
+bool kernel_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
+{
+	uint64_t *stack = (void *) ctx->fp;
+
+	*prev = stack[FRAME_OFFSET_FP_PREV];
+	return true;
+}
+
+bool kernel_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
+{
+	uint64_t *stack = (void *) ctx->fp;
+
+	*ra = stack[FRAME_OFFSET_RA];
+	return true;
+}
+
+bool uspace_stack_trace_context_validate(stack_trace_context_t *ctx)
+{
+	return ctx->fp != 0;
+}
+
+bool uspace_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
+{
+	return !copy_from_uspace((void *) prev,
+	    (uint64_t *) ctx->fp + FRAME_OFFSET_FP_PREV, sizeof(*prev));
+}
+
+bool uspace_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
+{
+	return !copy_from_uspace((void *) ra,
+	    (uint64_t *) ctx->fp + FRAME_OFFSET_RA, sizeof(*ra));
+}
+
+/** @}
+ */
Index: kernel/arch/arm64/src/debug/stacktrace_asm.S
===================================================================
--- kernel/arch/arm64/src/debug/stacktrace_asm.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/src/debug/stacktrace_asm.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 <abi/asmtool.h>
+
+.text
+
+FUNCTION_BEGIN(frame_pointer_get)
+	mov x0, x29
+	ret
+FUNCTION_END(frame_pointer_get)
+
+FUNCTION_BEGIN(program_counter_get)
+	mov x0, x30
+	ret
+FUNCTION_END(program_counter_get)
Index: kernel/arch/arm64/src/exception.c
===================================================================
--- kernel/arch/arm64/src/exception.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/src/exception.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ * @brief Exception handlers and exception initialization routines.
+ */
+
+#include <arch/asm.h>
+#include <arch/exception.h>
+#include <arch/machine_func.h>
+#include <arch/regutils.h>
+#include <interrupt.h>
+#include <mm/as.h>
+#include <stdio.h>
+#include <syscall/syscall.h>
+
+static void current_el_sp_sel0_synch_exception(unsigned int exc_no,
+    istate_t *istate)
+{
+	panic_badtrap(istate, exc_no, "Unhandled exception from Current EL, "
+	    "SP_SEL0, Synch, ESR_EL1=%0#10" PRIx32 ", FAR_EL1=%0#18" PRIx64 ".",
+	    (uint32_t) ESR_EL1_read(), FAR_EL1_read());
+}
+
+static void current_el_sp_sel0_irq_exception(unsigned int exc_no,
+    istate_t *istate)
+{
+	panic_badtrap(istate, exc_no, "Unhandled exception from Current EL, "
+	    "SP_SEL0, IRQ, ESR_EL1=%0#10" PRIx32 ", FAR_EL1=%0#18" PRIx64 ".",
+	    (uint32_t) ESR_EL1_read(), FAR_EL1_read());
+}
+
+static void current_el_sp_sel0_fiq_exception(unsigned int exc_no,
+    istate_t *istate)
+{
+	panic_badtrap(istate, exc_no, "Unhandled exception from Current EL, "
+	    "SP_SEL0, FIQ, ESR_EL1=%0#10" PRIx32 ", FAR_EL1=%0#18" PRIx64 ".",
+	    (uint32_t) ESR_EL1_read(), FAR_EL1_read());
+}
+
+static void current_el_sp_sel0_serror_exception(unsigned int exc_no,
+    istate_t *istate)
+{
+	panic_badtrap(istate, exc_no, "Unhandled exception from Current EL, "
+	    "SP_SEL0, SError, ESR_EL1=%0#10" PRIx32 ", FAR_EL1=%0#18" PRIx64
+	    ".", (uint32_t) ESR_EL1_read(), FAR_EL1_read());
+}
+
+static void current_el_sp_selx_synch_exception(unsigned int exc_no,
+    istate_t *istate)
+{
+	uint64_t esr_el1 = ESR_EL1_read();
+	uint64_t far_el1 = FAR_EL1_read();
+	pf_access_t access;
+
+	switch ((esr_el1 & ESR_EC_MASK) >> ESR_EC_SHIFT) {
+	case ESR_EC_DA_CURRENT_EL:
+		/* Data abort. */
+		switch ((esr_el1 & ESR_IDFSC_MASK) >> ESR_IDFSC_SHIFT) {
+		case ESR_IDA_IDFSC_TF0:
+		case ESR_IDA_IDFSC_TF1:
+		case ESR_IDA_IDFSC_TF2:
+		case ESR_IDA_IDFSC_TF3:
+			/* Translation fault. */
+			access = (esr_el1 & ESR_DA_WNR_FLAG) ? PF_ACCESS_WRITE :
+			    PF_ACCESS_READ;
+			as_page_fault(far_el1, access, istate);
+			return;
+		}
+	}
+
+	panic_badtrap(istate, exc_no, "Unhandled exception from Current EL, "
+	    "SP_SELx, Synch, ESR_EL1=%0#10" PRIx32 ", FAR_EL1=%0#18" PRIx64 ".",
+	    (uint32_t) ESR_EL1_read(), FAR_EL1_read());
+}
+
+static void current_el_sp_selx_irq_exception(unsigned int exc_no,
+    istate_t *istate)
+{
+	machine_irq_exception(exc_no, istate);
+}
+
+static void current_el_sp_selx_fiq_exception(unsigned int exc_no,
+    istate_t *istate)
+{
+	panic_badtrap(istate, exc_no, "Unhandled exception from Current EL, "
+	    "SP_SELx, FIQ, ESR_EL1=%0#10" PRIx32 ", FAR_EL1=%0#18" PRIx64 ".",
+	    (uint32_t) ESR_EL1_read(), FAR_EL1_read());
+}
+
+static void current_el_sp_selx_serror_exception(unsigned int exc_no,
+    istate_t *istate)
+{
+	panic_badtrap(istate, exc_no, "Unhandled exception from Current EL, "
+	    "SP_SELx, SError, ESR_EL1=%0#10" PRIx32 ", FAR_EL1=%0#18" PRIx64
+	    ".", (uint32_t) ESR_EL1_read(), FAR_EL1_read());
+}
+
+static void lower_el_aarch64_synch_exception(unsigned int exc_no,
+    istate_t *istate)
+{
+	uint64_t esr_el1 = ESR_EL1_read();
+	uint64_t far_el1 = FAR_EL1_read();
+	pf_access_t access;
+	bool exec = false;
+
+	switch ((esr_el1 & ESR_EC_MASK) >> ESR_EC_SHIFT) {
+	case ESR_EC_FP:
+		/* Access to Advanced SIMD or floating-point functionality. */
+#ifdef CONFIG_FPU_LAZY
+		scheduler_fpu_lazy_request();
+#else
+		fault_from_uspace(istate, "AdvSIMD/FP fault.");
+#endif
+		return;
+	case ESR_EC_SVC:
+		/* SVC instruction. */
+		interrupts_enable();
+		istate->x0 = syscall_handler(istate->x0, istate->x1, istate->x2,
+		    istate->x3, istate->x4, istate->x5, istate->x6);
+		interrupts_disable();
+		return;
+	case ESR_EC_IA_LOWER_EL:
+		/* Instruction abort. */
+		exec = true;
+		/* Fallthrough */
+	case ESR_EC_DA_LOWER_EL:
+		/* Data abort. */
+		switch ((esr_el1 & ESR_IDFSC_MASK) >> ESR_IDFSC_SHIFT) {
+		case ESR_IDA_IDFSC_TF0:
+		case ESR_IDA_IDFSC_TF1:
+		case ESR_IDA_IDFSC_TF2:
+		case ESR_IDA_IDFSC_TF3:
+			/* Translation fault. */
+			if (exec)
+				access = PF_ACCESS_EXEC;
+			else
+				access = (esr_el1 & ESR_DA_WNR_FLAG) ?
+				    PF_ACCESS_WRITE : PF_ACCESS_READ;
+			as_page_fault(far_el1, access, istate);
+			return;
+		}
+	}
+
+	fault_from_uspace(istate, "Unhandled exception from Lower EL, AArch64, "
+	    "Synch, ESR_EL1=%0#10" PRIx32 ", FAR_EL1=%0#18" PRIx64 ".",
+	    (uint32_t) esr_el1, far_el1);
+}
+
+static void lower_el_aarch64_irq_exception(unsigned int exc_no,
+    istate_t *istate)
+{
+	machine_irq_exception(exc_no, istate);
+}
+
+static void lower_el_aarch64_fiq_exception(unsigned int exc_no,
+    istate_t *istate)
+{
+	fault_from_uspace(istate, "Unhandled exception from Lower EL, AArch64, "
+	    "FIQ, ESR_EL1=%0#10" PRIx32 ", FAR_EL1=%0#18" PRIx64 ".",
+	    (uint32_t) ESR_EL1_read(), FAR_EL1_read());
+}
+
+static void lower_el_aarch64_serror_exception(unsigned int exc_no,
+    istate_t *istate)
+{
+	fault_from_uspace(istate, "Unhandled exception from Lower EL, AArch64, "
+	    "SError, ESR_EL1=%0#10" PRIx32 ", FAR_EL1=%0#18" PRIx64 ".",
+	    (uint32_t) ESR_EL1_read(), FAR_EL1_read());
+}
+
+static void lower_el_aarch32_synch_exception(unsigned int exc_no,
+    istate_t *istate)
+{
+	fault_from_uspace(istate, "Unhandled exception from Lower EL, AArch32, "
+	    "Synch, ESR_EL1=%0#10" PRIx32 ", FAR_EL1=%0#18" PRIx64 ".",
+	    (uint32_t) ESR_EL1_read(), FAR_EL1_read());
+}
+
+static void lower_el_aarch32_irq_exception(unsigned int exc_no,
+    istate_t *istate)
+{
+	fault_from_uspace(istate, "Unhandled exception from Lower EL, AArch32, "
+	    "IRQ, ESR_EL1=%0#10" PRIx32 ", FAR_EL1=%0#18" PRIx64 ".",
+	    (uint32_t) ESR_EL1_read(), FAR_EL1_read());
+}
+
+static void lower_el_aarch32_fiq_exception(unsigned int exc_no,
+    istate_t *istate)
+{
+	fault_from_uspace(istate, "Unhandled exception from Lower EL, AArch32, "
+	    "FIQ, ESR_EL1=%0#10" PRIx32 ", FAR_EL1=%0#18" PRIx64 ".",
+	    (uint32_t) ESR_EL1_read(), FAR_EL1_read());
+}
+
+static void lower_el_aarch32_serror_exception(unsigned int exc_no,
+    istate_t *istate)
+{
+	fault_from_uspace(istate, "Unhandled exception from Lower EL, AArch32, "
+	    "SError, ESR_EL1=%0#10" PRIx32 ", FAR_EL1=%0#18" PRIx64 ".",
+	    (uint32_t) ESR_EL1_read(), FAR_EL1_read());
+}
+
+/** Initializes exception handling.
+ *
+ * Installs low-level exception handlers and then registers exceptions and their
+ * handlers to kernel exception dispatcher.
+ */
+void exception_init(void)
+{
+	exc_register(EXC_CURRENT_EL_SP_SEL0_SYNCH,
+	    "current EL, SP_SEL0, Synchronous", true,
+	    (iroutine_t) current_el_sp_sel0_synch_exception);
+	exc_register(EXC_CURRENT_EL_SP_SEL0_IRQ,
+	    "current EL, SP_SEL0, IRQ", true,
+	    (iroutine_t) current_el_sp_sel0_irq_exception);
+	exc_register(EXC_CURRENT_EL_SP_SEL0_FIQ,
+	    "current EL, SP_SEL0, FIQ", true,
+	    (iroutine_t) current_el_sp_sel0_fiq_exception);
+	exc_register(EXC_CURRENT_EL_SP_SEL0_SERROR,
+	    "current EL, SP_SEL0, SError", true,
+	    (iroutine_t) current_el_sp_sel0_serror_exception);
+	exc_register(EXC_CURRENT_EL_SP_SELX_SYNCH,
+	    "current EL, SP_SELx, Synchronous", true,
+	    (iroutine_t) current_el_sp_selx_synch_exception);
+	exc_register(EXC_CURRENT_EL_SP_SELX_IRQ,
+	    "current EL, SP_SELx, IRQ", true,
+	    (iroutine_t) current_el_sp_selx_irq_exception);
+	exc_register(EXC_CURRENT_EL_SP_SELX_FIQ,
+	    "current EL, SP_SELx, FIQ", true,
+	    (iroutine_t) current_el_sp_selx_fiq_exception);
+	exc_register(EXC_CURRENT_EL_SP_SELX_SERROR,
+	    "current EL, SP_SELx, SError", true,
+	    (iroutine_t) current_el_sp_selx_serror_exception);
+	exc_register(EXC_LOWER_EL_AARCH64_SYNCH,
+	    "lower EL, AArch64, Synchronous", true,
+	    (iroutine_t) lower_el_aarch64_synch_exception);
+	exc_register(EXC_LOWER_EL_AARCH64_IRQ,
+	    "lower EL, AArch64, IRQ", true,
+	    (iroutine_t) lower_el_aarch64_irq_exception);
+	exc_register(EXC_LOWER_EL_AARCH64_FIQ,
+	    "lower EL, AArch64, FIQ", true,
+	    (iroutine_t) lower_el_aarch64_fiq_exception);
+	exc_register(EXC_LOWER_EL_AARCH64_SERROR,
+	    "lower EL, AArch64, SError", true,
+	    (iroutine_t) lower_el_aarch64_serror_exception);
+	exc_register(EXC_LOWER_EL_AARCH32_SYNCH,
+	    "lower EL, AArch32, Synchronous", true,
+	    (iroutine_t) lower_el_aarch32_synch_exception);
+	exc_register(EXC_LOWER_EL_AARCH32_IRQ,
+	    "lower EL, AArch32, IRQ", true,
+	    (iroutine_t) lower_el_aarch32_irq_exception);
+	exc_register(EXC_LOWER_EL_AARCH32_FIQ,
+	    "lower EL, AArch32, FIQ", true,
+	    (iroutine_t) lower_el_aarch32_fiq_exception);
+	exc_register(EXC_LOWER_EL_AARCH32_SERROR,
+	    "lower EL, AArch32, SError", true,
+	    (iroutine_t) lower_el_aarch32_serror_exception);
+
+	VBAR_EL1_write(((uint64_t) &exc_vector));
+}
+
+/** Print #istate_t structure content.
+ *
+ * @param istate Structure to be printed.
+ */
+void istate_decode(istate_t *istate)
+{
+	printf("x0 =%0#18" PRIx64 "\tx1 =%0#18" PRIx64 "\t"
+	    "x2 =%0#18" PRIx64 "\n", istate->x0, istate->x1, istate->x2);
+	printf("x3 =%0#18" PRIx64 "\tx4 =%0#18" PRIx64 "\t"
+	    "x5 =%0#18" PRIx64 "\n", istate->x3, istate->x4, istate->x5);
+	printf("x6 =%0#18" PRIx64 "\tx7 =%0#18" PRIx64 "\t"
+	    "x8 =%0#18" PRIx64 "\n", istate->x6, istate->x7, istate->x8);
+	printf("x9 =%0#18" PRIx64 "\tx10=%0#18" PRIx64 "\t"
+	    "x11=%0#18" PRIx64 "\n", istate->x9, istate->x10, istate->x11);
+	printf("x12=%0#18" PRIx64 "\tx13=%0#18" PRIx64 "\t"
+	    "x14=%0#18" PRIx64 "\n", istate->x12, istate->x13, istate->x14);
+	printf("x15=%0#18" PRIx64 "\tx16=%0#18" PRIx64 "\t"
+	    "x17=%0#18" PRIx64 "\n", istate->x15, istate->x16, istate->x17);
+	printf("x18=%0#18" PRIx64 "\tx19=%0#18" PRIx64 "\t"
+	    "x20=%0#18" PRIx64 "\n", istate->x18, istate->x19, istate->x20);
+	printf("x21=%0#18" PRIx64 "\tx22=%0#18" PRIx64 "\t"
+	    "x23=%0#18" PRIx64 "\n", istate->x21, istate->x22, istate->x23);
+	printf("x24=%0#18" PRIx64 "\tx25=%0#18" PRIx64 "\t"
+	    "x26=%0#18" PRIx64 "\n", istate->x24, istate->x25, istate->x26);
+	printf("x27=%0#18" PRIx64 "\tx28=%0#18" PRIx64 "\t"
+	    "x29=%0#18" PRIx64 "\n", istate->x27, istate->x28, istate->x29);
+	printf("x30=%0#18" PRIx64 "\tsp =%0#18" PRIx64 "\t"
+	    "pc =%0#18" PRIx64 "\n", istate->x30, istate->sp, istate->pc);
+	printf("spsr=%0#18" PRIx64 "\ttpidr=%0#18" PRIx64 "\n", istate->spsr,
+	    istate->tpidr);
+}
+
+/** @}
+ */
Index: kernel/arch/arm64/src/fpu.S
===================================================================
--- kernel/arch/arm64/src/fpu.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/src/fpu.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2018 Petr Pavlu
+ * 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 <abi/asmtool.h>
+#include <arch/fpu_context_struct.h>
+
+.text
+
+FUNCTION_BEGIN(fpu_context_save)
+	/* Save FPU registers into fpu_context_t pointed by x0. */
+	stp q0, q1, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 0]
+	stp q2, q3, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 2]
+	stp q4, q5, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 4]
+	stp q6, q7, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 6]
+	stp q8, q9, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 8]
+	stp q10, q11, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 10]
+	stp q12, q13, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 12]
+	stp q14, q15, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 14]
+	stp q16, q17, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 16]
+	stp q18, q19, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 18]
+	stp q20, q21, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 20]
+	stp q22, q23, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 22]
+	stp q24, q25, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 24]
+	stp q26, q27, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 26]
+	stp q28, q29, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 28]
+	stp q30, q31, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 30]
+	mrs x1, fpcr
+	str w1, [x0, #FPU_CONTEXT_OFFSET_FPCR]
+	mrs x1, fpsr
+	str w1, [x0, #FPU_CONTEXT_OFFSET_FPSR]
+	ret
+FUNCTION_END(fpu_context_save)
+
+FUNCTION_BEGIN(fpu_context_restore)
+	/* Restore FPU registers from fpu_context_t pointed by x0. */
+	ldp q0, q1, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 0]
+	ldp q2, q3, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 2]
+	ldp q4, q5, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 4]
+	ldp q6, q7, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 6]
+	ldp q8, q9, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 8]
+	ldp q10, q11, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 10]
+	ldp q12, q13, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 12]
+	ldp q14, q15, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 14]
+	ldp q16, q17, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 16]
+	ldp q18, q19, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 18]
+	ldp q20, q21, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 20]
+	ldp q22, q23, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 22]
+	ldp q24, q25, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 24]
+	ldp q26, q27, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 26]
+	ldp q28, q29, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 28]
+	ldp q30, q31, [x0, #FPU_CONTEXT_OFFSET_VREGS + 16 * 30]
+	ldr w1, [x0, #FPU_CONTEXT_OFFSET_FPCR]
+	msr fpcr, x1
+	ldr w1, [x0, #FPU_CONTEXT_OFFSET_FPSR]
+	msr fpsr, x1
+	ret
+FUNCTION_END(fpu_context_restore)
Index: kernel/arch/arm64/src/fpu_context.c
===================================================================
--- kernel/arch/arm64/src/fpu_context.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/src/fpu_context.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ * @brief ARM64 FPU context.
+ */
+
+#include <arch/regutils.h>
+#include <fpu_context.h>
+
+/** Initialize FPU functionality. */
+void fpu_init(void)
+{
+	/*
+	 * Set initial FPU state:
+	 * o Registers v0-v31 are cleared.
+	 * o FPCR value:
+	 *   [31:27] - Reserved 0.
+	 *   [26]    - AHP=0, IEEE half-precision format selected.
+	 *   [25]    - DN=0, NaN operands propagate through to the output of a
+	 *             floating-point operation.
+	 *   [24]    - FZ=0, flush-to-zero mode disabled.
+	 *   [23:22] - RMode=00, round to nearest mode.
+	 *   [21:20] - Stride=00, this field has no function in AArch64 state.
+	 *   [19]    - FZ16=0, flush-to-zero mode disabled.
+	 *   [18:16] - Len=000, this field has no function in AArch64 state.
+	 *   [15]    - IDE=0, input denormal FP exception is untrapped.
+	 *   [14:13] - Reserved 0.
+	 *   [12]    - IXE=0, inexact FP exception is untrapped.
+	 *   [11]    - UFE=0, underflow FP exception is untrapped.
+	 *   [10]    - OFE=0, overflow FP exception is untrapped.
+	 *   [9]     - DZE=0, divide by zero FP exception is untrapped.
+	 *   [8]     - IOE=0, invalid operation FP exception is untrapped.
+	 *   [7:0]   - Reserved 0.
+	 * o FPSR value:
+	 *   [31]    - N=0, negative condition flag for AArch32.
+	 *   [30]    - Z=0, zero condition flag for AArch32.
+	 *   [29]    - C=0, carry condition flag for AArch32.
+	 *   [28]    - V=0, overflow condition flag for AArch32.
+	 *   [27]    - QC=0, cumulative saturation bit.
+	 *   [26:8]  - Reserved 0.
+	 *   [7]     - IDC=0, input denormal cumulative FP exception bit.
+	 *   [6:5]   - Reserved 0.
+	 *   [4]     - IXC=0, inexact cumulative FP exception bit.
+	 *   [3]     - UFC=0, underflow cumulative FP exception bit.
+	 *   [2]     - OFC=0, overflow cumulative FP exception bit.
+	 *   [1]     - DZC=0, divide by zero cumulative FP exception bit.
+	 *   [0]     - IOC=0, invalid operation cumulative FP exception bit.
+	 */
+	static fpu_context_t init = { .vregs = { 0 }, .fpcr = 0, .fpsr = 0 };
+	fpu_context_restore(&init);
+}
+
+/** Enable FPU instructions. */
+void fpu_enable(void)
+{
+	CPACR_EL1_write((CPACR_EL1_read() & ~CPACR_FPEN_MASK) |
+	    (CPACR_FPEN_TRAP_NONE << CPACR_FPEN_SHIFT));
+}
+
+/** Disable FPU instructions. */
+void fpu_disable(void)
+{
+	CPACR_EL1_write((CPACR_EL1_read() & ~CPACR_FPEN_MASK) |
+	    (CPACR_FPEN_TRAP_ALL << CPACR_FPEN_SHIFT));
+}
+
+/** @}
+ */
Index: kernel/arch/arm64/src/interrupt.c
===================================================================
--- kernel/arch/arm64/src/interrupt.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/src/interrupt.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ * @brief Interrupts controlling routines.
+ */
+
+#include <arch/interrupt.h>
+#include <arch/machine_func.h>
+#include <ddi/irq.h>
+#include <interrupt.h>
+#include <time/clock.h>
+
+static irq_t timer_irq;
+static uint64_t timer_increment;
+
+/** Disable interrupts.
+ *
+ * @return Old interrupt priority level.
+ */
+ipl_t interrupts_disable(void)
+{
+	uint64_t daif = DAIF_read();
+
+	DAIF_write(daif | DAIF_IRQ_FLAG);
+
+	return daif & DAIF_IRQ_FLAG;
+}
+
+/** Enable interrupts.
+ *
+ * @return Old interrupt priority level.
+ */
+ipl_t interrupts_enable(void)
+{
+	uint64_t daif = DAIF_read();
+
+	DAIF_write(daif & ~DAIF_IRQ_FLAG);
+
+	return daif & DAIF_IRQ_FLAG;
+}
+
+/** Restore interrupt priority level.
+ *
+ * @param ipl Saved interrupt priority level.
+ */
+void interrupts_restore(ipl_t ipl)
+{
+	uint64_t daif = DAIF_read();
+
+	DAIF_write((daif & ~DAIF_IRQ_FLAG) | (ipl & DAIF_IRQ_FLAG));
+}
+
+/** Read interrupt priority level.
+ *
+ * @return Current interrupt priority level.
+ */
+ipl_t interrupts_read(void)
+{
+	return DAIF_read() & DAIF_IRQ_FLAG;
+}
+
+/** Check interrupts state.
+ *
+ * @return True if interrupts are disabled.
+ */
+bool interrupts_disabled(void)
+{
+	return DAIF_read() & DAIF_IRQ_FLAG;
+}
+
+/** Suspend the virtual timer. */
+static void timer_suspend(void)
+{
+	uint64_t cntv_ctl = CNTV_CTL_EL0_read();
+
+	CNTV_CTL_EL0_write(cntv_ctl | CNTV_CTL_IMASK_FLAG);
+}
+
+/** Start the virtual timer. */
+static void timer_start(void)
+{
+	uint64_t cntfrq = CNTFRQ_EL0_read();
+	uint64_t cntvct = CNTVCT_EL0_read();
+	uint64_t cntv_ctl = CNTV_CTL_EL0_read();
+
+	/* Calculate the increment. */
+	timer_increment = cntfrq / HZ;
+
+	/* Program the timer. */
+	CNTV_CVAL_EL0_write(cntvct + timer_increment);
+	CNTV_CTL_EL0_write(
+	    (cntv_ctl & ~CNTV_CTL_IMASK_FLAG) | CNTV_CTL_ENABLE_FLAG);
+}
+
+/** Claim the virtual timer interrupt. */
+static irq_ownership_t timer_claim(irq_t *irq)
+{
+	return IRQ_ACCEPT;
+}
+
+/** Handle the virtual timer interrupt. */
+static void timer_irq_handler(irq_t *irq)
+{
+	uint64_t cntvct = CNTVCT_EL0_read();
+	uint64_t cntv_cval = CNTV_CVAL_EL0_read();
+
+	uint64_t drift = cntvct - cntv_cval;
+	while (drift > timer_increment) {
+		drift -= timer_increment;
+		CPU->missed_clock_ticks++;
+	}
+	CNTV_CVAL_EL0_write(cntvct + timer_increment - drift);
+
+	/*
+	 * We are holding a lock which prevents preemption.
+	 * Release the lock, call clock() and reacquire the lock again.
+	 */
+	irq_spinlock_unlock(&irq->lock, false);
+	clock();
+	irq_spinlock_lock(&irq->lock, false);
+}
+
+/** Initialize basic tables for exception dispatching. */
+void interrupt_init(void)
+{
+	size_t irq_count = machine_get_irq_count();
+	irq_init(irq_count, irq_count);
+
+	/* Initialize virtual timer. */
+	timer_suspend();
+	inr_t timer_inr = machine_enable_vtimer_irq();
+
+	irq_initialize(&timer_irq);
+	timer_irq.inr = timer_inr;
+	timer_irq.claim = timer_claim;
+	timer_irq.handler = timer_irq_handler;
+	irq_register(&timer_irq);
+
+	timer_start();
+}
+
+/** @}
+ */
Index: kernel/arch/arm64/src/mach/virt/virt.c
===================================================================
--- kernel/arch/arm64/src/mach/virt/virt.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/src/mach/virt/virt.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2016 Petr Pavlu
+ * 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 kernel_arm64_virt
+ * @{
+ */
+/** @file
+ * @brief QEMU virt platform driver.
+ */
+
+#include <arch/mach/virt/virt.h>
+#include <console/console.h>
+#include <genarch/drivers/gicv2/gicv2.h>
+#include <genarch/drivers/pl011/pl011.h>
+#include <genarch/srln/srln.h>
+#include <mm/km.h>
+#include <sysinfo/sysinfo.h>
+
+#define VIRT_VTIMER_IRQ         27
+#define VIRT_UART_IRQ           33
+#define VIRT_GIC_DISTR_ADDRESS  0x08000000
+#define VIRT_GIC_CPUI_ADDRESS   0x08010000
+#define VIRT_UART_ADDRESS       0x09000000
+
+static void virt_init(void);
+static void virt_irq_exception(unsigned int exc_no, istate_t *istate);
+static void virt_output_init(void);
+static void virt_input_init(void);
+inr_t virt_enable_vtimer_irq(void);
+size_t virt_get_irq_count(void);
+static const char *virt_get_platform_name(void);
+
+struct {
+	gicv2_t gicv2;
+	pl011_uart_t uart;
+} virt;
+
+struct arm_machine_ops virt_machine_ops = {
+	virt_init,
+	virt_irq_exception,
+	virt_output_init,
+	virt_input_init,
+	virt_enable_vtimer_irq,
+	virt_get_irq_count,
+	virt_get_platform_name
+};
+
+static void virt_init(void)
+{
+	/* Initialize interrupt controller. */
+	gicv2_distr_regs_t *distr = (void *) km_map(VIRT_GIC_DISTR_ADDRESS,
+	    ALIGN_UP(sizeof(*distr), PAGE_SIZE), KM_NATURAL_ALIGNMENT,
+	    PAGE_NOT_CACHEABLE | PAGE_READ | PAGE_WRITE | PAGE_KERNEL);
+	gicv2_cpui_regs_t *cpui = (void *) km_map(VIRT_GIC_CPUI_ADDRESS,
+	    ALIGN_UP(sizeof(*cpui), PAGE_SIZE), KM_NATURAL_ALIGNMENT,
+	    PAGE_NOT_CACHEABLE | PAGE_READ | PAGE_WRITE | PAGE_KERNEL);
+	gicv2_init(&virt.gicv2, distr, cpui);
+}
+
+static void virt_irq_exception(unsigned int exc_no, istate_t *istate)
+{
+	unsigned inum, cpuid;
+	gicv2_inum_get(&virt.gicv2, &inum, &cpuid);
+
+	/* Dispatch the interrupt. */
+	irq_t *irq = irq_dispatch_and_lock(inum);
+	if (irq) {
+		/* The IRQ handler was found. */
+		irq->handler(irq);
+		irq_spinlock_unlock(&irq->lock, false);
+	} else {
+		/* Spurious interrupt.*/
+		printf("cpu%d: spurious interrupt (inum=%u)\n", CPU->id, inum);
+	}
+
+	/* Signal end of interrupt to the controller. */
+	gicv2_end(&virt.gicv2, inum, cpuid);
+}
+
+static void virt_output_init(void)
+{
+	if (!pl011_uart_init(&virt.uart, VIRT_UART_IRQ, VIRT_UART_ADDRESS))
+		return;
+
+	stdout_wire(&virt.uart.outdev);
+}
+
+static void virt_input_init(void)
+{
+	srln_instance_t *srln_instance = srln_init();
+	if (srln_instance == NULL)
+		return;
+
+	indev_t *sink = stdin_wire();
+	indev_t *srln = srln_wire(srln_instance, sink);
+	pl011_uart_input_wire(&virt.uart, srln);
+	gicv2_enable(&virt.gicv2, VIRT_UART_IRQ);
+}
+
+inr_t virt_enable_vtimer_irq(void)
+{
+	gicv2_enable(&virt.gicv2, VIRT_VTIMER_IRQ);
+	return VIRT_VTIMER_IRQ;
+}
+
+size_t virt_get_irq_count(void)
+{
+	return gicv2_inum_get_total(&virt.gicv2);
+}
+
+const char *virt_get_platform_name(void)
+{
+	return "arm64virt";
+}
+
+/** @}
+ */
Index: kernel/arch/arm64/src/machine_func.c
===================================================================
--- kernel/arch/arm64/src/machine_func.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/src/machine_func.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2016 Petr Pavlu
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ * @brief Definitions of machine specific functions.
+ *
+ * These functions enable to differentiate more kinds of ARM platforms.
+ */
+
+#include <arch/machine_func.h>
+#include <arch/mach/virt/virt.h>
+
+/** Pointer to machine_ops structure being used. */
+static struct arm_machine_ops *machine_ops;
+
+/** Initialize machine_ops pointer. */
+void machine_ops_init(void)
+{
+#if defined(MACHINE_virt)
+	machine_ops = &virt_machine_ops;
+#else
+#error Machine type not defined.
+#endif
+}
+
+/** Perform machine-specific initialization. */
+void machine_init(void)
+{
+	machine_ops->machine_init();
+}
+
+/** Interrupt exception handler.
+ *
+ * @param exc_no Interrupt exception number.
+ * @param istate Saved processor state.
+ */
+void machine_irq_exception(unsigned int exc_no, istate_t *istate)
+{
+	machine_ops->machine_irq_exception(exc_no, 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();
+}
+
+/** Enable virtual timer interrupt and return its number. */
+inr_t machine_enable_vtimer_irq(void)
+{
+	return machine_ops->machine_enable_vtimer_irq();
+}
+
+/** Get platform identifier. */
+const char *machine_get_platform_name(void)
+{
+	return machine_ops->machine_get_platform_name();
+}
+
+/** @}
+ */
Index: kernel/arch/arm64/src/mm/as.c
===================================================================
--- kernel/arch/arm64/src/mm/as.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/src/mm/as.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64_mm
+ * @{
+ */
+/** @file
+ * @brief Address space functions.
+ */
+
+#include <arch/mm/as.h>
+#include <arch/regutils.h>
+#include <genarch/mm/asid_fifo.h>
+#include <genarch/mm/page_pt.h>
+#include <mm/as.h>
+#include <mm/asid.h>
+
+/** Architecture dependent address space init.
+ *
+ * Since ARM64 supports page tables, #as_pt_operations are used.
+ */
+void as_arch_init(void)
+{
+	as_operations = &as_pt_operations;
+	asid_fifo_init();
+}
+
+/** Perform ARM64-specific tasks when an address space becomes active on the
+ * processor.
+ *
+ * Change the level 0 page table (this is normally done by
+ * SET_PTL0_ADDRESS_ARCH() on other architectures) and install ASID.
+ *
+ * @param as Address space.
+ */
+void as_install_arch(as_t *as)
+{
+	uint64_t val;
+
+	val = (uint64_t) as->genarch.page_table;
+	if (as->asid != ASID_KERNEL) {
+		val |= (uint64_t) as->asid << TTBR0_ASID_SHIFT;
+		TTBR0_EL1_write(val);
+	} else
+		TTBR1_EL1_write(val);
+}
+
+/** @}
+ */
Index: kernel/arch/arm64/src/mm/frame.c
===================================================================
--- kernel/arch/arm64/src/mm/frame.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/src/mm/frame.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64_mm
+ * @{
+ */
+/** @file
+ * @brief Frame related functions.
+ */
+
+#include <arch/mm/frame.h>
+#include <mm/frame.h>
+#include <config.h>
+#include <align.h>
+#include <macros.h>
+
+/** Physical memory map received from the bootcode. */
+memmap_t memmap;
+
+/** Print memory layout. */
+void physmem_print(void)
+{
+	printf("[base            ] [size            ] [type      ]\n");
+
+	size_t i;
+	for (i = 0; i < memmap.cnt; i++) {
+		const char *type;
+		switch (memmap.zones[i].type) {
+		case MEMTYPE_AVAILABLE:
+			type = "available";
+			break;
+		case MEMTYPE_ACPI_RECLAIM:
+			type = "ACPI reclaim";
+			break;
+		default:
+			type = "unusable";
+			break;
+		}
+
+		printf("%p %#018zx %s\n", memmap.zones[i].start,
+		    memmap.zones[i].size, type);
+	}
+}
+
+/** Create memory zones according to information stored in memmap.
+ *
+ * Walk the memory map and create frame zones according to it.
+ */
+static void frame_common_arch_init(bool low)
+{
+	size_t i;
+
+	for (i = 0; i < memmap.cnt; i++) {
+		if (memmap.zones[i].type != MEMTYPE_AVAILABLE)
+			continue;
+
+		/* To be safe, make the available zone possibly smaller. */
+		uintptr_t base = ALIGN_UP((uintptr_t) memmap.zones[i].start,
+		    FRAME_SIZE);
+		size_t size = ALIGN_DOWN(memmap.zones[i].size -
+		    (base - (uintptr_t) memmap.zones[i].start), FRAME_SIZE);
+
+		if (!frame_adjust_zone_bounds(low, &base, &size))
+			continue;
+
+		pfn_t confdata;
+		pfn_t pfn = ADDR2PFN(base);
+		size_t count = SIZE2FRAMES(size);
+
+		if (low) {
+			/* Determine where to place confdata. */
+			if (pfn == 0) {
+				/*
+				 * Avoid placing confdata at the NULL address.
+				 */
+				if (count == 1)
+					continue;
+				confdata = 1;
+			} else
+				confdata = pfn;
+
+			zone_create(pfn, count, confdata,
+			    ZONE_AVAILABLE | ZONE_LOWMEM);
+		} else {
+			confdata = zone_external_conf_alloc(count);
+			if (confdata != 0)
+				zone_create(pfn, count, confdata,
+				    ZONE_AVAILABLE | ZONE_HIGHMEM);
+		}
+	}
+}
+
+/** Create low memory zones. */
+void frame_low_arch_init(void)
+{
+	if (config.cpu_active > 1)
+		return;
+
+	frame_common_arch_init(true);
+
+	/*
+	 * On ARM64, physical memory can start on a non-zero address. The
+	 * generic frame_init() only marks PFN 0 as not free, so we must mark
+	 * the physically first frame not free explicitly here, no matter what
+	 * is its address.
+	 */
+	frame_mark_unavailable(ADDR2PFN(physmem_base), 1);
+}
+
+/** Create high memory zones. */
+void frame_high_arch_init(void)
+{
+	if (config.cpu_active > 1)
+		return;
+
+	frame_common_arch_init(false);
+}
+
+/** @}
+ */
Index: kernel/arch/arm64/src/mm/km.c
===================================================================
--- kernel/arch/arm64/src/mm/km.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/src/mm/km.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64_mm
+ * @{
+ */
+
+#include <arch/mm/km.h>
+#include <config.h>
+#include <macros.h>
+#include <mm/km.h>
+#include <typedefs.h>
+
+void km_identity_arch_init(void)
+{
+	config.identity_base = KM_ARM64_IDENTITY_START;
+	config.identity_size = KM_ARM64_IDENTITY_SIZE;
+}
+
+void km_non_identity_arch_init(void)
+{
+	km_non_identity_span_add(KM_ARM64_NON_IDENTITY_START,
+	    KM_ARM64_NON_IDENTITY_SIZE);
+}
+
+bool km_is_non_identity_arch(uintptr_t addr)
+{
+	return iswithin(KM_ARM64_NON_IDENTITY_START, KM_ARM64_NON_IDENTITY_SIZE,
+	    addr, 1);
+}
+
+/** @}
+ */
Index: kernel/arch/arm64/src/mm/page.c
===================================================================
--- kernel/arch/arm64/src/mm/page.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/src/mm/page.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64_mm
+ * @{
+ */
+/** @file
+ * @brief Paging related functions.
+ */
+
+#include <arch/mm/page.h>
+#include <genarch/mm/page_pt.h>
+#include <mm/as.h>
+#include <mm/page.h>
+
+/** Initializes page tables. */
+void page_arch_init(void)
+{
+	if (config.cpu_active > 1) {
+		as_switch(NULL, AS_KERNEL);
+		return;
+	}
+
+	page_mapping_operations = &pt_mapping_operations;
+
+	page_table_lock(AS_KERNEL, true);
+
+	/* PA2KA(identity) mapping for all low-memory frames. */
+	for (uintptr_t cur = 0; cur < config.identity_size; cur += FRAME_SIZE) {
+		uintptr_t addr = physmem_base + cur;
+		page_mapping_insert(AS_KERNEL, PA2KA(addr), addr,
+		    PAGE_GLOBAL | PAGE_CACHEABLE | PAGE_EXEC | PAGE_WRITE |
+		    PAGE_READ);
+	}
+
+	page_table_unlock(AS_KERNEL, true);
+
+	as_switch(NULL, AS_KERNEL);
+}
+
+/** @}
+ */
Index: kernel/arch/arm64/src/mm/tlb.c
===================================================================
--- kernel/arch/arm64/src/mm/tlb.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/src/mm/tlb.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64_mm
+ * @{
+ */
+/** @file
+ * @brief TLB related functions.
+ */
+
+#include <arch/mm/asid.h>
+#include <arch/mm/page.h>
+#include <arch/regutils.h>
+#include <mm/tlb.h>
+#include <typedefs.h>
+
+/** Invalidate all entries in TLB. */
+void tlb_invalidate_all(void)
+{
+	asm volatile (
+	    /* TLB Invalidate All, EL1, Inner Shareable. */
+	    "tlbi alle1is\n"
+	    /* Ensure completion on all PEs. */
+	    "dsb ish\n"
+	    /* Synchronize context on this PE. */
+	    "isb\n"
+	    : : : "memory"
+	);
+}
+
+/** Invalidate all entries in TLB that belong to specified address space.
+ *
+ * @param asid Address Space ID.
+ */
+void tlb_invalidate_asid(asid_t asid)
+{
+	uintptr_t val = (uintptr_t)asid << TLBI_ASID_SHIFT;
+
+	asm volatile (
+	    /* TLB Invalidate by ASID, EL1, Inner Shareable. */
+	    "tlbi aside1is, %[val]\n"
+	    /* Ensure completion on all PEs. */
+	    "dsb ish\n"
+	    /* Synchronize context on this PE. */
+	    "isb\n"
+	    : : [val] "r" (val) : "memory"
+	);
+}
+
+/** Invalidate TLB entries for specified page range belonging to specified
+ * address space.
+ *
+ * @param asid Address Space ID.
+ * @param page Address of the first page whose entry is to be invalidated.
+ * @param cnt  Number of entries to invalidate.
+ */
+void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
+{
+	for (size_t i = 0; i < cnt; i++) {
+		uintptr_t val;
+
+		val = (page + i * PAGE_SIZE) >> PAGE_WIDTH;
+		val |= (uintptr_t) asid << TLBI_ASID_SHIFT;
+
+		asm volatile (
+		    /* TLB Invalidate by Virt. Address, EL1, Inner Shareable. */
+		    "tlbi vae1is, %[val]\n"
+		    /* Ensure completion on all PEs. */
+		    "dsb ish\n"
+		    /* Synchronize context on this PE. */
+		    "isb\n"
+		    : : [val] "r" (val) : "memory"
+		);
+	}
+}
+
+void tlb_arch_init(void)
+{
+}
+
+void tlb_print(void)
+{
+}
+
+/** @}
+ */
Index: kernel/arch/arm64/src/smc.c
===================================================================
--- kernel/arch/arm64/src/smc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/src/smc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2019 Petr Pavlu
+ * 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/barrier.h>
+#include <barrier.h>
+
+void smc_coherence(void *a, size_t l)
+{
+	ensure_visibility(a, l);
+}
Index: kernel/arch/arm64/src/smp/ipi.c
===================================================================
--- kernel/arch/arm64/src/smp/ipi.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/src/smp/ipi.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ */
+
+#ifdef CONFIG_SMP
+
+#include <smp/ipi.h>
+#include <panic.h>
+
+/** Deliver IPI to all processors except the current one.
+ *
+ * @param ipi IPI number.
+ */
+void ipi_broadcast_arch(int ipi)
+{
+	panic("broadcast IPI not implemented.");
+}
+
+#endif /* CONFIG_SMP */
+
+/** @}
+ */
Index: kernel/arch/arm64/src/smp/smp.c
===================================================================
--- kernel/arch/arm64/src/smp/smp.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/src/smp/smp.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 kernel_arm64
+ * @{
+ */
+/** @file
+ */
+
+#include <smp/smp.h>
+
+#ifdef CONFIG_SMP
+
+void smp_init(void)
+{
+}
+
+void kmp(void *arg)
+{
+}
+
+#endif /* CONFIG_SMP */
+
+/** @}
+ */
Index: kernel/arch/arm64/src/start.S
===================================================================
--- kernel/arch/arm64/src/start.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/arm64/src/start.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 <abi/asmtool.h>
+#include <arch/boot/boot.h>
+#include <arch/mm/km.h>
+#include <arch/mm/page.h>
+#include <arch/regutils.h>
+
+.section K_TEXT_START, "ax"
+
+SYMBOL(kernel_image_start)
+	/*
+	 * Parameters:
+	 * x0 is kernel entry point (kernel_image_start).
+	 * x1 is pointer to the bootinfo structure.
+	 *
+	 * MMU must be disabled at this point.
+	 */
+
+	/* Get address of the main memory and remember it. */
+	adrp x20, kernel_image_start - BOOT_OFFSET
+	adrp x2, physmem_base
+	/* add x2, x2, #:lo12:physmem_base */
+	str x20, [x2]
+
+	/*
+	 * Set up address translation that identity maps the gigabyte area that
+	 * is holding the current execution page.
+	 */
+
+	/* Prepare the level 0 page table. */
+	adrp x2, lower_page_table_level0
+	lsr x3, x20, #PTL0_VA_SHIFT
+	and x3, x3, #PTL0_VA_MASK
+	add x2, x2, x3, lsl #PTL_ENTRY_SIZE_SHIFT
+	mov x3, #( \
+	    1 << PTE_ACCESS_SHIFT | \
+	    PTE_L012_TYPE_TABLE << PTE_TYPE_SHIFT | \
+	    1 << PTE_PRESENT_SHIFT)
+	adrp x4, lower_page_table_level1
+	lsr x4, x4, #FRAME_WIDTH
+	orr x3, x3, x4, lsl #PTE_NEXT_LEVEL_ADDRESS_SHIFT
+	str x3, [x2]
+
+	/* Prepare the level 1 page table. */
+	adrp x2, lower_page_table_level1
+	lsr x3, x20, #PTL1_VA_SHIFT
+	and x3, x3, #PTL1_VA_MASK
+	add x2, x2, x3, lsl #PTL_ENTRY_SIZE_SHIFT
+	mov x3, #( \
+	    1 << PTE_ACCESS_SHIFT | \
+	    MAIR_EL1_DEVICE_MEMORY_INDEX << PTE_ATTR_INDEX_SHIFT | \
+	    PTE_L012_TYPE_BLOCK << PTE_TYPE_SHIFT | \
+	    1 << PTE_PRESENT_SHIFT)
+	lsr x4, x20, #FRAME_WIDTH
+	orr x3, x3, x4, lsl #PTE_OUTPUT_ADDRESS_SHIFT
+	str x3, [x2]
+
+	/*
+	 * Set up address translation that maps the first gigabyte of the kernel
+	 * identity virtual address space to the first gigabyte of the physical
+	 * memory.
+	 */
+
+	mov x21, #KM_ARM64_IDENTITY_START
+
+	/* Prepare the level 0 page table. */
+	adrp x2, upper_page_table_level0
+	lsr x3, x21, #PTL0_VA_SHIFT
+	and x3, x3, #PTL0_VA_MASK
+	add x2, x2, x3, lsl #PTL_ENTRY_SIZE_SHIFT
+	mov x3, #( \
+	    1 << PTE_ACCESS_SHIFT | \
+	    PTE_L012_TYPE_TABLE << PTE_TYPE_SHIFT | \
+	    1 << PTE_PRESENT_SHIFT)
+	adrp x4, upper_page_table_level1
+	lsr x4, x4, #FRAME_WIDTH
+	orr x3, x3, x4, lsl #PTE_NEXT_LEVEL_ADDRESS_SHIFT
+	str x3, [x2]
+
+	/* Prepare the level 1 page table. */
+	adrp x2, upper_page_table_level1
+	lsr x3, x21, #PTL1_VA_SHIFT
+	and x3, x3, #PTL1_VA_MASK
+	add x2, x2, x3, lsl #PTL_ENTRY_SIZE_SHIFT
+	mov x3, #( \
+	    1 << PTE_ACCESS_SHIFT | \
+	    MAIR_EL1_DEVICE_MEMORY_INDEX << PTE_ATTR_INDEX_SHIFT | \
+	    PTE_L012_TYPE_BLOCK << PTE_TYPE_SHIFT | \
+	    1 << PTE_PRESENT_SHIFT)
+	lsr x4, x20, #FRAME_WIDTH
+	orr x3, x3, x4, lsl #PTE_OUTPUT_ADDRESS_SHIFT
+	str x3, [x2]
+
+	/* Make sure there are not any stale TLB entries. */
+	tlbi vmalle1is
+	dsb ish
+
+	/*
+	 * Set TCR_EL1:
+	 * [63:39] - Reserved 0.
+	 * [38]    - TBI1=0, top byte of an address is used in the address
+	 *           calculation for the TTBR1_EL1 region.
+	 * [37]    - TBI0=0, top byte of an address is used in the address
+	 *           calculation for the TTBR0_EL1 region.
+	 * [36]    - AS=1, the upper 16 bits of TTBR0_EL1 and TTBR1_EL1 are used
+	 *           for allocation and matching in the TLB.
+	 * [35]    - Reserved 0.
+	 * [34:32] - IPS=101, intermediate physical address size is 48 bits,
+	 *           256TB.
+	 * [31:30] - TG1=10, TTBR1_EL1 granule size is 4KB.
+	 * [29:28] - SH1=11, memory associated with translation table walks
+	 *           using TTBR1_EL1 is inner shareable.
+	 * [27:26] - ORGN1=01, memory associated with translation table walks
+	 *           using TTBR1_EL1 is normal memory, outer write-through
+	 *           cacheable.
+	 * [25:24] - IRGN1=01, memory associated with translation table walks
+	 *           using TTBR1_EL1 is normal memory, inner write-back
+	 *           write-allocate cacheable.
+	 * [23]    - EPD1=0, perform translation table walks using TTBR1_EL1.
+	 * [22]    - A1=0, TTBR0_EL1.ASID defines the ASID.
+	 * [21:16] - T1SZ=010000, size of the memory region addressed by
+	 *           TTBR1_EL1 is 2^(64 - 16) bytes.
+	 * [15:14] - TG0=00, TTBR0_EL1 granule size is 4KB.
+	 * [13:12] - SH0=11, memory associated with translation table walks
+	 *           using TTBR0_EL1 is inner shareable.
+	 * [11:10] - ORGN0=01, memory associated with translation table walks
+	 *           using TTBR0_EL1 is normal memory, outer write-through
+	 *           cacheable.
+	 * [9:8]   - IRGN0=01, memory associated with translation table walks
+	 *           using TTBR0_EL1 is normal memory, inner write-back
+	 *           write-allocate cacheable.
+	 * [7]     - EPD0=0, perform translation table walks using TTBR0.
+	 * [6]     - Reserved 0.
+	 * [5:0]   - T0SZ=010000, size of the memory region addressed by
+	 *           TTBR0_EL1 is 2^(64 - 16) bytes.
+	 */
+	ldr x2, =0x00000015b5103510
+	msr tcr_el1, x2
+
+	/* Initialize memory attributes. */
+	ldr x2, =(MAIR_EL1_DEVICE_MEMORY_ATTR << \
+	    (MAIR_EL1_DEVICE_MEMORY_INDEX * MAIR_EL1_ATTR_SHIFT) | \
+	    MAIR_EL1_NORMAL_MEMORY_ATTR << \
+	    (MAIR_EL1_NORMAL_MEMORY_INDEX * MAIR_EL1_ATTR_SHIFT))
+	msr mair_el1, x2
+
+	/* Set translation tables. */
+	adrp x2, lower_page_table_level0
+	msr ttbr0_el1, x2
+	adrp x2, upper_page_table_level0
+	msr ttbr1_el1, x2
+	isb
+
+	/*
+	 * Set SCTLR_EL1:
+	 * [31:30] - Reserved 0.
+	 * [29:28] - Reserved 1.
+	 * [27]    - Reserved 0.
+	 * [26]    - UCI=0, any attempt to execute cache maintenance
+	 *           instructions at EL0 is trapped to EL1.
+	 * [25]    - EE=0, explicit data accesses at EL1, and stage 1
+	 *           translation table walks in the EL1&0 translation regime are
+	 *           little-endian.
+	 * [24]    - E0E=0, explicit data accesses at EL1 are little-endian.
+	 * [23:22] - Reserved 1.
+	 * [21]    - Reserved 0.
+	 * [20]    - Reserved 1.
+	 * [19]    - WXN=0, regions with write permission are not forced to
+	 *           Execute Never.
+	 * [18]    - nTWE=0, any attempt to execute WFE at EL0 is trapped to
+	 *           EL1.
+	 * [17]    - Reserved 0.
+	 * [16]    - nTWI=0, any attempt to execute WFI at EL0 is trapped to
+	 *           EL1.
+	 * [15]    - UCT=0, accesses to CTR_EL0 from EL0 are trapped to EL1.
+	 * [14]    - DZE=0, any attempt to execute DC ZVA at EL0 is trapped to
+	 *           EL1.
+	 * [13]    - Reserved 0.
+	 * [12]    - I=1, this control has no effect on the cacheability of
+	 *           instruction access to normal memory.
+	 * [11]    - Reserved 1.
+	 * [10]    - Reserved 0.
+	 * [9]     - UMA=0, any attempt to execute MSR/MRS that accesses DAIF at
+	 *           EL0 is trapped to EL1.
+	 * [8]     - SED=1, SETEND is undefined at EL0 using AArch32.
+	 * [7]     - ITD=1, disables some uses of IT at EL0 using AArch32.
+	 * [6]     - Reserved 0.
+	 * [5]     - CP15BEN=0, CP15DMB/DSB/ISB is undefined at EL0 using
+	 *           AArch32.
+	 * [4]     - SA0=1, use of stack pointer with load/store at EL0 must be
+	 *           aligned to a 16-byte boundary.
+	 * [3]     - SA=1, use of stack pointer with load/store at EL1 must be
+	 *           aligned to a 16-byte boundary.
+	 * [2]     - C=1, this control has no effect on the cacheability of data
+	 *           access to normal memory from EL0 and EL1, and normal memory
+	 *           accesses to the EL1&0 stage 1 translation tables.
+	 * [1]     - A=0, instructions that load/store registers (other than
+	 *           load/store exclusive and load-acquire/store-release) do not
+	 *           check that the address being accessed is aligned to the
+	 *           size of the data element(s) being accessed.
+	 * [0]     - M=1, EL1 and EL0 stage 1 address translation enabled.
+	 */
+	ldr w2, =0x30d0199d
+	msr sctlr_el1, x2
+	isb
+
+	/*
+	 * MMU is enabled at this point (SCTLR_EL1.M=1), switch to the kernel
+	 * mapping.
+	 */
+	ldr x2, =1f
+	br x2
+1:
+
+	/* Disable access to low addresses. */
+	mov x2, #0
+	msr ttbr0_el1, x2
+	isb
+	tlbi vmalle1is
+	dsb ish
+
+	/* Jump on a temporary stack. */
+	ldr x2, =temp_stack
+	mov sp, x2
+
+	/* Create the first stack frame. */
+	mov x29, #0
+	mov x30, #0
+	stp x29, x30, [sp, #-16]!
+	mov x29, sp
+
+	/* PA2KA(bootinfo). */
+	sub x1, x1, x20
+	ldr x2, =KM_ARM64_IDENTITY_START
+	add x1, x1, x2
+
+	bl arm64_pre_main
+	bl main_bsp
+
+.section K_DATA_START, "ax"
+
+	/* Page tables. */
+.align 12
+lower_page_table_level0:
+	.space 4096
+lower_page_table_level1:
+	.space 4096
+upper_page_table_level0:
+	.space 4096
+upper_page_table_level1:
+	.space 4096
+
+	/* Physical memory base address. */
+.align 12
+SYMBOL(physmem_base)
+	.quad 0
+
+	/* Temporary stack. */
+.align 10
+	.space 1024
+temp_stack:
Index: kernel/arch/ia32/Makefile.inc
===================================================================
--- kernel/arch/ia32/Makefile.inc	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ia32/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -92,5 +92,4 @@
 	arch/$(KARCH)/src/ddi/ddi.c \
 	arch/$(KARCH)/src/drivers/i8254.c \
-	arch/$(KARCH)/src/drivers/i8259.c \
 	arch/$(KARCH)/src/boot/multiboot.S \
 	arch/$(KARCH)/src/boot/multiboot2.S \
Index: kernel/arch/ia32/include/arch/asm.h
===================================================================
--- kernel/arch/ia32/include/arch/asm.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ia32/include/arch/asm.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -48,5 +48,5 @@
  *
  */
-NO_TRACE static inline __attribute__((noreturn)) void cpu_halt(void)
+_NO_TRACE static inline __attribute__((noreturn)) void cpu_halt(void)
 {
 	while (true) {
@@ -57,5 +57,5 @@
 }
 
-NO_TRACE static inline void cpu_sleep(void)
+_NO_TRACE static inline void cpu_sleep(void)
 {
 	asm volatile (
@@ -64,5 +64,5 @@
 }
 
-#define GEN_READ_REG(reg) NO_TRACE static inline sysarg_t read_ ##reg (void) \
+#define GEN_READ_REG(reg) _NO_TRACE static inline sysarg_t read_ ##reg (void) \
 	{ \
 		sysarg_t res; \
@@ -74,5 +74,5 @@
 	}
 
-#define GEN_WRITE_REG(reg) NO_TRACE static inline void write_ ##reg (sysarg_t regn) \
+#define GEN_WRITE_REG(reg) _NO_TRACE static inline void write_ ##reg (sysarg_t regn) \
 	{ \
 		asm volatile ( \
@@ -113,5 +113,5 @@
  *
  */
-NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t val)
+_NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t val)
 {
 	if (port < (ioport8_t *) IO_SPACE_BOUNDARY) {
@@ -132,5 +132,5 @@
  *
  */
-NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t val)
+_NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t val)
 {
 	if (port < (ioport16_t *) IO_SPACE_BOUNDARY) {
@@ -151,5 +151,5 @@
  *
  */
-NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t val)
+_NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t val)
 {
 	if (port < (ioport32_t *) IO_SPACE_BOUNDARY) {
@@ -170,5 +170,5 @@
  *
  */
-NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
+_NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
 {
 	if (((void *)port) < IO_SPACE_BOUNDARY) {
@@ -194,5 +194,5 @@
  *
  */
-NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port)
+_NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port)
 {
 	if (((void *)port) < IO_SPACE_BOUNDARY) {
@@ -218,5 +218,5 @@
  *
  */
-NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
+_NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
 {
 	if (((void *)port) < IO_SPACE_BOUNDARY) {
@@ -234,5 +234,5 @@
 }
 
-NO_TRACE static inline uint32_t read_eflags(void)
+_NO_TRACE static inline uint32_t read_eflags(void)
 {
 	uint32_t eflags;
@@ -247,5 +247,5 @@
 }
 
-NO_TRACE static inline void write_eflags(uint32_t eflags)
+_NO_TRACE static inline void write_eflags(uint32_t eflags)
 {
 	asm volatile (
@@ -261,5 +261,5 @@
  *
  */
-NO_TRACE static inline ipl_t interrupts_read(void)
+_NO_TRACE static inline ipl_t interrupts_read(void)
 {
 	return (ipl_t) read_eflags();
@@ -273,5 +273,5 @@
  *
  */
-NO_TRACE static inline ipl_t interrupts_enable(void)
+_NO_TRACE static inline ipl_t interrupts_enable(void)
 {
 	ipl_t ipl = interrupts_read();
@@ -289,5 +289,5 @@
  *
  */
-NO_TRACE static inline ipl_t interrupts_disable(void)
+_NO_TRACE static inline ipl_t interrupts_disable(void)
 {
 	ipl_t ipl = interrupts_read();
@@ -305,5 +305,5 @@
  *
  */
-NO_TRACE static inline void interrupts_restore(ipl_t ipl)
+_NO_TRACE static inline void interrupts_restore(ipl_t ipl)
 {
 	write_eflags((uint32_t) ipl);
@@ -315,5 +315,5 @@
  *
  */
-NO_TRACE static inline bool interrupts_disabled(void)
+_NO_TRACE static inline bool interrupts_disabled(void)
 {
 	return ((read_eflags() & EFLAGS_IF) == 0);
@@ -323,5 +323,5 @@
 
 /** Write to MSR */
-NO_TRACE static inline void write_msr(uint32_t msr, uint64_t value)
+_NO_TRACE static inline void write_msr(uint32_t msr, uint64_t value)
 {
 	asm volatile (
@@ -333,5 +333,5 @@
 }
 
-NO_TRACE static inline uint64_t read_msr(uint32_t msr)
+_NO_TRACE static inline uint64_t read_msr(uint32_t msr)
 {
 	uint32_t ax, dx;
@@ -356,5 +356,5 @@
  *
  */
-NO_TRACE static inline uintptr_t get_stack_base(void)
+_NO_TRACE static inline uintptr_t get_stack_base(void)
 {
 	uintptr_t v;
@@ -374,5 +374,5 @@
  *
  */
-NO_TRACE static inline void invlpg(uintptr_t addr)
+_NO_TRACE static inline void invlpg(uintptr_t addr)
 {
 	asm volatile (
@@ -387,5 +387,5 @@
  *
  */
-NO_TRACE static inline void gdtr_load(ptr_16_32_t *gdtr_reg)
+_NO_TRACE static inline void gdtr_load(ptr_16_32_t *gdtr_reg)
 {
 	asm volatile (
@@ -400,5 +400,5 @@
  *
  */
-NO_TRACE static inline void gdtr_store(ptr_16_32_t *gdtr_reg)
+_NO_TRACE static inline void gdtr_store(ptr_16_32_t *gdtr_reg)
 {
 	asm volatile (
@@ -413,5 +413,5 @@
  *
  */
-NO_TRACE static inline void idtr_load(ptr_16_32_t *idtr_reg)
+_NO_TRACE static inline void idtr_load(ptr_16_32_t *idtr_reg)
 {
 	asm volatile (
@@ -426,5 +426,5 @@
  *
  */
-NO_TRACE static inline void tr_load(uint16_t sel)
+_NO_TRACE static inline void tr_load(uint16_t sel)
 {
 	asm volatile (
@@ -439,5 +439,5 @@
  *
  */
-NO_TRACE static inline void gs_load(uint16_t sel)
+_NO_TRACE static inline void gs_load(uint16_t sel)
 {
 	asm volatile (
Index: kernel/arch/ia32/include/arch/cycle.h
===================================================================
--- kernel/arch/ia32/include/arch/cycle.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ia32/include/arch/cycle.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,5 +38,5 @@
 #include <trace.h>
 
-NO_TRACE static inline uint64_t get_cycle(void)
+_NO_TRACE static inline uint64_t get_cycle(void)
 {
 #ifdef PROCESSOR_i486
Index: rnel/arch/ia32/include/arch/drivers/i8259.h
===================================================================
--- kernel/arch/ia32/include/arch/drivers/i8259.h	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,62 +1,0 @@
-/*
- * Copyright (c) 2001-2004 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 kernel_ia32
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_ia32_I8259_H_
-#define KERN_ia32_I8259_H_
-
-#include <typedefs.h>
-#include <arch/interrupt.h>
-
-#define PIC_PIC0PORT1  ((ioport8_t *) 0x20U)
-#define PIC_PIC0PORT2  ((ioport8_t *) 0x21U)
-#define PIC_PIC1PORT1  ((ioport8_t *) 0xa0U)
-#define PIC_PIC1PORT2  ((ioport8_t *) 0xa1U)
-
-/* ICW1 bits */
-#define PIC_ICW1           (1 << 4)
-#define PIC_ICW1_NEEDICW4  (1 << 0)
-
-/* OCW4 bits */
-#define PIC_OCW4           (0 << 3)
-#define PIC_OCW4_NSEOI     (1 << 5)
-
-extern void i8259_init(void);
-extern void pic_enable_irqs(uint16_t);
-extern void pic_disable_irqs(uint16_t);
-extern void pic_eoi(void);
-
-#endif
-
-/** @}
- */
Index: kernel/arch/ia32/include/arch/interrupt.h
===================================================================
--- kernel/arch/ia32/include/arch/interrupt.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ia32/include/arch/interrupt.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -63,6 +63,7 @@
 /* NS16550 at COM1 */
 #define IRQ_NS16550   4
-#define IRQ_PIC_SPUR  7
+#define IRQ_PIC0_SPUR 7
 #define IRQ_MOUSE     12
+#define IRQ_PIC1_SPUR 15
 
 /* This one must have four least significant bits set to ones */
@@ -81,5 +82,6 @@
 #define VECTOR_XM                 (IVT_EXCBASE + EXC_XM)
 #define VECTOR_CLK                (IVT_IRQBASE + IRQ_CLK)
-#define VECTOR_PIC_SPUR           (IVT_IRQBASE + IRQ_PIC_SPUR)
+#define VECTOR_PIC0_SPUR          (IVT_IRQBASE + IRQ_PIC0_SPUR)
+#define VECTOR_PIC1_SPUR          (IVT_IRQBASE + IRQ_PIC1_SPUR)
 #define VECTOR_SYSCALL            IVT_FREEBASE
 #define VECTOR_TLB_SHOOTDOWN_IPI  (IVT_FREEBASE + 1)
@@ -88,5 +90,5 @@
 extern void (*disable_irqs_function)(uint16_t);
 extern void (*enable_irqs_function)(uint16_t);
-extern void (*eoi_function)(void);
+extern void (*eoi_function)(unsigned int);
 extern const char *irqs_info;
 
Index: kernel/arch/ia32/include/arch/istate.h
===================================================================
--- kernel/arch/ia32/include/arch/istate.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ia32/include/arch/istate.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -47,10 +47,10 @@
 
 /** Return true if exception happened while in userspace */
-NO_TRACE static inline int istate_from_uspace(istate_t *istate)
+_NO_TRACE static inline int istate_from_uspace(istate_t *istate)
 {
 	return (istate->cs & RPL_USER) == RPL_USER;
 }
 
-NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
+_NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
     uintptr_t retaddr)
 {
@@ -58,10 +58,10 @@
 }
 
-NO_TRACE static inline uintptr_t istate_get_pc(istate_t *istate)
+_NO_TRACE static inline uintptr_t istate_get_pc(istate_t *istate)
 {
 	return istate->eip;
 }
 
-NO_TRACE static inline uintptr_t istate_get_fp(istate_t *istate)
+_NO_TRACE static inline uintptr_t istate_get_fp(istate_t *istate)
 {
 	return istate->ebp;
Index: kernel/arch/ia32/include/arch/mm/as.h
===================================================================
--- kernel/arch/ia32/include/arch/mm/as.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ia32/include/arch/mm/as.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,4 +37,5 @@
 
 #define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH  0
+#define KERNEL_SEPARATE_PTL0_ARCH           0
 
 #define KERNEL_ADDRESS_SPACE_START_ARCH  UINT32_C(0x80000000)
Index: kernel/arch/ia32/include/arch/mm/page.h
===================================================================
--- kernel/arch/ia32/include/arch/mm/page.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ia32/include/arch/mm/page.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -180,5 +180,5 @@
 } __attribute__((packed)) pte_t;
 
-NO_TRACE static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
+_NO_TRACE static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
 {
 	pte_t *p = &pt[i];
@@ -193,5 +193,5 @@
 }
 
-NO_TRACE static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
+_NO_TRACE static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
 {
 	pte_t *p = &pt[i];
@@ -210,5 +210,5 @@
 }
 
-NO_TRACE static inline void set_pt_present(pte_t *pt, size_t i)
+_NO_TRACE static inline void set_pt_present(pte_t *pt, size_t i)
 {
 	pte_t *p = &pt[i];
Index: kernel/arch/ia32/include/arch/smp/apic.h
===================================================================
--- kernel/arch/ia32/include/arch/smp/apic.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ia32/include/arch/smp/apic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -356,5 +356,5 @@
 
 extern void l_apic_init(void);
-extern void l_apic_eoi(void);
+extern void l_apic_eoi(unsigned int);
 extern int l_apic_send_custom_ipi(uint8_t, uint8_t);
 extern int l_apic_broadcast_custom_ipi(uint8_t);
Index: kernel/arch/ia32/src/drivers/i8254.c
===================================================================
--- kernel/arch/ia32/src/drivers/i8254.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ia32/src/drivers/i8254.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -42,5 +42,5 @@
 #include <arch/cycle.h>
 #include <arch/interrupt.h>
-#include <arch/drivers/i8259.h>
+#include <genarch/drivers/i8259/i8259.h>
 #include <arch/drivers/i8254.h>
 #include <cpu.h>
@@ -143,7 +143,11 @@
 	o2 |= pio_read_8(CLK_PORT1) << 8;
 
+	uint32_t delta = (t1 - t2) - (o1 - o2);
+	if (!delta)
+		delta = 1;
+
 	CPU->delay_loop_const =
-	    ((MAGIC_NUMBER * LOOPS) / 1000) / ((t1 - t2) - (o1 - o2)) +
-	    (((MAGIC_NUMBER * LOOPS) / 1000) % ((t1 - t2) - (o1 - o2)) ? 1 : 0);
+	    ((MAGIC_NUMBER * LOOPS) / 1000) / delta +
+	    (((MAGIC_NUMBER * LOOPS) / 1000) % delta ? 1 : 0);
 
 	uint64_t clk1 = get_cycle();
Index: rnel/arch/ia32/src/drivers/i8259.c
===================================================================
--- kernel/arch/ia32/src/drivers/i8259.c	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,136 +1,0 @@
-/*
- * Copyright (c) 2001-2004 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 kernel_ia32
- * @{
- */
-/**
- * @file
- * @brief PIC driver.
- *
- * Programmable Interrupt Controller for UP systems based on i8259 chip.
- */
-
-#include <arch/drivers/i8259.h>
-#include <cpu.h>
-#include <stdint.h>
-#include <arch/asm.h>
-#include <arch.h>
-#include <log.h>
-#include <interrupt.h>
-
-static void pic_spurious(unsigned int n, istate_t *istate);
-
-void i8259_init(void)
-{
-	/* ICW1: this is ICW1, ICW4 to follow */
-	pio_write_8(PIC_PIC0PORT1, PIC_ICW1 | PIC_ICW1_NEEDICW4);
-
-	/* ICW2: IRQ 0 maps to INT IRQBASE */
-	pio_write_8(PIC_PIC0PORT2, IVT_IRQBASE);
-
-	/* ICW3: pic1 using IRQ IRQ_PIC1 */
-	pio_write_8(PIC_PIC0PORT2, 1 << IRQ_PIC1);
-
-	/* ICW4: i8086 mode */
-	pio_write_8(PIC_PIC0PORT2, 1);
-
-	/* ICW1: ICW1, ICW4 to follow */
-	pio_write_8(PIC_PIC1PORT1, PIC_ICW1 | PIC_ICW1_NEEDICW4);
-
-	/* ICW2: IRQ 8 maps to INT (IVT_IRQBASE + 8) */
-	pio_write_8(PIC_PIC1PORT2, IVT_IRQBASE + 8);
-
-	/* ICW3: pic1 is known as IRQ_PIC1 */
-	pio_write_8(PIC_PIC1PORT2, IRQ_PIC1);
-
-	/* ICW4: i8086 mode */
-	pio_write_8(PIC_PIC1PORT2, 1);
-
-	/*
-	 * Register interrupt handler for the PIC spurious interrupt.
-	 */
-	exc_register(VECTOR_PIC_SPUR, "pic_spurious", false,
-	    (iroutine_t) pic_spurious);
-
-	/*
-	 * Set the enable/disable IRQs handlers.
-	 * Set the End-of-Interrupt handler.
-	 */
-	enable_irqs_function = pic_enable_irqs;
-	disable_irqs_function = pic_disable_irqs;
-	eoi_function = pic_eoi;
-	irqs_info = "i8259";
-
-	pic_disable_irqs(0xffff);		/* disable all irq's */
-	pic_enable_irqs(1 << IRQ_PIC1);		/* but enable pic1 */
-}
-
-void pic_enable_irqs(uint16_t irqmask)
-{
-	uint8_t x;
-
-	if (irqmask & 0xff) {
-		x = pio_read_8(PIC_PIC0PORT2);
-		pio_write_8(PIC_PIC0PORT2, (uint8_t) (x & (~(irqmask & 0xff))));
-	}
-	if (irqmask >> 8) {
-		x = pio_read_8(PIC_PIC1PORT2);
-		pio_write_8(PIC_PIC1PORT2, (uint8_t) (x & (~(irqmask >> 8))));
-	}
-}
-
-void pic_disable_irqs(uint16_t irqmask)
-{
-	uint8_t x;
-
-	if (irqmask & 0xff) {
-		x = pio_read_8(PIC_PIC0PORT2);
-		pio_write_8(PIC_PIC0PORT2, (uint8_t) (x | (irqmask & 0xff)));
-	}
-	if (irqmask >> 8) {
-		x = pio_read_8(PIC_PIC1PORT2);
-		pio_write_8(PIC_PIC1PORT2, (uint8_t) (x | (irqmask >> 8)));
-	}
-}
-
-void pic_eoi(void)
-{
-	pio_write_8(PIC_PIC0PORT1, PIC_OCW4 | PIC_OCW4_NSEOI);
-	pio_write_8(PIC_PIC1PORT1, PIC_OCW4 | PIC_OCW4_NSEOI);
-}
-
-void pic_spurious(unsigned int n __attribute__((unused)), istate_t *istate __attribute__((unused)))
-{
-#ifdef CONFIG_DEBUG
-	log(LF_ARCH, LVL_DEBUG, "cpu%u: PIC spurious interrupt", CPU->id);
-#endif
-}
-
-/** @}
- */
Index: kernel/arch/ia32/src/ia32.c
===================================================================
--- kernel/arch/ia32/src/ia32.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ia32/src/ia32.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -47,8 +47,8 @@
 #include <arch/boot/boot.h>
 #include <arch/drivers/i8254.h>
-#include <arch/drivers/i8259.h>
 #include <genarch/acpi/acpi.h>
 #include <genarch/drivers/ega/ega.h>
 #include <genarch/drivers/i8042/i8042.h>
+#include <genarch/drivers/i8259/i8259.h>
 #include <genarch/drivers/ns16550/ns16550.h>
 #include <genarch/drivers/legacy/ia32/io.h>
@@ -109,5 +109,15 @@
 
 		/* PIC */
-		i8259_init();
+		i8259_init((i8259_t *) I8259_PIC0_BASE,
+		    (i8259_t *) I8259_PIC1_BASE, IVT_IRQBASE);
+
+		/*
+		 * Set the enable/disable IRQs handlers.
+		 * Set the End-of-Interrupt handler.
+		 */
+		enable_irqs_function = pic_enable_irqs;
+		disable_irqs_function = pic_disable_irqs;
+		eoi_function = pic_eoi;
+		irqs_info = "i8259";
 	}
 }
Index: kernel/arch/ia32/src/interrupt.c
===================================================================
--- kernel/arch/ia32/src/interrupt.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ia32/src/interrupt.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,5 +39,5 @@
 #include <debug.h>
 #include <panic.h>
-#include <arch/drivers/i8259.h>
+#include <genarch/drivers/i8259/i8259.h>
 #include <halt.h>
 #include <cpu.h>
@@ -63,5 +63,5 @@
 void (*disable_irqs_function)(uint16_t irqmask) = NULL;
 void (*enable_irqs_function)(uint16_t irqmask) = NULL;
-void (*eoi_function)(void) = NULL;
+void (*eoi_function)(unsigned int) = NULL;
 const char *irqs_info = NULL;
 
@@ -90,8 +90,8 @@
 }
 
-static void trap_virtual_eoi(void)
+static void trap_virtual_eoi(unsigned int inum)
 {
 	if (eoi_function)
-		eoi_function();
+		eoi_function(inum);
 	else
 		panic("No eoi_function.");
@@ -179,5 +179,5 @@
     istate_t *istate __attribute__((unused)))
 {
-	trap_virtual_eoi();
+	trap_virtual_eoi(0);
 	tlb_shootdown_ipi_recv();
 }
@@ -192,5 +192,5 @@
 	bool ack = false;
 	assert(inum < IRQ_COUNT);
-	assert((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1));
+	assert(inum != IRQ_PIC1);
 
 	irq_t *irq = irq_dispatch_and_lock(inum);
@@ -202,5 +202,5 @@
 		if (irq->preack) {
 			/* Send EOI before processing the interrupt */
-			trap_virtual_eoi();
+			trap_virtual_eoi(inum);
 			ack = true;
 		}
@@ -208,14 +208,27 @@
 		irq_spinlock_unlock(&irq->lock, false);
 	} else {
-		/*
-		 * Spurious interrupt.
-		 */
 #ifdef CONFIG_DEBUG
-		printf("cpu%u: spurious interrupt (inum=%u)\n", CPU->id, inum);
+		log(LF_ARCH, LVL_DEBUG, "cpu%u: unhandled IRQ %u", CPU->id,
+		    inum);
 #endif
 	}
 
 	if (!ack)
-		trap_virtual_eoi();
+		trap_virtual_eoi(inum);
+}
+
+static void pic_spurious(unsigned int n, istate_t *istate)
+{
+	unsigned int inum = n - IVT_IRQBASE;
+	if (!pic_is_spurious(inum)) {
+		/* This is actually not a spurious IRQ, so proceed as usual. */
+		irq_interrupt(n, istate);
+		return;
+	}
+	pic_handle_spurious(n);
+#ifdef CONFIG_DEBUG
+	log(LF_ARCH, LVL_DEBUG, "cpu%u: PIC spurious interrupt %u", CPU->id,
+	    inum);
+#endif
 }
 
@@ -228,5 +241,6 @@
 
 	for (i = 0; i < IRQ_COUNT; i++) {
-		if ((i != IRQ_PIC_SPUR) && (i != IRQ_PIC1))
+		if ((i != IRQ_PIC0_SPUR) && (i != IRQ_PIC1_SPUR) &&
+		    (i != IRQ_PIC1))
 			exc_register(IVT_IRQBASE + i, "irq", true,
 			    (iroutine_t) irq_interrupt);
@@ -239,4 +253,8 @@
 	exc_register(VECTOR_GP, "gp_fault", true, (iroutine_t) gp_fault);
 	exc_register(VECTOR_XM, "simd_fp", true, (iroutine_t) simd_fp_exception);
+	exc_register(VECTOR_PIC0_SPUR, "pic0_spurious", true,
+	    (iroutine_t) pic_spurious);
+	exc_register(VECTOR_PIC1_SPUR, "pic1_spurious", true,
+	    (iroutine_t) pic_spurious);
 
 #ifdef CONFIG_SMP
Index: kernel/arch/ia32/src/smp/apic.c
===================================================================
--- kernel/arch/ia32/src/smp/apic.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ia32/src/smp/apic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -508,5 +508,5 @@
 
 /** Local APIC End of Interrupt. */
-void l_apic_eoi(void)
+void l_apic_eoi(unsigned int ignored)
 {
 	l_apic[EOI] = 0;
Index: kernel/arch/ia32/src/smp/smp.c
===================================================================
--- kernel/arch/ia32/src/smp/smp.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ia32/src/smp/smp.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -55,5 +55,5 @@
 #include <log.h>
 #include <mem.h>
-#include <arch/drivers/i8259.h>
+#include <genarch/drivers/i8259/i8259.h>
 #include <cpu.h>
 
Index: kernel/arch/ia64/include/arch/asm.h
===================================================================
--- kernel/arch/ia64/include/arch/asm.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ia64/include/arch/asm.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -45,5 +45,5 @@
 
 /** Map the I/O port address to a legacy I/O address. */
-NO_TRACE static inline uintptr_t p2a(volatile void *p)
+_NO_TRACE static inline uintptr_t p2a(volatile void *p)
 {
 	uintptr_t prt = (uintptr_t) p;
@@ -52,5 +52,5 @@
 }
 
-NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t v)
+_NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t v)
 {
 	if (port < (ioport8_t *) IO_SPACE_BOUNDARY)
@@ -66,5 +66,5 @@
 }
 
-NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t v)
+_NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t v)
 {
 	if (port < (ioport16_t *) IO_SPACE_BOUNDARY)
@@ -80,5 +80,5 @@
 }
 
-NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t v)
+_NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t v)
 {
 	if (port < (ioport32_t *) IO_SPACE_BOUNDARY)
@@ -94,5 +94,5 @@
 }
 
-NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
+_NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
 {
 	uint8_t v;
@@ -116,5 +116,5 @@
 }
 
-NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port)
+_NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port)
 {
 	uint16_t v;
@@ -138,5 +138,5 @@
 }
 
-NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
+_NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
 {
 	uint32_t v;
@@ -166,5 +166,5 @@
  * The memory stack must start on page boundary.
  */
-NO_TRACE static inline uintptr_t get_stack_base(void)
+_NO_TRACE static inline uintptr_t get_stack_base(void)
 {
 	uint64_t value;
@@ -183,5 +183,5 @@
  *
  */
-NO_TRACE static inline uint64_t psr_read(void)
+_NO_TRACE static inline uint64_t psr_read(void)
 {
 	uint64_t v;
@@ -200,5 +200,5 @@
  *
  */
-NO_TRACE static inline uint64_t iva_read(void)
+_NO_TRACE static inline uint64_t iva_read(void)
 {
 	uint64_t v;
@@ -217,5 +217,5 @@
  *
  */
-NO_TRACE static inline void iva_write(uint64_t v)
+_NO_TRACE static inline void iva_write(uint64_t v)
 {
 	asm volatile (
@@ -231,5 +231,5 @@
  *
  */
-NO_TRACE static inline uint64_t ivr_read(void)
+_NO_TRACE static inline uint64_t ivr_read(void)
 {
 	uint64_t v;
@@ -243,5 +243,5 @@
 }
 
-NO_TRACE static inline uint64_t cr64_read(void)
+_NO_TRACE static inline uint64_t cr64_read(void)
 {
 	uint64_t v;
@@ -260,5 +260,5 @@
  *
  */
-NO_TRACE static inline void itc_write(uint64_t v)
+_NO_TRACE static inline void itc_write(uint64_t v)
 {
 	asm volatile (
@@ -273,5 +273,5 @@
  *
  */
-NO_TRACE static inline uint64_t itc_read(void)
+_NO_TRACE static inline uint64_t itc_read(void)
 {
 	uint64_t v;
@@ -290,5 +290,5 @@
  *
  */
-NO_TRACE static inline void itm_write(uint64_t v)
+_NO_TRACE static inline void itm_write(uint64_t v)
 {
 	asm volatile (
@@ -303,5 +303,5 @@
  *
  */
-NO_TRACE static inline uint64_t itm_read(void)
+_NO_TRACE static inline uint64_t itm_read(void)
 {
 	uint64_t v;
@@ -320,5 +320,5 @@
  *
  */
-NO_TRACE static inline uint64_t itv_read(void)
+_NO_TRACE static inline uint64_t itv_read(void)
 {
 	uint64_t v;
@@ -337,5 +337,5 @@
  *
  */
-NO_TRACE static inline void itv_write(uint64_t v)
+_NO_TRACE static inline void itv_write(uint64_t v)
 {
 	asm volatile (
@@ -350,5 +350,5 @@
  *
  */
-NO_TRACE static inline void eoi_write(uint64_t v)
+_NO_TRACE static inline void eoi_write(uint64_t v)
 {
 	asm volatile (
@@ -363,5 +363,5 @@
  *
  */
-NO_TRACE static inline uint64_t tpr_read(void)
+_NO_TRACE static inline uint64_t tpr_read(void)
 {
 	uint64_t v;
@@ -380,5 +380,5 @@
  *
  */
-NO_TRACE static inline void tpr_write(uint64_t v)
+_NO_TRACE static inline void tpr_write(uint64_t v)
 {
 	asm volatile (
@@ -396,5 +396,5 @@
  *
  */
-NO_TRACE static ipl_t interrupts_disable(void)
+_NO_TRACE static ipl_t interrupts_disable(void)
 {
 	uint64_t v;
@@ -418,5 +418,5 @@
  *
  */
-NO_TRACE static ipl_t interrupts_enable(void)
+_NO_TRACE static ipl_t interrupts_enable(void)
 {
 	uint64_t v;
@@ -441,5 +441,5 @@
  *
  */
-NO_TRACE static inline void interrupts_restore(ipl_t ipl)
+_NO_TRACE static inline void interrupts_restore(ipl_t ipl)
 {
 	if (ipl & PSR_I_MASK)
@@ -454,5 +454,5 @@
  *
  */
-NO_TRACE static inline ipl_t interrupts_read(void)
+_NO_TRACE static inline ipl_t interrupts_read(void)
 {
 	return (ipl_t) psr_read();
@@ -464,5 +464,5 @@
  *
  */
-NO_TRACE static inline bool interrupts_disabled(void)
+_NO_TRACE static inline bool interrupts_disabled(void)
 {
 	return !(psr_read() & PSR_I_MASK);
@@ -470,5 +470,5 @@
 
 /** Disable protection key checking. */
-NO_TRACE static inline void pk_disable(void)
+_NO_TRACE static inline void pk_disable(void)
 {
 	asm volatile (
Index: kernel/arch/ia64/include/arch/cpu.h
===================================================================
--- kernel/arch/ia64/include/arch/cpu.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ia64/include/arch/cpu.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -64,5 +64,5 @@
  *
  */
-NO_TRACE static inline uint64_t cpuid_read(int n)
+_NO_TRACE static inline uint64_t cpuid_read(int n)
 {
 	uint64_t v;
@@ -77,5 +77,5 @@
 }
 
-NO_TRACE static inline int ia64_get_cpu_id(void)
+_NO_TRACE static inline int ia64_get_cpu_id(void)
 {
 	uint64_t cr64 = cr64_read();
@@ -83,5 +83,5 @@
 }
 
-NO_TRACE static inline int ia64_get_cpu_eid(void)
+_NO_TRACE static inline int ia64_get_cpu_eid(void)
 {
 	uint64_t cr64 = cr64_read();
@@ -89,5 +89,5 @@
 }
 
-NO_TRACE static inline void ipi_send_ipi(int id, int eid, int intno)
+_NO_TRACE static inline void ipi_send_ipi(int id, int eid, int intno)
 {
 	(bootinfo->sapic)[2 * (id * 256 + eid)] = intno;
Index: kernel/arch/ia64/include/arch/cycle.h
===================================================================
--- kernel/arch/ia64/include/arch/cycle.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ia64/include/arch/cycle.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,5 +38,5 @@
 #include <trace.h>
 
-NO_TRACE static inline uint64_t get_cycle(void)
+_NO_TRACE static inline uint64_t get_cycle(void)
 {
 	return 0;
Index: kernel/arch/ia64/include/arch/istate.h
===================================================================
--- kernel/arch/ia64/include/arch/istate.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ia64/include/arch/istate.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -50,5 +50,5 @@
 #endif /* KERNEL */
 
-NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
+_NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
     uintptr_t retaddr)
 {
@@ -57,10 +57,10 @@
 }
 
-NO_TRACE static inline uintptr_t istate_get_pc(istate_t *istate)
+_NO_TRACE static inline uintptr_t istate_get_pc(istate_t *istate)
 {
 	return istate->cr_iip;
 }
 
-NO_TRACE static inline uintptr_t istate_get_fp(istate_t *istate)
+_NO_TRACE static inline uintptr_t istate_get_fp(istate_t *istate)
 {
 	/* FIXME */
@@ -69,5 +69,5 @@
 }
 
-NO_TRACE static inline int istate_from_uspace(istate_t *istate)
+_NO_TRACE static inline int istate_from_uspace(istate_t *istate)
 {
 	return (istate->cr_iip) < 0xe000000000000000ULL;
Index: kernel/arch/ia64/include/arch/mm/as.h
===================================================================
--- kernel/arch/ia64/include/arch/mm/as.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ia64/include/arch/mm/as.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,4 +37,5 @@
 
 #define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH  0
+#define KERNEL_SEPARATE_PTL0_ARCH           0
 
 #define KERNEL_ADDRESS_SPACE_START_ARCH  UINT64_C(0xe000000000000000)
Index: kernel/arch/ia64/include/arch/mm/page.h
===================================================================
--- kernel/arch/ia64/include/arch/mm/page.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ia64/include/arch/mm/page.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -191,5 +191,5 @@
  * @return Address of the head of VHPT collision chain.
  */
-NO_TRACE static inline uint64_t thash(uint64_t va)
+_NO_TRACE static inline uint64_t thash(uint64_t va)
 {
 	uint64_t ret;
@@ -213,5 +213,5 @@
  * @return The unique tag for VPN and RID in the collision chain returned by thash().
  */
-NO_TRACE static inline uint64_t ttag(uint64_t va)
+_NO_TRACE static inline uint64_t ttag(uint64_t va)
 {
 	uint64_t ret;
@@ -232,5 +232,5 @@
  * @return Current contents of rr[i].
  */
-NO_TRACE static inline uint64_t rr_read(size_t i)
+_NO_TRACE static inline uint64_t rr_read(size_t i)
 {
 	uint64_t ret;
@@ -252,5 +252,5 @@
  * @param v Value to be written to rr[i].
  */
-NO_TRACE static inline void rr_write(size_t i, uint64_t v)
+_NO_TRACE static inline void rr_write(size_t i, uint64_t v)
 {
 	assert(i < REGION_REGISTERS);
@@ -267,5 +267,5 @@
  * @return Current value stored in PTA.
  */
-NO_TRACE static inline uint64_t pta_read(void)
+_NO_TRACE static inline uint64_t pta_read(void)
 {
 	uint64_t ret;
@@ -283,5 +283,5 @@
  * @param v New value to be stored in PTA.
  */
-NO_TRACE static inline void pta_write(uint64_t v)
+_NO_TRACE static inline void pta_write(uint64_t v)
 {
 	asm volatile (
Index: kernel/arch/mips32/Makefile.inc
===================================================================
--- kernel/arch/mips32/Makefile.inc	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/mips32/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -70,9 +70,4 @@
 	arch/$(KARCH)/src/machine_func.c
 
-ifeq ($(MACHINE),msim)
-	ARCH_SOURCES += \
-		arch/$(KARCH)/src/smp/dorder.c
-endif
-
 ifeq ($(MACHINE),$(filter lmalta bmalta,$(MACHINE)))
 	ARCH_SOURCES += arch/$(KARCH)/src/mach/malta/malta.c
@@ -80,5 +75,7 @@
 
 ifeq ($(MACHINE),msim)
-	ARCH_SOURCES += arch/$(KARCH)/src/mach/msim/msim.c
+	ARCH_SOURCES += \
+		arch/$(KARCH)/src/mach/msim/msim.c \
+		arch/$(KARCH)/src/mach/msim/dorder.c
 endif
 
Index: kernel/arch/mips32/include/arch/asm.h
===================================================================
--- kernel/arch/mips32/include/arch/asm.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/mips32/include/arch/asm.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -40,5 +40,5 @@
 #include <trace.h>
 
-NO_TRACE static inline void cpu_sleep(void)
+_NO_TRACE static inline void cpu_sleep(void)
 {
 	asm volatile ("wait");
@@ -52,5 +52,5 @@
  *
  */
-NO_TRACE static inline uintptr_t get_stack_base(void)
+_NO_TRACE static inline uintptr_t get_stack_base(void)
 {
 	uintptr_t base;
@@ -65,30 +65,30 @@
 }
 
-NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t v)
+_NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t v)
 {
 	*port = v;
 }
 
-NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t v)
+_NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t v)
 {
 	*port = v;
 }
 
-NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t v)
+_NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t v)
 {
 	*port = v;
 }
 
-NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
+_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)
+_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)
+_NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
 {
 	return *port;
Index: kernel/arch/mips32/include/arch/cycle.h
===================================================================
--- kernel/arch/mips32/include/arch/cycle.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/mips32/include/arch/cycle.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -40,5 +40,5 @@
 #include <trace.h>
 
-NO_TRACE static inline uint64_t get_cycle(void)
+_NO_TRACE static inline uint64_t get_cycle(void)
 {
 	return ((uint64_t) count_hi << 32) + ((uint64_t) cp0_count_read());
Index: rnel/arch/mips32/include/arch/drivers/msim.h
===================================================================
--- kernel/arch/mips32/include/arch/drivers/msim.h	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,48 +1,0 @@
-/*
- * 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 kernel_mips32
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_mips32_MSIM_H_
-#define KERN_mips32_MSIM_H_
-
-/** Address of devices. */
-#define MSIM_VIDEORAM     0x90000000
-#define MSIM_KBD_ADDRESS  0x90000000
-
-#define MSIM_KBD_IRQ      2
-#define MSIM_DDISK_IRQ    6
-
-#endif
-
-/** @}
- */
Index: kernel/arch/mips32/include/arch/exception.h
===================================================================
--- kernel/arch/mips32/include/arch/exception.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/mips32/include/arch/exception.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -57,4 +57,19 @@
 #define EXC_VCED   31
 
+#define INT_SW0    0
+#define INT_SW1    1
+#define INT_HW0    2
+#define INT_HW1    3
+#define INT_HW2    4
+#define INT_HW3    5
+#define INT_HW4    6
+#define INT_TIMER  7
+
+#define MIPS_INTERRUPTS    8
+#define HW_INTERRUPTS      (MIPS_INTERRUPTS - 3)
+
+typedef void (*int_handler_t)(unsigned int);
+extern int_handler_t int_handler[];
+
 extern void exception(istate_t *istate);
 extern void tlb_refill_entry(void);
Index: kernel/arch/mips32/include/arch/istate.h
===================================================================
--- kernel/arch/mips32/include/arch/istate.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/mips32/include/arch/istate.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -50,5 +50,5 @@
 #endif /* KERNEL */
 
-NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
+_NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
     uintptr_t retaddr)
 {
@@ -57,15 +57,15 @@
 
 /** Return true if exception happened while in userspace */
-NO_TRACE static inline int istate_from_uspace(istate_t *istate)
+_NO_TRACE static inline int istate_from_uspace(istate_t *istate)
 {
 	return istate->status & cp0_status_um_bit;
 }
 
-NO_TRACE static inline uintptr_t istate_get_pc(istate_t *istate)
+_NO_TRACE static inline uintptr_t istate_get_pc(istate_t *istate)
 {
 	return istate->epc;
 }
 
-NO_TRACE static inline uintptr_t istate_get_fp(istate_t *istate)
+_NO_TRACE static inline uintptr_t istate_get_fp(istate_t *istate)
 {
 	return istate->sp;
Index: kernel/arch/mips32/include/arch/mach/malta/malta.h
===================================================================
--- kernel/arch/mips32/include/arch/mach/malta/malta.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/mips32/include/arch/mach/malta/malta.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,4 +38,21 @@
 
 #include <arch/machine_func.h>
+#include <arch/mm/page.h>
+#include <typedefs.h>
+
+#define MALTA_PCI_PHYSBASE	0x18000000UL
+
+#define MALTA_PCI_BASE		PA2KSEG1(MALTA_PCI_PHYSBASE)
+#define MALTA_GT64120_BASE	PA2KSEG1(0x1be00000UL)
+
+#define PIC0_BASE		(MALTA_PCI_BASE + 0x20)
+#define PIC1_BASE		(MALTA_PCI_BASE + 0xa0)
+
+#define ISA_IRQ_COUNT		16
+
+#define TTY_BASE		(MALTA_PCI_PHYSBASE + 0x3f8)
+#define TTY_ISA_IRQ		4
+
+#define GT64120_PCI0_INTACK	((ioport32_t *) (MALTA_GT64120_BASE + 0xc34))
 
 extern struct mips32_machine_ops malta_machine_ops;
Index: kernel/arch/mips32/include/arch/mach/msim/dorder.h
===================================================================
--- kernel/arch/mips32/include/arch/mach/msim/dorder.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/mips32/include/arch/mach/msim/dorder.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2007 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 kernel_mips32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips32_DORDER_H_
+#define KERN_mips32_DORDER_H_
+
+#include <stdint.h>
+
+extern void dorder_init(void);
+extern uint32_t dorder_cpuid(void);
+extern void dorder_ipi_ack(uint32_t);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips32/include/arch/mach/msim/msim.h
===================================================================
--- kernel/arch/mips32/include/arch/mach/msim/msim.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/mips32/include/arch/mach/msim/msim.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,4 +38,14 @@
 
 #include <arch/machine_func.h>
+#include <arch/mm/page.h>
+
+/** Address of devices. */
+#define MSIM_VIDEORAM        PA2KSEG1(0x10000000)
+#define MSIM_KBD_ADDRESS     PA2KSEG1(0x10000000)
+#define MSIM_DORDER_ADDRESS  PA2KSEG1(0x10000100)
+
+#define MSIM_KBD_IRQ      2
+#define MSIM_DORDER_IRQ   5
+#define MSIM_DDISK_IRQ    6
 
 extern struct mips32_machine_ops msim_machine_ops;
Index: kernel/arch/mips32/include/arch/machine_func.h
===================================================================
--- kernel/arch/mips32/include/arch/machine_func.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/mips32/include/arch/machine_func.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -43,4 +43,5 @@
 
 #include <typedefs.h>
+#include <stdbool.h>
 
 struct mips32_machine_ops {
Index: kernel/arch/mips32/include/arch/mm/as.h
===================================================================
--- kernel/arch/mips32/include/arch/mm/as.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/mips32/include/arch/mm/as.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,4 +37,5 @@
 
 #define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH  0
+#define KERNEL_SEPARATE_PTL0_ARCH           0
 
 #define KERNEL_ADDRESS_SPACE_START_ARCH  UINT32_C(0x80000000)
Index: kernel/arch/mips32/include/arch/mm/page.h
===================================================================
--- kernel/arch/mips32/include/arch/mm/page.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/mips32/include/arch/mm/page.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -43,4 +43,6 @@
 
 #ifndef __ASSEMBLER__
+#	define KSEG12PA(x)	(((uintptr_t) (x)) - 0xa0000000)
+#	define PA2KSEG1(x)	(((uintptr_t) (x)) + 0xa0000000)
 #	define KA2PA(x)	(((uintptr_t) (x)) - 0x80000000)
 #	define PA2KA(x)	(((uintptr_t) (x)) + 0x80000000)
@@ -161,5 +163,5 @@
 } pte_t;
 
-NO_TRACE static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
+_NO_TRACE static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
 {
 	pte_t *p = &pt[i];
@@ -174,5 +176,5 @@
 }
 
-NO_TRACE static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
+_NO_TRACE static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
 {
 	pte_t *p = &pt[i];
@@ -189,5 +191,5 @@
 }
 
-NO_TRACE static inline void set_pt_present(pte_t *pt, size_t i)
+_NO_TRACE static inline void set_pt_present(pte_t *pt, size_t i)
 {
 	pte_t *p = &pt[i];
Index: kernel/arch/mips32/include/arch/mm/tlb.h
===================================================================
--- kernel/arch/mips32/include/arch/mm/tlb.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/mips32/include/arch/mm/tlb.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -135,5 +135,5 @@
  * Probe TLB for Matching Entry.
  */
-NO_TRACE static inline void tlbp(void)
+_NO_TRACE static inline void tlbp(void)
 {
 	asm volatile ("tlbp\n\t");
@@ -144,5 +144,5 @@
  * Read Indexed TLB Entry.
  */
-NO_TRACE static inline void tlbr(void)
+_NO_TRACE static inline void tlbr(void)
 {
 	asm volatile ("tlbr\n\t");
@@ -153,5 +153,5 @@
  * Write Indexed TLB Entry.
  */
-NO_TRACE static inline void tlbwi(void)
+_NO_TRACE static inline void tlbwi(void)
 {
 	asm volatile ("tlbwi\n\t");
@@ -162,5 +162,5 @@
  * Write Random TLB Entry.
  */
-NO_TRACE static inline void tlbwr(void)
+_NO_TRACE static inline void tlbwr(void)
 {
 	asm volatile ("tlbwr\n\t");
Index: rnel/arch/mips32/include/arch/smp/dorder.h
===================================================================
--- kernel/arch/mips32/include/arch/smp/dorder.h	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,46 +1,0 @@
-/*
- * Copyright (c) 2007 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 kernel_mips32
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_mips32_DORDER_H_
-#define KERN_mips32_DORDER_H_
-
-#include <stdint.h>
-
-extern uint32_t dorder_cpuid(void);
-extern void dorder_ipi_ack(uint32_t);
-
-#endif
-
-/** @}
- */
Index: kernel/arch/mips32/src/exception.c
===================================================================
--- kernel/arch/mips32/src/exception.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/mips32/src/exception.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -47,4 +47,5 @@
 #include <symtab.h>
 #include <log.h>
+#include <arch/machine_func.h>
 
 static const char *exctable[] = {
@@ -174,5 +175,5 @@
 
 	unsigned int i;
-	for (i = 0; i < 8; i++) {
+	for (i = 0; i < MIPS_INTERRUPTS; i++) {
 
 		/*
@@ -183,12 +184,7 @@
 		 */
 		if (im & ip & (1 << i)) {
-			irq_t *irq = irq_dispatch_and_lock(i);
-			if (irq) {
-				/*
-				 * The IRQ handler was found.
-				 */
-				irq->handler(irq);
-				irq_spinlock_unlock(&irq->lock, false);
-			} else {
+			if (int_handler[i])
+				int_handler[i](i);
+			else {
 				/*
 				 * Spurious interrupt.
Index: kernel/arch/mips32/src/interrupt.c
===================================================================
--- kernel/arch/mips32/src/interrupt.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/mips32/src/interrupt.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,21 +38,6 @@
 #include <arch.h>
 #include <arch/cp0.h>
-#include <arch/smp/dorder.h>
 #include <time/clock.h>
 #include <ipc/sysipc.h>
-
-#define IRQ_COUNT   8
-#define TIMER_IRQ   7
-
-#ifdef MACHINE_msim
-#define DORDER_IRQ  5
-#endif
-
-function virtual_timer_fnc = NULL;
-static irq_t timer_irq;
-
-#ifdef MACHINE_msim
-static irq_t dorder_irq;
-#endif
 
 // TODO: This is SMP unsafe!!!
@@ -61,4 +46,7 @@
 static unsigned long nextcount;
 static unsigned long lastcount;
+
+/** Table of interrupt handlers. */
+int_handler_t int_handler[MIPS_INTERRUPTS] = { };
 
 /** Disable interrupts.
@@ -122,10 +110,5 @@
 }
 
-static irq_ownership_t timer_claim(irq_t *irq)
-{
-	return IRQ_ACCEPT;
-}
-
-static void timer_irq_handler(irq_t *irq)
+static void timer_interrupt_handler(unsigned int intr)
 {
 	if (cp0_count_read() < lastcount)
@@ -144,51 +127,14 @@
 	cp0_compare_write(nextcount);
 
-	/*
-	 * We are holding a lock which prevents preemption.
-	 * Release the lock, call clock() and reacquire the lock again.
-	 */
-	irq_spinlock_unlock(&irq->lock, false);
 	clock();
-	irq_spinlock_lock(&irq->lock, false);
-
-	if (virtual_timer_fnc != NULL)
-		virtual_timer_fnc();
 }
-
-#ifdef MACHINE_msim
-static irq_ownership_t dorder_claim(irq_t *irq)
-{
-	return IRQ_ACCEPT;
-}
-
-static void dorder_irq_handler(irq_t *irq)
-{
-	dorder_ipi_ack(1 << dorder_cpuid());
-}
-#endif
 
 /* Initialize basic tables for exception dispatching */
 void interrupt_init(void)
 {
-	irq_init(IRQ_COUNT, IRQ_COUNT);
-
-	irq_initialize(&timer_irq);
-	timer_irq.inr = TIMER_IRQ;
-	timer_irq.claim = timer_claim;
-	timer_irq.handler = timer_irq_handler;
-	irq_register(&timer_irq);
+	int_handler[INT_TIMER] = timer_interrupt_handler;
 
 	timer_start();
-	cp0_unmask_int(TIMER_IRQ);
-
-#ifdef MACHINE_msim
-	irq_initialize(&dorder_irq);
-	dorder_irq.inr = DORDER_IRQ;
-	dorder_irq.claim = dorder_claim;
-	dorder_irq.handler = dorder_irq_handler;
-	irq_register(&dorder_irq);
-
-	cp0_unmask_int(DORDER_IRQ);
-#endif
+	cp0_unmask_int(INT_TIMER);
 }
 
Index: kernel/arch/mips32/src/mach/malta/malta.c
===================================================================
--- kernel/arch/mips32/src/mach/malta/malta.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/mips32/src/mach/malta/malta.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,4 +38,13 @@
 #include <console/chardev.h>
 #include <arch/mm/page.h>
+#include <genarch/drivers/i8259/i8259.h>
+#include <genarch/drivers/ns16550/ns16550.h>
+#include <genarch/srln/srln.h>
+#include <arch/interrupt.h>
+#include <stdbool.h>
+#include <byteorder.h>
+#include <sysinfo/sysinfo.h>
+#include <log.h>
+#include <str.h>
 
 static void malta_init(void);
@@ -57,6 +66,57 @@
 };
 
+#ifdef CONFIG_NS16550
+static ns16550_instance_t *tty_instance;
+#endif
+#ifdef CONFIG_NS16550_OUT
+static outdev_t *tty_out;
+#endif
+
+static void malta_isa_irq_handler(unsigned int i)
+{
+	uint8_t isa_irq = host2uint32_t_le(pio_read_32(GT64120_PCI0_INTACK));
+	if (pic_is_spurious(isa_irq)) {
+		pic_handle_spurious(isa_irq);
+#ifdef CONFIG_DEBUG
+		log(LF_ARCH, LVL_DEBUG, "cpu%u: PIC spurious interrupt %u",
+		    CPU->id, isa_irq);
+		return;
+#endif
+	}
+	irq_t *irq = irq_dispatch_and_lock(isa_irq);
+	if (irq) {
+		irq->handler(irq);
+		irq_spinlock_unlock(&irq->lock, false);
+	} else {
+#ifdef CONFIG_DEBUG
+		log(LF_ARCH, LVL_DEBUG, "cpu%u: unhandled IRQ (irq=%u)",
+		    CPU->id, isa_irq);
+#endif
+	}
+	pic_eoi(isa_irq);
+}
+
 void malta_init(void)
 {
+	irq_init(ISA_IRQ_COUNT, ISA_IRQ_COUNT);
+
+	i8259_init((i8259_t *) PIC0_BASE, (i8259_t *) PIC1_BASE, 0);
+	sysinfo_set_item_val("i8259", NULL, true);
+
+	int_handler[INT_HW0] = malta_isa_irq_handler;
+	cp0_unmask_int(INT_HW0);
+
+#if (defined(CONFIG_NS16550) || defined(CONFIG_NS16550_OUT))
+#ifdef CONFIG_NS16550_OUT
+	outdev_t **tty_out_ptr = &tty_out;
+#else
+	outdev_t **tty_out_ptr = NULL;
+#endif
+	tty_instance = ns16550_init((ioport8_t *) TTY_BASE, 0, TTY_ISA_IRQ,
+	    NULL, NULL, tty_out_ptr);
+#endif
+
+	const char *args = "console=devices/\\hw\\pci0\\00:0a.0\\com1\\a";
+	str_ncpy(bargs, CONFIG_BOOT_ARGUMENTS_BUFLEN, args, str_length(args));
 }
 
@@ -73,37 +133,25 @@
 }
 
-#define YAMON_SUBR_BASE         PA2KA(0x1fc00500)
-#define YAMON_SUBR_PRINT_COUNT  (YAMON_SUBR_BASE + 0x4)
-
-typedef void (**yamon_print_count_ptr_t)(uint32_t, const char *, uint32_t);
-
-yamon_print_count_ptr_t yamon_print_count =
-    (yamon_print_count_ptr_t) YAMON_SUBR_PRINT_COUNT;
-
-static void yamon_putwchar(outdev_t *dev, const wchar_t wch)
-{
-
-	const char ch = (char) wch;
-
-	(*yamon_print_count)(0, &ch, 1);
-}
-
-static outdev_t yamon_outdev;
-static outdev_operations_t yamon_outdev_ops = {
-	.write = yamon_putwchar,
-	.redraw = NULL,
-	.scroll_up = NULL,
-	.scroll_down = NULL
-};
-
 void malta_output_init(void)
 {
-	outdev_initialize("yamon", &yamon_outdev, &yamon_outdev_ops);
-	stdout_wire(&yamon_outdev);
+#ifdef CONFIG_NS16550_OUT
+	if (tty_out)
+		stdout_wire(tty_out);
+#endif
 }
 
 void malta_input_init(void)
 {
-	(void) stdin_wire();
+#ifdef CONFIG_NS16550
+	if (tty_instance) {
+		srln_instance_t *srln_instance = srln_init();
+		if (srln_instance) {
+			indev_t *sink = stdin_wire();
+			indev_t *srln = srln_wire(srln_instance, sink);
+			ns16550_wire(tty_instance, srln);
+			pic_enable_irqs(1 << TTY_ISA_IRQ);
+		}
+	}
+#endif
 }
 
Index: kernel/arch/mips32/src/mach/msim/dorder.c
===================================================================
--- kernel/arch/mips32/src/mach/msim/dorder.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/mips32/src/mach/msim/dorder.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2007 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 kernel_mips32
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/mach/msim/dorder.h>
+#include <arch/mach/msim/msim.h>
+#include <stdint.h>
+#include <smp/ipi.h>
+#include <interrupt.h>
+#include <arch/asm.h>
+#include <typedefs.h>
+
+static irq_t dorder_irq;
+
+#ifdef CONFIG_SMP
+
+void ipi_broadcast_arch(int ipi)
+{
+	pio_write_32(((ioport32_t *) MSIM_DORDER_ADDRESS), 0x7fffffff);
+}
+
+#endif
+
+static irq_ownership_t dorder_claim(irq_t *irq)
+{
+	return IRQ_ACCEPT;
+}
+
+static void dorder_irq_handler(irq_t *irq)
+{
+	dorder_ipi_ack(1 << dorder_cpuid());
+}
+
+void dorder_init(void)
+{
+	irq_initialize(&dorder_irq);
+	dorder_irq.inr = MSIM_DORDER_IRQ;
+	dorder_irq.claim = dorder_claim;
+	dorder_irq.handler = dorder_irq_handler;
+	irq_register(&dorder_irq);
+
+	cp0_unmask_int(MSIM_DORDER_IRQ);
+}
+
+uint32_t dorder_cpuid(void)
+{
+	return pio_read_32((ioport32_t *) MSIM_DORDER_ADDRESS);
+}
+
+void dorder_ipi_ack(uint32_t mask)
+{
+	pio_write_32((ioport32_t *) (MSIM_DORDER_ADDRESS + 4), mask);
+}
+
+/** @}
+ */
Index: kernel/arch/mips32/src/mach/msim/msim.c
===================================================================
--- kernel/arch/mips32/src/mach/msim/msim.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/mips32/src/mach/msim/msim.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,10 +35,11 @@
 
 #include <arch/mach/msim/msim.h>
+#include <arch/mach/msim/dorder.h>
 #include <console/console.h>
 #include <sysinfo/sysinfo.h>
-#include <arch/drivers/msim.h>
 #include <genarch/drivers/dsrln/dsrlnin.h>
 #include <genarch/drivers/dsrln/dsrlnout.h>
 #include <genarch/srln/srln.h>
+#include <stdbool.h>
 
 static void msim_init(void);
@@ -60,6 +61,29 @@
 };
 
+static void msim_irq_handler(unsigned int i)
+{
+	irq_t *irq = irq_dispatch_and_lock(i);
+	if (irq) {
+		irq->handler(irq);
+		irq_spinlock_unlock(&irq->lock, false);
+	} else {
+#ifdef CONFIG_DEBUG
+		log(LF_ARCH, LVL_DEBUG, "cpu%u: spurious IRQ (irq=%u)",
+		    CPU->id, i);
+#endif
+	}
+}
+
 void msim_init(void)
 {
+	irq_init(HW_INTERRUPTS, HW_INTERRUPTS);
+
+	int_handler[INT_HW0] = msim_irq_handler;
+	int_handler[INT_HW1] = msim_irq_handler;
+	int_handler[INT_HW2] = msim_irq_handler;
+	int_handler[INT_HW3] = msim_irq_handler;
+	int_handler[INT_HW4] = msim_irq_handler;
+
+	dorder_init();
 	cp0_unmask_int(MSIM_DDISK_IRQ);
 }
@@ -80,5 +104,6 @@
 {
 #ifdef CONFIG_MSIM_PRN
-	outdev_t *dsrlndev = dsrlnout_init((ioport8_t *) MSIM_KBD_ADDRESS);
+	outdev_t *dsrlndev = dsrlnout_init((ioport8_t *) MSIM_KBD_ADDRESS,
+	    KSEG12PA(MSIM_KBD_ADDRESS));
 	if (dsrlndev)
 		stdout_wire(dsrlndev);
Index: kernel/arch/mips32/src/mm/frame.c
===================================================================
--- kernel/arch/mips32/src/mm/frame.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/mips32/src/mm/frame.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -41,5 +41,5 @@
 #include <config.h>
 #ifdef MACHINE_msim
-#include <arch/drivers/msim.h>
+#include <arch/mach/msim/msim.h>
 #endif
 #include <arch/arch.h>
@@ -57,5 +57,5 @@
 
 #define ZERO_PAGE_VALUE_KSEG1(frame) \
-	(((volatile uint32_t *) (0xa0000000 + (frame << ZERO_PAGE_WIDTH)))[ZERO_PAGE_OFFSET])
+	(((volatile uint32_t *) PA2KSEG1(frame << ZERO_PAGE_WIDTH))[ZERO_PAGE_OFFSET])
 
 #define MAX_REGIONS  32
@@ -80,9 +80,9 @@
 #ifdef MACHINE_msim
 	/* MSIM device (dprinter) */
-	if (frame == (KA2PA(MSIM_VIDEORAM) >> ZERO_PAGE_WIDTH))
+	if (frame == (KSEG12PA(MSIM_VIDEORAM) >> ZERO_PAGE_WIDTH))
 		return false;
 
 	/* MSIM device (dkeyboard) */
-	if (frame == (KA2PA(MSIM_KBD_ADDRESS) >> ZERO_PAGE_WIDTH))
+	if (frame == (KSEG12PA(MSIM_KBD_ADDRESS) >> ZERO_PAGE_WIDTH))
 		return false;
 #endif
Index: rnel/arch/mips32/src/smp/dorder.c
===================================================================
--- kernel/arch/mips32/src/smp/dorder.c	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,61 +1,0 @@
-/*
- * Copyright (c) 2007 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 kernel_mips32
- * @{
- */
-/** @file
- */
-
-#include <stdint.h>
-#include <smp/ipi.h>
-#include <arch/smp/dorder.h>
-
-#define MSIM_DORDER_ADDRESS  0xB0000100
-
-#ifdef CONFIG_SMP
-
-void ipi_broadcast_arch(int ipi)
-{
-	*((volatile uint32_t *) MSIM_DORDER_ADDRESS) = 0x7fffffff;
-}
-
-#endif
-
-uint32_t dorder_cpuid(void)
-{
-	return *((volatile uint32_t *) MSIM_DORDER_ADDRESS);
-}
-
-void dorder_ipi_ack(uint32_t mask)
-{
-	*((volatile uint32_t *) (MSIM_DORDER_ADDRESS + 4)) = mask;
-}
-
-/** @}
- */
Index: kernel/arch/ppc32/include/arch/asm.h
===================================================================
--- kernel/arch/ppc32/include/arch/asm.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ppc32/include/arch/asm.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -42,5 +42,5 @@
 #include <trace.h>
 
-NO_TRACE static inline uint32_t msr_read(void)
+_NO_TRACE static inline uint32_t msr_read(void)
 {
 	uint32_t msr;
@@ -54,5 +54,5 @@
 }
 
-NO_TRACE static inline void msr_write(uint32_t msr)
+_NO_TRACE static inline void msr_write(uint32_t msr)
 {
 	asm volatile (
@@ -63,5 +63,5 @@
 }
 
-NO_TRACE static inline void sr_set(uint32_t flags, asid_t asid, uint32_t sr)
+_NO_TRACE static inline void sr_set(uint32_t flags, asid_t asid, uint32_t sr)
 {
 	asm volatile (
@@ -74,5 +74,5 @@
 }
 
-NO_TRACE static inline uint32_t sr_get(uint32_t vaddr)
+_NO_TRACE static inline uint32_t sr_get(uint32_t vaddr)
 {
 	uint32_t vsid;
@@ -87,5 +87,5 @@
 }
 
-NO_TRACE static inline uint32_t sdr1_get(void)
+_NO_TRACE static inline uint32_t sdr1_get(void)
 {
 	uint32_t sdr1;
@@ -107,5 +107,5 @@
  *
  */
-NO_TRACE static inline ipl_t interrupts_enable(void)
+_NO_TRACE static inline ipl_t interrupts_enable(void)
 {
 	ipl_t ipl = msr_read();
@@ -122,5 +122,5 @@
  *
  */
-NO_TRACE static inline ipl_t interrupts_disable(void)
+_NO_TRACE static inline ipl_t interrupts_disable(void)
 {
 	ipl_t ipl = msr_read();
@@ -136,5 +136,5 @@
  *
  */
-NO_TRACE static inline void interrupts_restore(ipl_t ipl)
+_NO_TRACE static inline void interrupts_restore(ipl_t ipl)
 {
 	msr_write((msr_read() & (~MSR_EE)) | (ipl & MSR_EE));
@@ -148,5 +148,5 @@
  *
  */
-NO_TRACE static inline ipl_t interrupts_read(void)
+_NO_TRACE static inline ipl_t interrupts_read(void)
 {
 	return msr_read();
@@ -158,5 +158,5 @@
  *
  */
-NO_TRACE static inline bool interrupts_disabled(void)
+_NO_TRACE static inline bool interrupts_disabled(void)
 {
 	return ((msr_read() & MSR_EE) == 0);
@@ -170,5 +170,5 @@
  *
  */
-NO_TRACE static inline uintptr_t get_stack_base(void)
+_NO_TRACE static inline uintptr_t get_stack_base(void)
 {
 	uintptr_t base;
@@ -183,34 +183,34 @@
 }
 
-NO_TRACE static inline void cpu_sleep(void)
-{
-}
-
-NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t v)
+_NO_TRACE static inline void cpu_sleep(void)
+{
+}
+
+_NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t v)
 {
 	*port = v;
 }
 
-NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t v)
+_NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t v)
 {
 	*port = v;
 }
 
-NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t v)
+_NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t v)
 {
 	*port = v;
 }
 
-NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
+_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)
+_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)
+_NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
 {
 	return *port;
Index: kernel/arch/ppc32/include/arch/cpu.h
===================================================================
--- kernel/arch/ppc32/include/arch/cpu.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ppc32/include/arch/cpu.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -44,5 +44,5 @@
 } __attribute__((packed)) cpu_arch_t;
 
-NO_TRACE static inline void cpu_version(cpu_arch_t *info)
+_NO_TRACE static inline void cpu_version(cpu_arch_t *info)
 {
 	asm volatile (
Index: kernel/arch/ppc32/include/arch/cycle.h
===================================================================
--- kernel/arch/ppc32/include/arch/cycle.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ppc32/include/arch/cycle.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,5 +38,5 @@
 #include <trace.h>
 
-NO_TRACE static inline uint64_t get_cycle(void)
+_NO_TRACE static inline uint64_t get_cycle(void)
 {
 	uint32_t lower;
Index: kernel/arch/ppc32/include/arch/istate.h
===================================================================
--- kernel/arch/ppc32/include/arch/istate.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ppc32/include/arch/istate.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -50,5 +50,5 @@
 #endif /* KERNEL */
 
-NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
+_NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
     uintptr_t retaddr)
 {
@@ -61,15 +61,15 @@
  *
  */
-NO_TRACE static inline int istate_from_uspace(istate_t *istate)
+_NO_TRACE static inline int istate_from_uspace(istate_t *istate)
 {
 	return (istate->srr1 & MSR_PR) != 0;
 }
 
-NO_TRACE static inline sysarg_t istate_get_pc(istate_t *istate)
+_NO_TRACE static inline sysarg_t istate_get_pc(istate_t *istate)
 {
 	return istate->pc;
 }
 
-NO_TRACE static inline sysarg_t istate_get_fp(istate_t *istate)
+_NO_TRACE static inline sysarg_t istate_get_fp(istate_t *istate)
 {
 	return istate->sp;
Index: kernel/arch/ppc32/include/arch/istate_struct.h
===================================================================
--- kernel/arch/ppc32/include/arch/istate_struct.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ppc32/include/arch/istate_struct.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -86,5 +86,5 @@
 	/* imitation of frame pointer linkage */
 	uint32_t sp_frame;
-	/* imitation of return adress linkage */
+	/* imitation of return address linkage */
 	uint32_t lr_frame;
 	uint32_t r0;
Index: kernel/arch/ppc32/include/arch/mm/as.h
===================================================================
--- kernel/arch/ppc32/include/arch/mm/as.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ppc32/include/arch/mm/as.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,4 +39,5 @@
 
 #define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH  0
+#define KERNEL_SEPARATE_PTL0_ARCH           0
 
 #define KERNEL_ADDRESS_SPACE_START_ARCH  UINT32_C(0x80000000)
Index: kernel/arch/ppc32/include/arch/mm/frame.h
===================================================================
--- kernel/arch/ppc32/include/arch/mm/frame.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ppc32/include/arch/mm/frame.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -46,5 +46,5 @@
 #include <trace.h>
 
-NO_TRACE static inline uint32_t physmem_top(void)
+_NO_TRACE static inline uint32_t physmem_top(void)
 {
 	uint32_t physmem;
Index: kernel/arch/ppc32/include/arch/mm/page.h
===================================================================
--- kernel/arch/ppc32/include/arch/mm/page.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ppc32/include/arch/mm/page.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -162,5 +162,5 @@
 } pte_t;
 
-NO_TRACE static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
+_NO_TRACE static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
 {
 	pte_t *entry = &pt[i];
@@ -175,5 +175,5 @@
 }
 
-NO_TRACE static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
+_NO_TRACE static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
 {
 	pte_t *entry = &pt[i];
@@ -185,5 +185,5 @@
 }
 
-NO_TRACE static inline void set_pt_present(pte_t *pt, size_t i)
+_NO_TRACE static inline void set_pt_present(pte_t *pt, size_t i)
 {
 	pte_t *entry = &pt[i];
Index: kernel/arch/ppc32/src/drivers/pic.c
===================================================================
--- kernel/arch/ppc32/src/drivers/pic.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ppc32/src/drivers/pic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,6 +37,7 @@
 #include <byteorder.h>
 #include <bitops.h>
+#include <typedefs.h>
 
-static volatile uint32_t *pic = NULL;
+static ioport32_t *pic = NULL;
 
 void pic_init(uintptr_t base, size_t size, cir_t *cir, void **cir_arg)
@@ -50,20 +51,27 @@
 void pic_enable_interrupt(inr_t intnum)
 {
-	if (pic) {
-		if (intnum < 32)
-			pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] | (1 << intnum);
-		else
-			pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] | (1 << (intnum - 32));
+	if (!pic)
+		return;
+
+	if (intnum < 32) {
+		pio_write_32(&pic[PIC_MASK_LOW],
+		    pio_read_32(&pic[PIC_MASK_LOW]) | (1 << intnum));
+	} else {
+		pio_write_32(&pic[PIC_MASK_HIGH],
+		    pio_read_32(&pic[PIC_MASK_HIGH]) | (1 << (intnum - 32)));
 	}
-
 }
 
 void pic_disable_interrupt(inr_t intnum)
 {
-	if (pic) {
-		if (intnum < 32)
-			pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] & (~(1 << intnum));
-		else
-			pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] & (~(1 << (intnum - 32)));
+	if (!pic)
+		return;
+
+	if (intnum < 32) {
+		pio_write_32(&pic[PIC_MASK_LOW],
+		    pio_read_32(&pic[PIC_MASK_LOW]) & (~(1 << intnum)));
+	} else {
+		pio_write_32(&pic[PIC_MASK_HIGH],
+		    pio_read_32(&pic[PIC_MASK_HIGH]) & (~(1 << (intnum - 32))));
 	}
 }
@@ -71,9 +79,11 @@
 void pic_ack_interrupt(void *arg, inr_t intnum)
 {
-	if (pic) {
-		if (intnum < 32)
-			pic[PIC_ACK_LOW] = 1 << intnum;
-		else
-			pic[PIC_ACK_HIGH] = 1 << (intnum - 32);
+	if (!pic)
+		return;
+
+	if (intnum < 32) {
+		pio_write_32(&pic[PIC_ACK_LOW], 1 << intnum);
+	} else {
+		pio_write_32(&pic[PIC_ACK_HIGH], 1 << (intnum - 32));
 	}
 }
@@ -87,9 +97,9 @@
 		uint32_t pending;
 
-		pending = pic[PIC_PENDING_LOW];
+		pending = pio_read_32(&pic[PIC_PENDING_LOW]);
 		if (pending != 0)
 			return fnzb32(pending);
 
-		pending = pic[PIC_PENDING_HIGH];
+		pending = pio_read_32(&pic[PIC_PENDING_HIGH]);
 		if (pending != 0)
 			return fnzb32(pending) + 32;
Index: kernel/arch/ppc32/src/interrupt.c
===================================================================
--- kernel/arch/ppc32/src/interrupt.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/ppc32/src/interrupt.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -141,4 +141,6 @@
 			    " (inum=%" PRIu8 ")", CPU->id, inum);
 #endif
+			pic_ack_interrupt(NULL, inum);
+			break;
 		}
 	}
Index: kernel/arch/riscv64/include/arch/asm.h
===================================================================
--- kernel/arch/riscv64/include/arch/asm.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/riscv64/include/arch/asm.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -42,5 +42,5 @@
 #include <trace.h>
 
-NO_TRACE static inline ipl_t interrupts_enable(void)
+_NO_TRACE static inline ipl_t interrupts_enable(void)
 {
 	ipl_t ipl;
@@ -54,5 +54,5 @@
 }
 
-NO_TRACE static inline ipl_t interrupts_disable(void)
+_NO_TRACE static inline ipl_t interrupts_disable(void)
 {
 	ipl_t ipl;
@@ -66,5 +66,5 @@
 }
 
-NO_TRACE static inline void interrupts_restore(ipl_t ipl)
+_NO_TRACE static inline void interrupts_restore(ipl_t ipl)
 {
 	if ((ipl & SSTATUS_SIE_MASK) == SSTATUS_SIE_MASK)
@@ -74,5 +74,5 @@
 }
 
-NO_TRACE static inline ipl_t interrupts_read(void)
+_NO_TRACE static inline ipl_t interrupts_read(void)
 {
 	ipl_t ipl;
@@ -86,10 +86,10 @@
 }
 
-NO_TRACE static inline bool interrupts_disabled(void)
+_NO_TRACE static inline bool interrupts_disabled(void)
 {
 	return ((interrupts_read() & SSTATUS_SIE_MASK) == 0);
 }
 
-NO_TRACE static inline uintptr_t get_stack_base(void)
+_NO_TRACE static inline uintptr_t get_stack_base(void)
 {
 	uintptr_t base;
@@ -104,34 +104,34 @@
 }
 
-NO_TRACE static inline void cpu_sleep(void)
+_NO_TRACE static inline void cpu_sleep(void)
 {
 }
 
-NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t v)
+_NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t v)
 {
 	*port = v;
 }
 
-NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t v)
+_NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t v)
 {
 	*port = v;
 }
 
-NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t v)
+_NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t v)
 {
 	*port = v;
 }
 
-NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
+_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)
+_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)
+_NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
 {
 	return *port;
Index: kernel/arch/riscv64/include/arch/cycle.h
===================================================================
--- kernel/arch/riscv64/include/arch/cycle.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/riscv64/include/arch/cycle.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,5 +38,5 @@
 #include <trace.h>
 
-NO_TRACE static inline uint64_t get_cycle(void)
+_NO_TRACE static inline uint64_t get_cycle(void)
 {
 	uint64_t cycle;
Index: kernel/arch/riscv64/include/arch/istate.h
===================================================================
--- kernel/arch/riscv64/include/arch/istate.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/riscv64/include/arch/istate.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -44,5 +44,5 @@
 #endif
 
-NO_TRACE static inline int istate_from_uspace(istate_t *istate)
+_NO_TRACE static inline int istate_from_uspace(istate_t *istate)
 {
 	// FIXME
@@ -50,5 +50,5 @@
 }
 
-NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
+_NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
     uintptr_t retaddr)
 {
@@ -56,5 +56,5 @@
 }
 
-NO_TRACE static inline uintptr_t istate_get_pc(istate_t *istate)
+_NO_TRACE static inline uintptr_t istate_get_pc(istate_t *istate)
 {
 	// FIXME
@@ -62,5 +62,5 @@
 }
 
-NO_TRACE static inline uintptr_t istate_get_fp(istate_t *istate)
+_NO_TRACE static inline uintptr_t istate_get_fp(istate_t *istate)
 {
 	// FIXME
Index: kernel/arch/riscv64/include/arch/mm/as.h
===================================================================
--- kernel/arch/riscv64/include/arch/mm/as.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/riscv64/include/arch/mm/as.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -40,4 +40,5 @@
 
 #define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH  0
+#define KERNEL_SEPARATE_PTL0_ARCH           0
 
 #define KERNEL_ADDRESS_SPACE_START_ARCH  UINT64_C(0xffff800000000000)
Index: kernel/arch/riscv64/include/arch/mm/page.h
===================================================================
--- kernel/arch/riscv64/include/arch/mm/page.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/riscv64/include/arch/mm/page.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -179,5 +179,5 @@
 } pte_t;
 
-NO_TRACE static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
+_NO_TRACE static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
 {
 	pte_t *entry = &pt[i];
@@ -191,5 +191,5 @@
 }
 
-NO_TRACE static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
+_NO_TRACE static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
 {
 	pte_t *entry = &pt[i];
@@ -205,5 +205,5 @@
 }
 
-NO_TRACE static inline void set_pt_present(pte_t *pt, size_t i)
+_NO_TRACE static inline void set_pt_present(pte_t *pt, size_t i)
 {
 	pte_t *entry = &pt[i];
Index: kernel/arch/sparc64/Makefile.inc
===================================================================
--- kernel/arch/sparc64/Makefile.inc	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/sparc64/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -82,4 +82,5 @@
 	arch/$(KARCH)/src/drivers/tick.c \
 	arch/$(KARCH)/src/drivers/kbd.c \
+	arch/$(KARCH)/src/drivers/tty.c \
 	arch/$(KARCH)/src/drivers/pci.c \
 	arch/$(KARCH)/src/trap/$(USARCH)/interrupt.c
Index: kernel/arch/sparc64/include/arch/asm.h
===================================================================
--- kernel/arch/sparc64/include/arch/asm.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/sparc64/include/arch/asm.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -44,5 +44,5 @@
 #include <trace.h>
 
-NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t v)
+_NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t v)
 {
 	*port = v;
@@ -50,5 +50,5 @@
 }
 
-NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t v)
+_NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t v)
 {
 	*port = v;
@@ -56,5 +56,5 @@
 }
 
-NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t v)
+_NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t v)
 {
 	*port = v;
@@ -62,5 +62,5 @@
 }
 
-NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
+_NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
 {
 	uint8_t rv = *port;
@@ -69,5 +69,5 @@
 }
 
-NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port)
+_NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port)
 {
 	uint16_t rv = *port;
@@ -76,5 +76,5 @@
 }
 
-NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
+_NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
 {
 	uint32_t rv = *port;
@@ -88,5 +88,5 @@
  *
  */
-NO_TRACE static inline uint64_t pstate_read(void)
+_NO_TRACE static inline uint64_t pstate_read(void)
 {
 	uint64_t v;
@@ -105,5 +105,5 @@
  *
  */
-NO_TRACE static inline void pstate_write(uint64_t v)
+_NO_TRACE static inline void pstate_write(uint64_t v)
 {
 	asm volatile (
@@ -119,5 +119,5 @@
  *
  */
-NO_TRACE static inline uint64_t tick_compare_read(void)
+_NO_TRACE static inline uint64_t tick_compare_read(void)
 {
 	uint64_t v;
@@ -136,5 +136,5 @@
  *
  */
-NO_TRACE static inline void tick_compare_write(uint64_t v)
+_NO_TRACE static inline void tick_compare_write(uint64_t v)
 {
 	asm volatile (
@@ -150,5 +150,5 @@
  *
  */
-NO_TRACE static inline uint64_t stick_compare_read(void)
+_NO_TRACE static inline uint64_t stick_compare_read(void)
 {
 	uint64_t v;
@@ -167,5 +167,5 @@
  *
  */
-NO_TRACE static inline void stick_compare_write(uint64_t v)
+_NO_TRACE static inline void stick_compare_write(uint64_t v)
 {
 	asm volatile (
@@ -181,5 +181,5 @@
  *
  */
-NO_TRACE static inline uint64_t tick_read(void)
+_NO_TRACE static inline uint64_t tick_read(void)
 {
 	uint64_t v;
@@ -198,5 +198,5 @@
  *
  */
-NO_TRACE static inline void tick_write(uint64_t v)
+_NO_TRACE static inline void tick_write(uint64_t v)
 {
 	asm volatile (
@@ -212,5 +212,5 @@
  *
  */
-NO_TRACE static inline uint64_t fprs_read(void)
+_NO_TRACE static inline uint64_t fprs_read(void)
 {
 	uint64_t v;
@@ -229,5 +229,5 @@
  *
  */
-NO_TRACE static inline void fprs_write(uint64_t v)
+_NO_TRACE static inline void fprs_write(uint64_t v)
 {
 	asm volatile (
@@ -243,5 +243,5 @@
  *
  */
-NO_TRACE static inline uint64_t softint_read(void)
+_NO_TRACE static inline uint64_t softint_read(void)
 {
 	uint64_t v;
@@ -260,5 +260,5 @@
  *
  */
-NO_TRACE static inline void softint_write(uint64_t v)
+_NO_TRACE static inline void softint_write(uint64_t v)
 {
 	asm volatile (
@@ -276,5 +276,5 @@
  *
  */
-NO_TRACE static inline void clear_softint_write(uint64_t v)
+_NO_TRACE static inline void clear_softint_write(uint64_t v)
 {
 	asm volatile (
@@ -292,5 +292,5 @@
  *
  */
-NO_TRACE static inline void set_softint_write(uint64_t v)
+_NO_TRACE static inline void set_softint_write(uint64_t v)
 {
 	asm volatile (
@@ -309,5 +309,5 @@
  *
  */
-NO_TRACE static inline ipl_t interrupts_enable(void)
+_NO_TRACE static inline ipl_t interrupts_enable(void)
 {
 	pstate_reg_t pstate;
@@ -329,5 +329,5 @@
  *
  */
-NO_TRACE static inline ipl_t interrupts_disable(void)
+_NO_TRACE static inline ipl_t interrupts_disable(void)
 {
 	pstate_reg_t pstate;
@@ -348,5 +348,5 @@
  *
  */
-NO_TRACE static inline void interrupts_restore(ipl_t ipl)
+_NO_TRACE static inline void interrupts_restore(ipl_t ipl)
 {
 	pstate_reg_t pstate;
@@ -364,5 +364,5 @@
  *
  */
-NO_TRACE static inline ipl_t interrupts_read(void)
+_NO_TRACE static inline ipl_t interrupts_read(void)
 {
 	return (ipl_t) pstate_read();
@@ -374,5 +374,5 @@
  *
  */
-NO_TRACE static inline bool interrupts_disabled(void)
+_NO_TRACE static inline bool interrupts_disabled(void)
 {
 	pstate_reg_t pstate;
@@ -389,5 +389,5 @@
  *
  */
-NO_TRACE static inline uintptr_t get_stack_base(void)
+_NO_TRACE static inline uintptr_t get_stack_base(void)
 {
 	uintptr_t unbiased_sp;
@@ -407,5 +407,5 @@
  *
  */
-NO_TRACE static inline uint64_t ver_read(void)
+_NO_TRACE static inline uint64_t ver_read(void)
 {
 	uint64_t v;
@@ -424,5 +424,5 @@
  *
  */
-NO_TRACE static inline uint64_t tpc_read(void)
+_NO_TRACE static inline uint64_t tpc_read(void)
 {
 	uint64_t v;
@@ -441,5 +441,5 @@
  *
  */
-NO_TRACE static inline uint64_t tl_read(void)
+_NO_TRACE static inline uint64_t tl_read(void)
 {
 	uint64_t v;
@@ -458,5 +458,5 @@
  *
  */
-NO_TRACE static inline uint64_t tba_read(void)
+_NO_TRACE static inline uint64_t tba_read(void)
 {
 	uint64_t v;
@@ -475,5 +475,5 @@
  *
  */
-NO_TRACE static inline void tba_write(uint64_t v)
+_NO_TRACE static inline void tba_write(uint64_t v)
 {
 	asm volatile (
@@ -493,5 +493,5 @@
  *
  */
-NO_TRACE static inline uint64_t asi_u64_read(asi_t asi, uintptr_t va)
+_NO_TRACE static inline uint64_t asi_u64_read(asi_t asi, uintptr_t va)
 {
 	uint64_t v;
@@ -514,5 +514,5 @@
  *
  */
-NO_TRACE static inline void asi_u64_write(asi_t asi, uintptr_t va, uint64_t v)
+_NO_TRACE static inline void asi_u64_write(asi_t asi, uintptr_t va, uint64_t v)
 {
 	asm volatile (
@@ -526,5 +526,5 @@
 
 /** Flush all valid register windows to memory. */
-NO_TRACE static inline void flushw(void)
+_NO_TRACE static inline void flushw(void)
 {
 	asm volatile ("flushw\n");
@@ -532,5 +532,5 @@
 
 /** Switch to nucleus by setting TL to 1. */
-NO_TRACE static inline void nucleus_enter(void)
+_NO_TRACE static inline void nucleus_enter(void)
 {
 	asm volatile ("wrpr %g0, 1, %tl\n");
@@ -538,5 +538,5 @@
 
 /** Switch from nucleus by setting TL to 0. */
-NO_TRACE static inline void nucleus_leave(void)
+_NO_TRACE static inline void nucleus_leave(void)
 {
 	asm volatile ("wrpr %g0, %g0, %tl\n");
Index: kernel/arch/sparc64/include/arch/barrier.h
===================================================================
--- kernel/arch/sparc64/include/arch/barrier.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/sparc64/include/arch/barrier.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,5 +39,5 @@
 
 /** Flush Instruction pipeline. */
-NO_TRACE static inline void flush_pipeline(void)
+_NO_TRACE static inline void flush_pipeline(void)
 {
 	unsigned long pc;
@@ -62,5 +62,5 @@
 
 /** Memory Barrier instruction. */
-NO_TRACE static inline void membar(void)
+_NO_TRACE static inline void membar(void)
 {
 	asm volatile (
Index: kernel/arch/sparc64/include/arch/cycle.h
===================================================================
--- kernel/arch/sparc64/include/arch/cycle.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/sparc64/include/arch/cycle.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,5 +39,5 @@
 #include <trace.h>
 
-NO_TRACE static inline uint64_t get_cycle(void)
+_NO_TRACE static inline uint64_t get_cycle(void)
 {
 	return tick_read();
Index: kernel/arch/sparc64/include/arch/drivers/tty.h
===================================================================
--- kernel/arch/sparc64/include/arch/drivers/tty.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/sparc64/include/arch/drivers/tty.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2019 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 kernel_sparc64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_sparc64_TTY_H_
+#define KERN_sparc64_TTY_H_
+
+#include <genarch/ofw/ofw_tree.h>
+
+extern void tty_init(ofw_tree_node_t *node);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/sparc64/include/arch/istate.h
===================================================================
--- kernel/arch/sparc64/include/arch/istate.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/sparc64/include/arch/istate.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -51,5 +51,5 @@
 #endif /* KERNEL */
 
-NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
+_NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
     uintptr_t retaddr)
 {
@@ -57,15 +57,15 @@
 }
 
-NO_TRACE static inline int istate_from_uspace(istate_t *istate)
+_NO_TRACE static inline int istate_from_uspace(istate_t *istate)
 {
 	return !(istate->tstate & TSTATE_PRIV_BIT);
 }
 
-NO_TRACE static inline uintptr_t istate_get_pc(istate_t *istate)
+_NO_TRACE static inline uintptr_t istate_get_pc(istate_t *istate)
 {
 	return istate->tpc;
 }
 
-NO_TRACE static inline uintptr_t istate_get_fp(istate_t *istate)
+_NO_TRACE static inline uintptr_t istate_get_fp(istate_t *istate)
 {
 	/* TODO */
Index: kernel/arch/sparc64/include/arch/mm/sun4u/as.h
===================================================================
--- kernel/arch/sparc64/include/arch/mm/sun4u/as.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/sparc64/include/arch/mm/sun4u/as.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,4 +39,5 @@
 
 #define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH  1
+#define KERNEL_SEPARATE_PTL0_ARCH           0
 
 #define KERNEL_ADDRESS_SPACE_START_ARCH  UINT64_C(0x0000000000000000)
Index: kernel/arch/sparc64/include/arch/mm/sun4u/tlb.h
===================================================================
--- kernel/arch/sparc64/include/arch/mm/sun4u/tlb.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/sparc64/include/arch/mm/sun4u/tlb.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -243,5 +243,5 @@
  * Determine the number of entries in the DMMU's small TLB.
  */
-NO_TRACE static inline uint16_t tlb_dsmall_size(void)
+_NO_TRACE static inline uint16_t tlb_dsmall_size(void)
 {
 	return 16;
@@ -251,5 +251,5 @@
  * Determine the number of entries in each DMMU's big TLB.
  */
-NO_TRACE static inline uint16_t tlb_dbig_size(void)
+_NO_TRACE static inline uint16_t tlb_dbig_size(void)
 {
 	return 512;
@@ -259,5 +259,5 @@
  * Determine the number of entries in the IMMU's small TLB.
  */
-NO_TRACE static inline uint16_t tlb_ismall_size(void)
+_NO_TRACE static inline uint16_t tlb_ismall_size(void)
 {
 	return 16;
@@ -267,5 +267,5 @@
  * Determine the number of entries in the IMMU's big TLB.
  */
-NO_TRACE static inline uint16_t tlb_ibig_size(void)
+_NO_TRACE static inline uint16_t tlb_ibig_size(void)
 {
 	if (((ver_reg_t) ver_read()).impl == IMPL_ULTRASPARCIV_PLUS)
@@ -281,5 +281,5 @@
  * @return		Current value of Primary Context Register.
  */
-NO_TRACE static inline uint64_t mmu_primary_context_read(void)
+_NO_TRACE static inline uint64_t mmu_primary_context_read(void)
 {
 	return asi_u64_read(ASI_DMMU, VA_PRIMARY_CONTEXT_REG);
@@ -290,5 +290,5 @@
  * @param v		New value of Primary Context Register.
  */
-NO_TRACE static inline void mmu_primary_context_write(uint64_t v)
+_NO_TRACE static inline void mmu_primary_context_write(uint64_t v)
 {
 	asi_u64_write(ASI_DMMU, VA_PRIMARY_CONTEXT_REG, v);
@@ -300,5 +300,5 @@
  * @return		Current value of Secondary Context Register.
  */
-NO_TRACE static inline uint64_t mmu_secondary_context_read(void)
+_NO_TRACE static inline uint64_t mmu_secondary_context_read(void)
 {
 	return asi_u64_read(ASI_DMMU, VA_SECONDARY_CONTEXT_REG);
@@ -309,5 +309,5 @@
  * @param v		New value of Primary Context Register.
  */
-NO_TRACE static inline void mmu_secondary_context_write(uint64_t v)
+_NO_TRACE static inline void mmu_secondary_context_write(uint64_t v)
 {
 	asi_u64_write(ASI_DMMU, VA_SECONDARY_CONTEXT_REG, v);
@@ -324,5 +324,5 @@
  * 			Register.
  */
-NO_TRACE static inline uint64_t itlb_data_access_read(size_t entry)
+_NO_TRACE static inline uint64_t itlb_data_access_read(size_t entry)
 {
 	itlb_data_access_addr_t reg;
@@ -338,5 +338,5 @@
  * @param value		Value to be written.
  */
-NO_TRACE static inline void itlb_data_access_write(size_t entry, uint64_t value)
+_NO_TRACE static inline void itlb_data_access_write(size_t entry, uint64_t value)
 {
 	itlb_data_access_addr_t reg;
@@ -355,5 +355,5 @@
  * 			Register.
  */
-NO_TRACE static inline uint64_t dtlb_data_access_read(size_t entry)
+_NO_TRACE static inline uint64_t dtlb_data_access_read(size_t entry)
 {
 	dtlb_data_access_addr_t reg;
@@ -369,5 +369,5 @@
  * @param value		Value to be written.
  */
-NO_TRACE static inline void dtlb_data_access_write(size_t entry, uint64_t value)
+_NO_TRACE static inline void dtlb_data_access_write(size_t entry, uint64_t value)
 {
 	dtlb_data_access_addr_t reg;
@@ -385,5 +385,5 @@
  * @return		Current value of specified IMMU TLB Tag Read Register.
  */
-NO_TRACE static inline uint64_t itlb_tag_read_read(size_t entry)
+_NO_TRACE static inline uint64_t itlb_tag_read_read(size_t entry)
 {
 	itlb_tag_read_addr_t tag;
@@ -400,5 +400,5 @@
  * @return		Current value of specified DMMU TLB Tag Read Register.
  */
-NO_TRACE static inline uint64_t dtlb_tag_read_read(size_t entry)
+_NO_TRACE static inline uint64_t dtlb_tag_read_read(size_t entry)
 {
 	dtlb_tag_read_addr_t tag;
@@ -419,5 +419,5 @@
  * 			Register.
  */
-NO_TRACE static inline uint64_t itlb_data_access_read(int tlb, size_t entry)
+_NO_TRACE static inline uint64_t itlb_data_access_read(int tlb, size_t entry)
 {
 	itlb_data_access_addr_t reg;
@@ -434,5 +434,5 @@
  * @param value		Value to be written.
  */
-NO_TRACE static inline void itlb_data_access_write(int tlb, size_t entry,
+_NO_TRACE static inline void itlb_data_access_write(int tlb, size_t entry,
     uint64_t value)
 {
@@ -454,5 +454,5 @@
  * 			Register.
  */
-NO_TRACE static inline uint64_t dtlb_data_access_read(int tlb, size_t entry)
+_NO_TRACE static inline uint64_t dtlb_data_access_read(int tlb, size_t entry)
 {
 	dtlb_data_access_addr_t reg;
@@ -470,5 +470,5 @@
  * @param value		Value to be written.
  */
-NO_TRACE static inline void dtlb_data_access_write(int tlb, size_t entry,
+_NO_TRACE static inline void dtlb_data_access_write(int tlb, size_t entry,
     uint64_t value)
 {
@@ -489,5 +489,5 @@
  * @return		Current value of specified IMMU TLB Tag Read Register.
  */
-NO_TRACE static inline uint64_t itlb_tag_read_read(int tlb, size_t entry)
+_NO_TRACE static inline uint64_t itlb_tag_read_read(int tlb, size_t entry)
 {
 	itlb_tag_read_addr_t tag;
@@ -506,5 +506,5 @@
  * @return		Current value of specified DMMU TLB Tag Read Register.
  */
-NO_TRACE static inline uint64_t dtlb_tag_read_read(int tlb, size_t entry)
+_NO_TRACE static inline uint64_t dtlb_tag_read_read(int tlb, size_t entry)
 {
 	dtlb_tag_read_addr_t tag;
@@ -522,5 +522,5 @@
  * @param v		Value to be written.
  */
-NO_TRACE static inline void itlb_tag_access_write(uint64_t v)
+_NO_TRACE static inline void itlb_tag_access_write(uint64_t v)
 {
 	asi_u64_write(ASI_IMMU, VA_IMMU_TAG_ACCESS, v);
@@ -532,5 +532,5 @@
  * @return		Current value of IMMU TLB Tag Access Register.
  */
-NO_TRACE static inline uint64_t itlb_tag_access_read(void)
+_NO_TRACE static inline uint64_t itlb_tag_access_read(void)
 {
 	return asi_u64_read(ASI_IMMU, VA_IMMU_TAG_ACCESS);
@@ -541,5 +541,5 @@
  * @param v		Value to be written.
  */
-NO_TRACE static inline void dtlb_tag_access_write(uint64_t v)
+_NO_TRACE static inline void dtlb_tag_access_write(uint64_t v)
 {
 	asi_u64_write(ASI_DMMU, VA_DMMU_TAG_ACCESS, v);
@@ -551,5 +551,5 @@
  * @return 		Current value of DMMU TLB Tag Access Register.
  */
-NO_TRACE static inline uint64_t dtlb_tag_access_read(void)
+_NO_TRACE static inline uint64_t dtlb_tag_access_read(void)
 {
 	return asi_u64_read(ASI_DMMU, VA_DMMU_TAG_ACCESS);
@@ -560,5 +560,5 @@
  * @param v		Value to be written.
  */
-NO_TRACE static inline void itlb_data_in_write(uint64_t v)
+_NO_TRACE static inline void itlb_data_in_write(uint64_t v)
 {
 	asi_u64_write(ASI_ITLB_DATA_IN_REG, 0, v);
@@ -570,5 +570,5 @@
  * @param v		Value to be written.
  */
-NO_TRACE static inline void dtlb_data_in_write(uint64_t v)
+_NO_TRACE static inline void dtlb_data_in_write(uint64_t v)
 {
 	asi_u64_write(ASI_DTLB_DATA_IN_REG, 0, v);
@@ -580,5 +580,5 @@
  * @return		Current content of I-SFSR register.
  */
-NO_TRACE static inline uint64_t itlb_sfsr_read(void)
+_NO_TRACE static inline uint64_t itlb_sfsr_read(void)
 {
 	return asi_u64_read(ASI_IMMU, VA_IMMU_SFSR);
@@ -589,5 +589,5 @@
  * @param v		New value of I-SFSR register.
  */
-NO_TRACE static inline void itlb_sfsr_write(uint64_t v)
+_NO_TRACE static inline void itlb_sfsr_write(uint64_t v)
 {
 	asi_u64_write(ASI_IMMU, VA_IMMU_SFSR, v);
@@ -599,5 +599,5 @@
  * @return		Current content of D-SFSR register.
  */
-NO_TRACE static inline uint64_t dtlb_sfsr_read(void)
+_NO_TRACE static inline uint64_t dtlb_sfsr_read(void)
 {
 	return asi_u64_read(ASI_DMMU, VA_DMMU_SFSR);
@@ -608,5 +608,5 @@
  * @param v		New value of D-SFSR register.
  */
-NO_TRACE static inline void dtlb_sfsr_write(uint64_t v)
+_NO_TRACE static inline void dtlb_sfsr_write(uint64_t v)
 {
 	asi_u64_write(ASI_DMMU, VA_DMMU_SFSR, v);
@@ -618,5 +618,5 @@
  * @return		Current content of D-SFAR register.
  */
-NO_TRACE static inline uint64_t dtlb_sfar_read(void)
+_NO_TRACE static inline uint64_t dtlb_sfar_read(void)
 {
 	return asi_u64_read(ASI_DMMU, VA_DMMU_SFAR);
@@ -631,5 +631,5 @@
  * @param page		Address which is on the page to be demapped.
  */
-NO_TRACE static inline void itlb_demap(int type, int context_encoding, uintptr_t page)
+_NO_TRACE static inline void itlb_demap(int type, int context_encoding, uintptr_t page)
 {
 	tlb_demap_addr_t da;
@@ -657,5 +657,5 @@
  * @param page		Address which is on the page to be demapped.
  */
-NO_TRACE static inline void dtlb_demap(int type, int context_encoding, uintptr_t page)
+_NO_TRACE static inline void dtlb_demap(int type, int context_encoding, uintptr_t page)
 {
 	tlb_demap_addr_t da;
Index: kernel/arch/sparc64/include/arch/mm/sun4v/as.h
===================================================================
--- kernel/arch/sparc64/include/arch/mm/sun4v/as.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/sparc64/include/arch/mm/sun4v/as.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -41,4 +41,5 @@
 
 #define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH  1
+#define KERNEL_SEPARATE_PTL0_ARCH           0
 
 #define KERNEL_ADDRESS_SPACE_START_ARCH  UINT64_C(0x0000000000000000)
Index: kernel/arch/sparc64/include/arch/mm/sun4v/tlb.h
===================================================================
--- kernel/arch/sparc64/include/arch/mm/sun4v/tlb.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/sparc64/include/arch/mm/sun4v/tlb.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -88,5 +88,5 @@
  * @return	Current value of Primary Context Register.
  */
-NO_TRACE static inline uint64_t mmu_primary_context_read(void)
+_NO_TRACE static inline uint64_t mmu_primary_context_read(void)
 {
 	return asi_u64_read(ASI_PRIMARY_CONTEXT_REG, VA_PRIMARY_CONTEXT_REG);
@@ -97,5 +97,5 @@
  * @param v	New value of Primary Context Register.
  */
-NO_TRACE static inline void mmu_primary_context_write(uint64_t v)
+_NO_TRACE static inline void mmu_primary_context_write(uint64_t v)
 {
 	asi_u64_write(ASI_PRIMARY_CONTEXT_REG, VA_PRIMARY_CONTEXT_REG, v);
@@ -106,5 +106,5 @@
  * @return	Current value of Secondary Context Register.
  */
-NO_TRACE static inline uint64_t mmu_secondary_context_read(void)
+_NO_TRACE static inline uint64_t mmu_secondary_context_read(void)
 {
 	return asi_u64_read(ASI_SECONDARY_CONTEXT_REG, VA_SECONDARY_CONTEXT_REG);
@@ -115,5 +115,5 @@
  * @param v	New value of Secondary Context Register.
  */
-NO_TRACE static inline void mmu_secondary_context_write(uint64_t v)
+_NO_TRACE static inline void mmu_secondary_context_write(uint64_t v)
 {
 	asi_u64_write(ASI_SECONDARY_CONTEXT_REG, VA_SECONDARY_CONTEXT_REG, v);
@@ -126,5 +126,5 @@
  * @param mmu_flag	MMU_FLAG_DTLB, MMU_FLAG_ITLB or a combination of both
  */
-NO_TRACE static inline void mmu_demap_ctx(int context, int mmu_flag)
+_NO_TRACE static inline void mmu_demap_ctx(int context, int mmu_flag)
 {
 	__hypercall_fast4(MMU_DEMAP_CTX, 0, 0, context, mmu_flag);
@@ -138,5 +138,5 @@
  * @param mmu_flag	MMU_FLAG_DTLB, MMU_FLAG_ITLB or a combination of both
  */
-NO_TRACE static inline void mmu_demap_page(uintptr_t vaddr, int context, int mmu_flag)
+_NO_TRACE static inline void mmu_demap_page(uintptr_t vaddr, int context, int mmu_flag)
 {
 	__hypercall_fast5(MMU_DEMAP_PAGE, 0, 0, vaddr, context, mmu_flag);
Index: kernel/arch/sparc64/include/arch/sun4u/asm.h
===================================================================
--- kernel/arch/sparc64/include/arch/sun4u/asm.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/sparc64/include/arch/sun4u/asm.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -43,5 +43,5 @@
  *
  */
-NO_TRACE static inline uint64_t ver_read(void)
+_NO_TRACE static inline uint64_t ver_read(void)
 {
 	uint64_t v;
Index: kernel/arch/sparc64/include/arch/sun4u/cpu.h
===================================================================
--- kernel/arch/sparc64/include/arch/sun4u/cpu.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/sparc64/include/arch/sun4u/cpu.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -76,5 +76,5 @@
  *
  */
-NO_TRACE static inline uint32_t read_mid(void)
+_NO_TRACE static inline uint32_t read_mid(void)
 {
 	uint64_t icbus_config = asi_u64_read(ASI_ICBUS_CONFIG, 0);
Index: kernel/arch/sparc64/src/console.c
===================================================================
--- kernel/arch/sparc64/src/console.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/sparc64/src/console.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,4 +37,5 @@
 #include <arch/drivers/scr.h>
 #include <arch/drivers/kbd.h>
+#include <arch/drivers/tty.h>
 #include <genarch/srln/srln.h>
 #include <console/chardev.h>
@@ -84,4 +85,13 @@
 	kbd_init(keyboard);
 #endif
+
+#ifdef CONFIG_SUN_TTY
+	ofw_tree_property_t *prop_tty = ofw_tree_getprop(aliases, "ttya");
+	if (prop_tty && prop_tty->value) {
+		ofw_tree_node_t *tty = ofw_tree_lookup(prop_tty->value);
+		if (tty)
+			tty_init(tty);
+	}
+#endif
 }
 
Index: kernel/arch/sparc64/src/drivers/kbd.c
===================================================================
--- kernel/arch/sparc64/src/drivers/kbd.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/sparc64/src/drivers/kbd.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,7 +38,4 @@
 #include <console/console.h>
 #include <ddi/irq.h>
-#include <mm/page.h>
-#include <arch/mm/page.h>
-#include <mm/km.h>
 #include <typedefs.h>
 #include <align.h>
@@ -88,6 +85,4 @@
 	}
 
-	size_t size = ((ofw_ebus_reg_t *) prop->value)->size;
-
 	uintptr_t pa = 0; // Prevent -Werror=maybe-uninitialized
 	if (!ofw_ebus_apply_ranges(node->parent,
@@ -109,9 +104,6 @@
 	}
 
-	ioport8_t *ns16550 = (ioport8_t *) km_map(pa, size,
-	    KM_NATURAL_ALIGNMENT, PAGE_WRITE | PAGE_NOT_CACHEABLE);
-
-	ns16550_instance_t *ns16550_instance = ns16550_init(ns16550, 0, inr, cir,
-	    cir_arg, NULL);
+	ns16550_instance_t *ns16550_instance = ns16550_init((ioport8_t *) pa, 0,
+	    inr, cir, cir_arg, NULL);
 	if (ns16550_instance) {
 		kbrd_instance_t *kbrd_instance = kbrd_init();
Index: kernel/arch/sparc64/src/drivers/tty.c
===================================================================
--- kernel/arch/sparc64/src/drivers/tty.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/arch/sparc64/src/drivers/tty.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2019 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 kernel_sparc64
+ * @{
+ */
+/** @file
+ */
+
+#include <genarch/ofw/ofw_tree.h>
+#include <genarch/ofw/ebus.h>
+#include <console/console.h>
+#include <genarch/srln/srln.h>
+#include <ddi/irq.h>
+#include <typedefs.h>
+#include <align.h>
+#include <str.h>
+#include <log.h>
+
+#ifdef CONFIG_SUN_TTY
+#include <arch/drivers/tty.h>
+#endif
+
+#ifdef CONFIG_NS16550
+#include <genarch/drivers/ns16550/ns16550.h>
+#endif
+
+#ifdef CONFIG_SUN_TTY
+
+#ifdef CONFIG_NS16550
+
+static bool tty_ns16550_init(ofw_tree_node_t *node)
+{
+	const char *name = ofw_tree_node_name(node);
+
+	if (str_cmp(name, "su") != 0)
+		return false;
+
+	/*
+	 * Read 'interrupts' property.
+	 */
+	ofw_tree_property_t *prop = ofw_tree_getprop(node, "interrupts");
+	if ((!prop) || (!prop->value)) {
+		log(LF_ARCH, LVL_ERROR,
+		    "ns16550: Unable to find interrupts property");
+		return false;
+	}
+
+	uint32_t interrupts = *((uint32_t *) prop->value);
+
+	/*
+	 * Read 'reg' property.
+	 */
+	prop = ofw_tree_getprop(node, "reg");
+	if ((!prop) || (!prop->value)) {
+		log(LF_ARCH, LVL_ERROR,
+		    "ns16550: Unable to find reg property");
+		return false;
+	}
+
+	uintptr_t pa = 0; // Prevent -Werror=maybe-uninitialized
+	if (!ofw_ebus_apply_ranges(node->parent,
+	    ((ofw_ebus_reg_t *) prop->value), &pa)) {
+		log(LF_ARCH, LVL_ERROR,
+		    "ns16550: Failed to determine address");
+		return false;
+	}
+
+	inr_t inr;
+	cir_t cir;
+	void *cir_arg;
+	if (!ofw_ebus_map_interrupt(node->parent,
+	    ((ofw_ebus_reg_t *) prop->value), interrupts, &inr, &cir,
+	    &cir_arg)) {
+		log(LF_ARCH, LVL_ERROR,
+		    "ns16550: Failed to determine interrupt");
+		return false;
+	}
+
+	outdev_t *ns16550_out;
+	ns16550_instance_t *ns16550_instance = ns16550_init((ioport8_t *) pa, 0,
+	    inr, cir, cir_arg, &ns16550_out);
+	if (ns16550_instance) {
+		srln_instance_t *srln_instance = srln_init();
+		if (srln_instance) {
+			indev_t *sink = stdin_wire();
+			indev_t *srln = srln_wire(srln_instance, sink);
+			ns16550_wire(ns16550_instance, srln);
+		}
+		stdout_wire(ns16550_out);
+	}
+
+	return true;
+}
+
+#endif /* CONFIG_NS16550 */
+
+/** Initialize tty.
+ *
+ * Traverse OpenFirmware device tree in order to find necessary
+ * info about the keyboard device.
+ *
+ * @param node Keyboard device node.
+ *
+ */
+void tty_init(ofw_tree_node_t *node)
+{
+#ifdef CONFIG_NS16550
+	tty_ns16550_init(node);
+#endif
+}
+
+#endif /* CONFIG_SUN_TTY */
+
+/** @}
+ */
Index: kernel/arch/sparc64/src/mm/sun4u/tlb.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4u/tlb.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/sparc64/src/mm/sun4u/tlb.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -311,5 +311,6 @@
 		t.a = true;
 		t.d = true;
-		dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY,
+		dtlb_demap(TLB_DEMAP_PAGE,
+		    (as == AS_KERNEL) ? TLB_DEMAP_PRIMARY : TLB_DEMAP_SECONDARY,
 		    page_16k + index * MMU_PAGE_SIZE);
 		dtlb_pte_copy(&t, index, false);
Index: kernel/arch/sparc64/src/sun4v/start.S
===================================================================
--- kernel/arch/sparc64/src/sun4v/start.S	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/arch/sparc64/src/sun4v/start.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -162,7 +162,7 @@
 
 	! map kernel in context 1
-	set kernel_image_start, %o0				! virt. address
+	set kernel_load_address, %o0				! virt. address
 	set 1, %o1						! context
-	TTE_DATA(kernel_image_start, %l5, %g2, %g3, %o2)	! TTE data
+	TTE_DATA(kernel_load_address, %l5, %g2, %g3, %o2)	! TTE data
 	set MMU_FLAG_DTLB | MMU_FLAG_ITLB, %o3			! MMU flags
 	__HYPERCALL_HYPERFAST(MMU_MAP_ADDR)
@@ -181,7 +181,7 @@
 
 	! install permanent mapping for kernel in context 0
-	set kernel_image_start, %o0				! virtual address
+	set kernel_load_address, %o0				! virtual address
 	set 0, %o1						! context
-	TTE_DATA(kernel_image_start, %l5, %g2, %g3, %o2)	! TTE data
+	TTE_DATA(kernel_load_address, %l5, %g2, %g3, %o2)	! TTE data
 	set MMU_FLAG_DTLB | MMU_FLAG_ITLB, %o3			! MMU flags
 	__HYPERCALL_FAST(MMU_MAP_PERM_ADDR)
Index: kernel/doc/doxygroups.h
===================================================================
--- kernel/doc/doxygroups.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/doc/doxygroups.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -47,4 +47,11 @@
 
 /**
+ *     @cond arm64
+ *     @defgroup kernel_arm64_proc arm64
+ *     @ingroup proc
+ *     @endcond
+ */
+
+/**
  *     @cond ia32
  *     @defgroup kernel_ia32_proc ia32
@@ -123,4 +130,11 @@
  *     @cond arm32
  *     @defgroup kernel_arm32_mm arm32
+ *     @ingroup mm
+ *     @endcond
+ */
+
+/**
+ *     @cond arm64
+ *     @defgroup kernel_arm64_mm arm64
  *     @ingroup mm
  *     @endcond
@@ -209,4 +223,11 @@
 
 /**
+ *     @cond arm64
+ *     @defgroup kernel_arm64_ddi arm64
+ *     @ingroup ddi
+ *     @endcond
+ */
+
+/**
  *     @cond ia32
  *     @defgroup kernel_ia32_ddi ia32
@@ -281,4 +302,11 @@
 
 /**
+ *     @cond arm64
+ *     @defgroup kernel_arm64_debug arm64
+ *     @ingroup debug
+ *     @endcond
+ */
+
+/**
  *     @cond ia32
  *     @defgroup kernel_amd64_debug ia32/amd64
@@ -352,4 +380,11 @@
 
 /**
+ *     @cond arm64
+ *     @defgroup kernel_arm64_interrupt arm64
+ *     @ingroup interrupt
+ *     @endcond
+ */
+
+/**
  *     @cond ia32
  *     @defgroup kernel_ia32_interrupt ia32
@@ -429,4 +464,11 @@
 
 /**
+ *     @cond arm64
+ *     @defgroup kernel_arm64 arm64
+ *     @ingroup others
+ *     @endcond
+ */
+
+/**
  *     @cond ia32
  *     @defgroup kernel_ia32 ia32
Index: kernel/genarch/Makefile.inc
===================================================================
--- kernel/genarch/Makefile.inc	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/genarch/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -85,4 +85,9 @@
 endif
 
+ifeq ($(CONFIG_I8259),y)
+GENARCH_SOURCES += \
+	genarch/src/drivers/i8259/i8259.c
+endif
+
 ifeq ($(CONFIG_NS16550),y)
 GENARCH_SOURCES += \
@@ -117,5 +122,12 @@
 ifeq ($(CONFIG_BCM2835_MAILBOX),y)
 GENARCH_SOURCES += \
-	genarch/src/drivers/bcm2835/mbox.c
+	genarch/src/drivers/bcm2835/irc.c \
+	genarch/src/drivers/bcm2835/mbox.c \
+	genarch/src/drivers/bcm2835/timer.c
+endif
+
+ifeq ($(CONFIG_GICV2), y)
+GENARCH_SOURCES += \
+	genarch/src/drivers/gicv2/gicv2.c
 endif
 
Index: kernel/genarch/include/genarch/drivers/bcm2835/irc.h
===================================================================
--- kernel/genarch/include/genarch/drivers/bcm2835/irc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/genarch/include/genarch/drivers/bcm2835/irc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,3 +1,4 @@
 /*
+ * Copyright (c) 2019 Jiri Svoboda
  * Copyright (c) 2012 Jan Vesely
  * Copyright (c) 2013 Beniamino Galvani
@@ -59,6 +60,4 @@
 #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;
@@ -75,98 +74,8 @@
 #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));
-}
+extern void bcm2835_irc_init(bcm2835_irc_t *);
+extern unsigned bcm2835_irc_inum_get(bcm2835_irc_t *);
+extern void bcm2835_irc_enable(bcm2835_irc_t *, unsigned);
+extern void bcm2835_irc_disable(bcm2835_irc_t *, unsigned);
 
 #endif /* KERN_BCM2835_IRQC_H_ */
Index: kernel/genarch/include/genarch/drivers/bcm2835/mbox.h
===================================================================
--- kernel/genarch/include/genarch/drivers/bcm2835/mbox.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/genarch/include/genarch/drivers/bcm2835/mbox.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -134,8 +134,9 @@
 } bcm2835_fb_desc_t;
 
-bool bcm2835_prop_get_memory(uint32_t *base, uint32_t *size);
-bool bcm2835_fb_init(fb_properties_t *prop);
+extern bool bcm2835_prop_get_memory(uint32_t *base, uint32_t *size);
+extern 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 c878693123930f0906703462cf2807430679517e)
+++ kernel/genarch/include/genarch/drivers/bcm2835/timer.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -64,21 +64,10 @@
 } 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);
-}
+extern void bcm2835_timer_start(bcm2835_timer_t *);
+extern void bcm2835_timer_irq_ack(bcm2835_timer_t *);
 
 #endif /* KERN_BCM2835_TIMER_H_ */
+
+/**
+ * @}
+ */
Index: kernel/genarch/include/genarch/drivers/dsrln/dsrlnout.h
===================================================================
--- kernel/genarch/include/genarch/drivers/dsrln/dsrlnout.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/genarch/include/genarch/drivers/dsrln/dsrlnout.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,7 +39,8 @@
 
 #include <typedefs.h>
+#include <stdint.h>
 #include <console/chardev.h>
 
-extern outdev_t *dsrlnout_init(ioport8_t *);
+extern outdev_t *dsrlnout_init(ioport8_t *, uintptr_t);
 
 #endif
Index: kernel/genarch/include/genarch/drivers/gicv2/gicv2.h
===================================================================
--- kernel/genarch/include/genarch/drivers/gicv2/gicv2.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/genarch/include/genarch/drivers/gicv2/gicv2.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2016 Petr Pavlu
+ * 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 Generic Interrupt Controller, Architecture version 2.0.
+ */
+
+#ifndef KERN_GICV2_H_
+#define KERN_GICV2_H_
+
+#include <typedefs.h>
+
+/** GICv2 distributor register map. */
+typedef struct {
+	/** Distributor control register. */
+	ioport32_t ctlr;
+#define GICV2D_CTLR_ENABLE_FLAG  0x1
+
+	/** Interrupt controller type register. */
+	const ioport32_t typer;
+#define GICV2D_TYPER_IT_LINES_NUMBER_SHIFT  0
+#define GICV2D_TYPER_IT_LINES_NUMBER_MASK \
+	(0x1f << GICV2D_TYPER_IT_LINES_NUMBER_SHIFT)
+
+	/** Distributor implementer identification register. */
+	const ioport32_t iidr;
+	/** Reserved. */
+	ioport32_t res_[5];
+	/** Implementation defined registers. */
+	ioport32_t impl[8];
+	/** Reserved. */
+	ioport32_t res2_[16];
+	/** Interrupt group registers. */
+	ioport32_t igroupr[32];
+	/** Interrupt set-enable registers. */
+	ioport32_t isenabler[32];
+	/** Interrupt clear-enable registers. */
+	ioport32_t icenabler[32];
+	/** Interrupt set-pending registers. */
+	ioport32_t ispendr[32];
+	/** Interrupt clear-pending registers. */
+	ioport32_t icpendr[32];
+	/** GICv2 interrupt set-active registers. */
+	ioport32_t isactiver[32];
+	/** Interrupt clear-active registers. */
+	ioport32_t icactiver[32];
+	/** Interrupt priority registers. */
+	ioport32_t ipriorityr[255];
+	/** Reserved. */
+	ioport32_t res3_;
+	/** Interrupt processor target registers. First 8 words are read-only.
+	 */
+	ioport32_t itargetsr[255];
+	/** Reserved. */
+	ioport32_t res4_;
+	/** Interrupt configuration registers. */
+	ioport32_t icfgr[64];
+	/** Implementation defined registers. */
+	ioport32_t impl2[64];
+	/** Non-secure access control registers. */
+	ioport32_t nsacr[64];
+	/** Software generated interrupt register. */
+	ioport32_t sgir;
+	/** Reserved. */
+	ioport32_t res5_[3];
+	/** SGI clear-pending registers. */
+	ioport32_t cpendsgir[4];
+	/** SGI set-pending registers. */
+	ioport32_t spendsgir[4];
+	/** Reserved. */
+	ioport32_t res6_[40];
+	/** Implementation defined identification registers. */
+	const ioport32_t impl3[12];
+} gicv2_distr_regs_t;
+
+/* GICv2 CPU interface register map. */
+typedef struct {
+	/** CPU interface control register. */
+	ioport32_t ctlr;
+#define GICV2C_CTLR_ENABLE_FLAG  0x1
+
+	/** Interrupt priority mask register. */
+	ioport32_t pmr;
+	/** Binary point register. */
+	ioport32_t bpr;
+	/** Interrupt acknowledge register. */
+	const ioport32_t iar;
+#define GICV2C_IAR_INTERRUPT_ID_SHIFT  0
+#define GICV2C_IAR_INTERRUPT_ID_MASK \
+	(0x3ff << GICV2C_IAR_INTERRUPT_ID_SHIFT)
+#define GICV2C_IAR_CPUID_SHIFT  10
+#define GICV2C_IAR_CPUID_MASK \
+	(0x7 << GICV2C_IAR_CPUID_SHIFT)
+
+	/** End of interrupt register. */
+	ioport32_t eoir;
+	/** Running priority register. */
+	const ioport32_t rpr;
+	/** Highest priority pending interrupt register. */
+	const ioport32_t hppir;
+	/** Aliased binary point register. */
+	ioport32_t abpr;
+	/** Aliased interrupt acknowledge register. */
+	const ioport32_t aiar;
+	/** Aliased end of interrupt register. */
+	ioport32_t aeoir;
+	/** Aliased highest priority pending interrupt register. */
+	const ioport32_t ahppir;
+	/** Reserved. */
+	ioport32_t res_[5];
+	/** Implementation defined registers. */
+	ioport32_t impl[36];
+	/** Active priorities registers. */
+	ioport32_t apr[4];
+	/** Non-secure active priorities registers. */
+	ioport32_t nsapr[4];
+	/** Reserved. */
+	ioport32_t res2_[3];
+	/** CPU interface identification register. */
+	const ioport32_t iidr;
+	/** Unallocated. */
+	ioport32_t unalloc_[960];
+	/** Deactivate interrupt register. */
+	ioport32_t dir;
+} gicv2_cpui_regs_t;
+
+/** GICv2 driver-specific device data. */
+typedef struct {
+	gicv2_distr_regs_t *distr;
+	gicv2_cpui_regs_t *cpui;
+	unsigned inum_total;
+} gicv2_t;
+
+extern void gicv2_init(gicv2_t *, gicv2_distr_regs_t *, gicv2_cpui_regs_t *);
+extern unsigned gicv2_inum_get_total(gicv2_t *);
+extern void gicv2_inum_get(gicv2_t *, unsigned *, unsigned *);
+extern void gicv2_end(gicv2_t *, unsigned, unsigned);
+extern void gicv2_enable(gicv2_t *, unsigned);
+extern void gicv2_disable(gicv2_t *, unsigned);
+
+#endif
+
+/** @}
+ */
Index: kernel/genarch/include/genarch/drivers/i8259/i8259.h
===================================================================
--- kernel/genarch/include/genarch/drivers/i8259/i8259.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/genarch/include/genarch/drivers/i8259/i8259.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2001-2004 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 kernel_genarch
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_I8259_H_
+#define KERN_I8259_H_
+
+#include <typedefs.h>
+#include <arch/interrupt.h>
+#include <stdbool.h>
+
+/* ICW1 bits */
+#define PIC_ICW1           (1 << 4)
+#define PIC_ICW1_NEEDICW4  (1 << 0)
+
+/* OCW3 bits */
+#define PIC_OCW3           (1 << 3)
+#define PIC_OCW3_READ_ISR  (3 << 0)
+
+/* OCW4 bits */
+#define PIC_OCW4           (0 << 3)
+#define PIC_OCW4_NSEOI     (1 << 5)
+
+#define PIC0_IRQ_COUNT      8
+#define PIC1_IRQ_COUNT      8
+
+#define PIC0_IRQ_PIC1       2
+
+typedef struct {
+	ioport8_t port1;
+	ioport8_t port2;
+} __attribute__((packed)) i8259_t;
+
+extern void i8259_init(i8259_t *, i8259_t *, unsigned int);
+extern void pic_enable_irqs(uint16_t);
+extern void pic_disable_irqs(uint16_t);
+extern void pic_eoi(unsigned int);
+extern bool pic_is_spurious(unsigned int);
+extern void pic_handle_spurious(unsigned int);
+
+#endif
+
+/** @}
+ */
Index: kernel/genarch/include/genarch/drivers/legacy/ia32/io.h
===================================================================
--- kernel/genarch/include/genarch/drivers/legacy/ia32/io.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/genarch/include/genarch/drivers/legacy/ia32/io.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -44,4 +44,7 @@
 #define NS16550_BASE  ((ioport8_t *) 0x3f8)
 
+#define I8259_PIC0_BASE ((ioport8_t *) 0x20U)
+#define I8259_PIC1_BASE ((ioport8_t *) 0xA0U)
+
 #define EGA_VIDEORAM  0xb8000
 
Index: kernel/genarch/include/genarch/drivers/pl011/pl011.h
===================================================================
--- kernel/genarch/include/genarch/drivers/pl011/pl011.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/genarch/include/genarch/drivers/pl011/pl011.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,4 +38,5 @@
 #define KERN_PL011_H_
 
+#include <ddi/ddi.h>
 #include <ddi/irq.h>
 #include <console/chardev.h>
@@ -150,4 +151,5 @@
 	outdev_t outdev;
 	irq_t irq;
+	parea_t parea;
 } pl011_uart_t;
 
Index: kernel/genarch/include/genarch/drivers/via-cuda/cuda.h
===================================================================
--- kernel/genarch/include/genarch/drivers/via-cuda/cuda.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/genarch/include/genarch/drivers/via-cuda/cuda.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -42,50 +42,50 @@
 
 typedef struct {
-	uint8_t b;
+	ioport8_t b;
 	uint8_t pad0[0x1ff];
 
-	uint8_t a;
+	ioport8_t a;
 	uint8_t pad1[0x1ff];
 
-	uint8_t dirb;
+	ioport8_t dirb;
 	uint8_t pad2[0x1ff];
 
-	uint8_t dira;
+	ioport8_t dira;
 	uint8_t pad3[0x1ff];
 
-	uint8_t t1cl;
+	ioport8_t t1cl;
 	uint8_t pad4[0x1ff];
 
-	uint8_t t1ch;
+	ioport8_t t1ch;
 	uint8_t pad5[0x1ff];
 
-	uint8_t t1ll;
+	ioport8_t t1ll;
 	uint8_t pad6[0x1ff];
 
-	uint8_t t1lh;
+	ioport8_t t1lh;
 	uint8_t pad7[0x1ff];
 
-	uint8_t t2cl;
+	ioport8_t t2cl;
 	uint8_t pad8[0x1ff];
 
-	uint8_t t2ch;
+	ioport8_t t2ch;
 	uint8_t pad9[0x1ff];
 
-	uint8_t sr;
+	ioport8_t sr;
 	uint8_t pad10[0x1ff];
 
-	uint8_t acr;
+	ioport8_t acr;
 	uint8_t pad11[0x1ff];
 
-	uint8_t pcr;
+	ioport8_t pcr;
 	uint8_t pad12[0x1ff];
 
-	uint8_t ifr;
+	ioport8_t ifr;
 	uint8_t pad13[0x1ff];
 
-	uint8_t ier;
+	ioport8_t ier;
 	uint8_t pad14[0x1ff];
 
-	uint8_t anh;
+	ioport8_t anh;
 	uint8_t pad15[0x1ff];
 } cuda_t;
Index: kernel/genarch/src/drivers/bcm2835/irc.c
===================================================================
--- kernel/genarch/src/drivers/bcm2835/irc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/genarch/src/drivers/bcm2835/irc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2019 Jiri Svoboda
+ * 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 kernel_genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief Broadcom BCM2835 on-chip interrupt controller driver.
+ */
+
+#include <assert.h>
+#include <genarch/drivers/bcm2835/irc.h>
+#include <stdio.h>
+
+unsigned shortcut_inums[] = { 7, 9, 10, 18, 19, 53, 54, 55, 56, 57, 62 };
+
+static 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
+}
+
+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 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;
+}
+
+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;
+}
+
+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));
+}
+
+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));
+}
+
+/**
+ * @}
+ */
Index: kernel/genarch/src/drivers/bcm2835/timer.c
===================================================================
--- kernel/genarch/src/drivers/bcm2835/timer.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/genarch/src/drivers/bcm2835/timer.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2019 Jiri Svoboda
+ * 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 kernel_genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief Broadcom BCM2835 system timer driver.
+ */
+
+#include <assert.h>
+#include <genarch/drivers/bcm2835/timer.h>
+#include <time/clock.h>
+
+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);
+}
+
+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);
+}
+
+/**
+ * @}
+ */
Index: kernel/genarch/src/drivers/dsrln/dsrlnout.c
===================================================================
--- kernel/genarch/src/drivers/dsrln/dsrlnout.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/genarch/src/drivers/dsrln/dsrlnout.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -68,5 +68,5 @@
 };
 
-outdev_t *dsrlnout_init(ioport8_t *base)
+outdev_t *dsrlnout_init(ioport8_t *base, uintptr_t base_phys)
 {
 	outdev_t *dsrlndev = malloc(sizeof(outdev_t));
@@ -85,5 +85,5 @@
 	instance->base = base;
 	ddi_parea_init(&instance->parea);
-	instance->parea.pbase = KA2PA(base);
+	instance->parea.pbase = base_phys;
 	instance->parea.frames = 1;
 	instance->parea.unpriv = false;
Index: kernel/genarch/src/drivers/gicv2/gicv2.c
===================================================================
--- kernel/genarch/src/drivers/gicv2/gicv2.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/genarch/src/drivers/gicv2/gicv2.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2016 Petr Pavlu
+ * 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 Generic Interrupt Controller, Architecture version 2.0.
+ *
+ * This IRQ controller is present on the QEMU virt platform for ARM.
+ */
+
+#include <arch/asm.h>
+#include <genarch/drivers/gicv2/gicv2.h>
+#include <assert.h>
+
+/** Initialize GICv2 interrupt controller.
+ *
+ * @param irqc Instance structure.
+ * @param distr Distributor registers.
+ * @param cpui CPU interface registers.
+ */
+void gicv2_init(gicv2_t *irqc, gicv2_distr_regs_t *distr,
+    gicv2_cpui_regs_t *cpui)
+{
+	irqc->distr = distr;
+	irqc->cpui = cpui;
+
+	/* Get maximum number of interrupts. */
+	uint32_t typer = pio_read_32(&distr->typer);
+	irqc->inum_total = (((typer & GICV2D_TYPER_IT_LINES_NUMBER_MASK) >>
+	    GICV2D_TYPER_IT_LINES_NUMBER_SHIFT) + 1) * 32;
+
+	/* Disable all interrupts. */
+	for (unsigned i = 0; i < irqc->inum_total / 32; i++)
+		pio_write_32(&distr->icenabler[i], 0xffffffff);
+
+	/* Enable interrupts for all priority levels. */
+	pio_write_32(&cpui->pmr, 0xff);
+
+	/* Enable signaling of interrupts. */
+	pio_write_32(&cpui->ctlr, GICV2C_CTLR_ENABLE_FLAG);
+	pio_write_32(&distr->ctlr, GICV2D_CTLR_ENABLE_FLAG);
+}
+
+/** Obtain total number of interrupts that the controller supports. */
+unsigned gicv2_inum_get_total(gicv2_t *irqc)
+{
+	return irqc->inum_total;
+}
+
+/** Obtain number of pending interrupt. */
+void gicv2_inum_get(gicv2_t *irqc, unsigned *inum, unsigned *cpuid)
+{
+	uint32_t iar = pio_read_32(&irqc->cpui->iar);
+
+	*inum = (iar & GICV2C_IAR_INTERRUPT_ID_MASK) >>
+	    GICV2C_IAR_INTERRUPT_ID_SHIFT;
+	*cpuid = (iar & GICV2C_IAR_CPUID_MASK) >> GICV2C_IAR_CPUID_SHIFT;
+}
+
+/** Signal end of interrupt to the controller. */
+void gicv2_end(gicv2_t *irqc, unsigned inum, unsigned cpuid)
+{
+	assert((inum & ~((unsigned) GICV2C_IAR_INTERRUPT_ID_MASK >>
+	    GICV2C_IAR_INTERRUPT_ID_SHIFT)) == 0);
+	assert((cpuid & ~((unsigned) GICV2C_IAR_CPUID_MASK >>
+	    GICV2C_IAR_CPUID_SHIFT)) == 0);
+
+	uint32_t eoir = (inum << GICV2C_IAR_INTERRUPT_ID_SHIFT) |
+	    (cpuid << GICV2C_IAR_CPUID_SHIFT);
+	pio_write_32(&irqc->cpui->eoir, eoir);
+}
+
+/** Enable specific interrupt. */
+void gicv2_enable(gicv2_t *irqc, unsigned inum)
+{
+	assert(inum < irqc->inum_total);
+
+	pio_write_32(&irqc->distr->isenabler[inum / 32], 1 << (inum % 32));
+}
+
+/** Disable specific interrupt. */
+void gicv2_disable(gicv2_t *irqc, unsigned inum)
+{
+	assert(inum < irqc->inum_total);
+
+	pio_write_32(&irqc->distr->icenabler[inum / 32], 1 << (inum % 32));
+}
+
+/** @}
+ */
Index: kernel/genarch/src/drivers/i8259/i8259.c
===================================================================
--- kernel/genarch/src/drivers/i8259/i8259.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ kernel/genarch/src/drivers/i8259/i8259.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2001-2004 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 kernel_genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief PIC driver.
+ *
+ * Programmable Interrupt Controller for UP systems based on i8259 chip.
+ */
+
+#include <genarch/drivers/i8259/i8259.h>
+#include <typedefs.h>
+#include <stdint.h>
+#include <log.h>
+#include <interrupt.h>
+
+// XXX: need to change pic_* API to get rid of these
+static i8259_t *saved_pic0;
+static i8259_t *saved_pic1;
+
+void i8259_init(i8259_t *pic0, i8259_t *pic1, unsigned int irq0_vec)
+{
+	saved_pic0 = pic0;
+	saved_pic1 = pic1;
+
+	/* ICW1: this is ICW1, ICW4 to follow */
+	pio_write_8(&pic0->port1, PIC_ICW1 | PIC_ICW1_NEEDICW4);
+
+	/* ICW2: IRQ 0 maps to interrupt vector address irq0_vec */
+	pio_write_8(&pic0->port2, irq0_vec);
+
+	/* ICW3: pic1 using IRQ PIC0_IRQ_PIC1 */
+	pio_write_8(&pic0->port2, 1 << PIC0_IRQ_PIC1);
+
+	/* ICW4: i8086 mode */
+	pio_write_8(&pic0->port2, 1);
+
+	/* ICW1: ICW1, ICW4 to follow */
+	pio_write_8(&pic1->port1, PIC_ICW1 | PIC_ICW1_NEEDICW4);
+
+	/* ICW2: IRQ 8 maps to interrupt vector address irq0_vec + 8 */
+	pio_write_8(&pic1->port2, irq0_vec + PIC0_IRQ_COUNT);
+
+	/* ICW3: pic1 is known as PIC0_IRQ_PIC1 */
+	pio_write_8(&pic1->port2, PIC0_IRQ_PIC1);
+
+	/* ICW4: i8086 mode */
+	pio_write_8(&pic1->port2, 1);
+
+	pic_disable_irqs(0xffff);		/* disable all irq's */
+	pic_enable_irqs(1 << PIC0_IRQ_PIC1);	/* but enable PIC0_IRQ_PIC1 */
+}
+
+void pic_enable_irqs(uint16_t irqmask)
+{
+	uint8_t x;
+
+	if (irqmask & 0xff) {
+		x = pio_read_8(&saved_pic0->port2);
+		pio_write_8(&saved_pic0->port2,
+		    (uint8_t) (x & (~(irqmask & 0xff))));
+	}
+	if (irqmask >> PIC0_IRQ_COUNT) {
+		x = pio_read_8(&saved_pic1->port2);
+		pio_write_8(&saved_pic1->port2,
+		    (uint8_t) (x & (~(irqmask >> PIC0_IRQ_COUNT))));
+	}
+}
+
+void pic_disable_irqs(uint16_t irqmask)
+{
+	uint8_t x;
+
+	if (irqmask & 0xff) {
+		x = pio_read_8(&saved_pic0->port2);
+		pio_write_8(&saved_pic0->port2,
+		    (uint8_t) (x | (irqmask & 0xff)));
+	}
+	if (irqmask >> PIC0_IRQ_COUNT) {
+		x = pio_read_8(&saved_pic1->port2);
+		pio_write_8(&saved_pic1->port2,
+		    (uint8_t) (x | (irqmask >> PIC0_IRQ_COUNT)));
+	}
+}
+
+void pic_eoi(unsigned int irq)
+{
+	if (irq >= PIC0_IRQ_COUNT)
+		pio_write_8(&saved_pic1->port1, PIC_OCW4 | PIC_OCW4_NSEOI);
+	pio_write_8(&saved_pic0->port1, PIC_OCW4 | PIC_OCW4_NSEOI);
+}
+
+bool pic_is_spurious(unsigned int irq)
+{
+	pio_write_8(&saved_pic0->port1, PIC_OCW3 | PIC_OCW3_READ_ISR);
+	pio_write_8(&saved_pic1->port1, PIC_OCW3 | PIC_OCW3_READ_ISR);
+	uint8_t isr_lo = pio_read_8(&saved_pic0->port1);
+	uint8_t isr_hi = pio_read_8(&saved_pic1->port1);
+	return !(((isr_hi << PIC0_IRQ_COUNT) | isr_lo) & (1 << irq));
+}
+
+void pic_handle_spurious(unsigned int irq)
+{
+	/* For spurious IRQs from pic1, we need to isssue an EOI to pic0 */
+	if (irq >= PIC0_IRQ_COUNT)
+		pio_write_8(&saved_pic0->port1, PIC_OCW4 | PIC_OCW4_NSEOI);
+}
+
+/** @}
+ */
Index: kernel/genarch/src/drivers/ns16550/ns16550.c
===================================================================
--- kernel/genarch/src/drivers/ns16550/ns16550.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/genarch/src/drivers/ns16550/ns16550.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,7 +39,9 @@
 #include <genarch/drivers/ns16550/ns16550.h>
 #include <ddi/irq.h>
+#include <ddi/ddi.h>
 #include <arch/asm.h>
 #include <console/chardev.h>
 #include <stdlib.h>
+#include <align.h>
 #include <str.h>
 
@@ -143,9 +145,11 @@
  *
  */
-ns16550_instance_t *ns16550_init(ioport8_t *dev, unsigned reg_shift, inr_t inr,
-    cir_t cir, void *cir_arg, outdev_t **output)
-{
-	ns16550_instance_t *instance =
-	    malloc(sizeof(ns16550_instance_t));
+ns16550_instance_t *ns16550_init(ioport8_t *dev_phys, unsigned reg_shift,
+    inr_t inr, cir_t cir, void *cir_arg, outdev_t **output)
+{
+	size_t size = 6 * (1U << reg_shift);
+	ioport8_t *dev = pio_map((void *) dev_phys, size);
+
+	ns16550_instance_t *instance = malloc(sizeof(ns16550_instance_t));
 	if (instance) {
 		instance->ns16550 = dev;
@@ -158,4 +162,6 @@
 			if (!instance->output) {
 				free(instance);
+				pio_unmap((void *) dev_phys, (void *) dev,
+				    size);
 				return NULL;
 			}
@@ -176,6 +182,7 @@
 
 		ddi_parea_init(&instance->parea);
-		instance->parea.pbase = (uintptr_t) dev;
-		instance->parea.frames = 1;
+		instance->parea.pbase = ALIGN_DOWN((uintptr_t) dev_phys,
+		    PAGE_SIZE);
+		instance->parea.frames = ALIGN_UP(size, PAGE_SIZE);
 		instance->parea.unpriv = false;
 		instance->parea.mapped = false;
Index: kernel/genarch/src/drivers/pl011/pl011.c
===================================================================
--- kernel/genarch/src/drivers/pl011/pl011.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/genarch/src/drivers/pl011/pl011.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -60,7 +60,11 @@
 	pl011_uart_t *uart = dev->data;
 
-	if (!ascii_check(ch)) {
+	/* If the userspace owns the console, do not output anything. */
+	if (uart->parea.mapped && !console_override)
+		return;
+
+	if (!ascii_check(ch))
 		pl011_uart_sendb(uart, U_SPECIAL);
-	} else {
+	else {
 		if (ch == '\n')
 			pl011_uart_sendb(uart, (uint8_t) '\r');
@@ -100,5 +104,5 @@
 	assert(uart);
 	uart->regs = (void *)km_map(addr, sizeof(pl011_uart_regs_t),
-	    KM_NATURAL_ALIGNMENT, PAGE_NOT_CACHEABLE);
+	    KM_NATURAL_ALIGNMENT, PAGE_WRITE | PAGE_NOT_CACHEABLE);
 	assert(uart->regs);
 
@@ -131,4 +135,11 @@
 	uart->irq.instance = uart;
 
+	ddi_parea_init(&uart->parea);
+	uart->parea.pbase = addr;
+	uart->parea.frames = 1;
+	uart->parea.unpriv = false;
+	uart->parea.mapped = false;
+	ddi_parea_register(&uart->parea);
+
 	return true;
 }
Index: kernel/genarch/src/fb/fb.c
===================================================================
--- kernel/genarch/src/fb/fb.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/genarch/src/fb/fb.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -76,4 +76,6 @@
 	    (instance)->cols + (col))
 
+#define BB_NEXT_COL(pos) (++(pos))
+
 #define GLYPH_POS(instance, glyph, y) \
 	((glyph) * (instance)->glyphbytes + (y) * (instance)->glyphscanline)
@@ -270,4 +272,6 @@
 				unsigned int x;
 				unsigned int col;
+				size_t bb_pos = BB_POS(instance, 0, row);
+				size_t bb_pos1 = BB_POS(instance, 0, row + 1);
 
 				for (col = 0, x = 0; col < instance->cols;
@@ -276,9 +280,9 @@
 
 					if (row < instance->rows - 1) {
-						if (instance->backbuf[BB_POS(instance, col, row)] ==
-						    instance->backbuf[BB_POS(instance, col, row + 1)])
-							continue;
-
-						glyph = instance->backbuf[BB_POS(instance, col, row + 1)];
+						if (instance->backbuf[bb_pos] ==
+						    instance->backbuf[bb_pos1])
+							goto skip;
+
+						glyph = instance->backbuf[bb_pos1];
 					} else
 						glyph = 0;
@@ -287,4 +291,7 @@
 					    &instance->glyphs[GLYPH_POS(instance, glyph, yd)],
 					    instance->glyphscanline);
+				skip:
+					BB_NEXT_COL(bb_pos);
+					BB_NEXT_COL(bb_pos1);
 				}
 			}
@@ -373,12 +380,14 @@
 			unsigned int x;
 			unsigned int col;
+			size_t bb_pos = BB_POS(instance, 0, row);
 
 			for (col = 0, x = 0; col < instance->cols;
 			    col++, x += FONT_WIDTH) {
 				uint16_t glyph =
-				    instance->backbuf[BB_POS(instance, col, row)];
+				    instance->backbuf[bb_pos];
 				void *dst = &instance->addr[FB_POS(instance, x, y + yd)];
 				void *src = &instance->glyphs[GLYPH_POS(instance, glyph, yd)];
 				memcpy(dst, src, instance->glyphscanline);
+				BB_NEXT_COL(bb_pos);
 			}
 		}
Index: kernel/genarch/src/mm/as_pt.c
===================================================================
--- kernel/genarch/src/mm/as_pt.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/genarch/src/mm/as_pt.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -76,7 +76,7 @@
 	    PA2KA(frame_alloc(PTL0_FRAMES, FRAME_LOWMEM, PTL0_SIZE - 1));
 
-	if (flags & FLAG_AS_KERNEL)
-		memsetb(dst_ptl0, PTL0_SIZE, 0);
-	else {
+	memsetb(dst_ptl0, PTL0_SIZE, 0);
+
+	if (!KERNEL_SEPARATE_PTL0 && !(flags & FLAG_AS_KERNEL)) {
 		/*
 		 * Copy the kernel address space portion to new PTL0.
@@ -93,5 +93,4 @@
 		    &dst_ptl0[PTL0_INDEX(KERNEL_ADDRESS_SPACE_START)];
 
-		memsetb(dst_ptl0, PTL0_SIZE, 0);
 		memcpy((void *) dst, (void *) src,
 		    PTL0_SIZE - (src - (uintptr_t) src_ptl0));
Index: kernel/genarch/src/mm/page_ht.c
===================================================================
--- kernel/genarch/src/mm/page_ht.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/genarch/src/mm/page_ht.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -54,6 +54,6 @@
 
 static size_t ht_hash(const ht_link_t *);
-static size_t ht_key_hash(void *);
-static bool ht_key_equal(void *, const ht_link_t *);
+static size_t ht_key_hash(const void *);
+static bool ht_key_equal(const void *, const ht_link_t *);
 static void ht_remove_callback(ht_link_t *);
 
@@ -109,7 +109,7 @@
 
 /** Return the hash of the key. */
-size_t ht_key_hash(void *arg)
-{
-	uintptr_t *key = (uintptr_t *) arg;
+size_t ht_key_hash(const void *arg)
+{
+	const uintptr_t *key = arg;
 	size_t hash = 0;
 	hash = hash_combine(hash, key[KEY_AS]);
@@ -119,7 +119,7 @@
 
 /** Return true if the key is equal to the item's lookup key. */
-bool ht_key_equal(void *arg, const ht_link_t *item)
-{
-	uintptr_t *key = (uintptr_t *) arg;
+bool ht_key_equal(const void *arg, const ht_link_t *item)
+{
+	const uintptr_t *key = arg;
 	pte_t *pte = hash_table_get_inst(item, pte_t, link);
 	return (key[KEY_AS] == (uintptr_t) pte->as) &&
Index: kernel/genarch/src/multiboot/multiboot.c
===================================================================
--- kernel/genarch/src/multiboot/multiboot.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/genarch/src/multiboot/multiboot.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -55,8 +55,8 @@
 	/*
 	 * Find last occurence of '/' before 'end'. If found, place start at
-	 * next character. Otherwise, place start at beginning of buffer.
+	 * next character. Otherwise, place start at beginning of command line.
 	 */
 	const char *cp = end;
-	const char *start = buf;
+	const char *start = cmd_line;
 
 	while (cp != start) {
Index: kernel/genarch/src/multiboot/multiboot2.c
===================================================================
--- kernel/genarch/src/multiboot/multiboot2.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/genarch/src/multiboot/multiboot2.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -65,5 +65,5 @@
 	multiboot2_memmap_entry_t *entry = (multiboot2_memmap_entry_t *)
 	    ((uintptr_t) memmap + sizeof(*memmap));
-	uint32_t pos = sizeof(*memmap);
+	uint32_t pos = offsetof(multiboot2_tag_t, memmap) + sizeof(*memmap);
 
 	while ((pos < length) && (e820counter < MEMMAP_E820_MAX_RECORDS)) {
Index: kernel/genarch/src/ofw/ofw_tree.c
===================================================================
--- kernel/genarch/src/ofw/ofw_tree.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/genarch/src/ofw/ofw_tree.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -393,4 +393,6 @@
 		if ((cur->parent) && (path))
 			snprintf(cur_path, PATH_MAX_LEN, "%s.%s", path, cur->da_name);
+		else if (!str_size(cur->da_name))
+			snprintf(cur_path, PATH_MAX_LEN, "firmware.ofw");
 		else
 			snprintf(cur_path, PATH_MAX_LEN, "firmware.%s", cur->da_name);
Index: rnel/generic/include/adt/btree.h
===================================================================
--- kernel/generic/include/adt/btree.h	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,117 +1,0 @@
-/*
- * 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 kernel_generic_adt
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_BTREE_H_
-#define KERN_BTREE_H_
-
-#include <adt/list.h>
-#include <stddef.h>
-
-#define BTREE_M		5
-#define BTREE_MAX_KEYS	(BTREE_M - 1)
-
-typedef uint64_t btree_key_t;
-
-/** B-tree node structure. */
-typedef struct btree_node {
-	/** Number of keys. */
-	size_t keys;
-
-	/**
-	 * Keys. We currently support only single keys. Additional room for one
-	 * extra key is provided.
-	 */
-	btree_key_t key[BTREE_MAX_KEYS + 1];
-
-	/**
-	 * Pointers to values. Sorted according to the key array. Defined only in
-	 * leaf-level. There is room for storing value for the extra key.
-	 */
-	void *value[BTREE_MAX_KEYS + 1];
-
-	/**
-	 * Pointers to descendants of this node sorted according to the key
-	 * array.
-	 *
-	 * subtree[0] points to subtree with keys lesser than to key[0].
-	 * subtree[1] points to subtree with keys greater than or equal to
-	 *	      key[0] and lesser than key[1].
-	 * ...
-	 * There is room for storing a subtree pointer for the extra key.
-	 */
-	struct btree_node *subtree[BTREE_M + 1];
-
-	/** Pointer to parent node. Root node has NULL parent. */
-	struct btree_node *parent;
-
-	/**
-	 * Link connecting leaf-level nodes. Defined only when this node is a
-	 * leaf.
-	 */
-	link_t leaf_link;
-
-	/* Variables needed by btree_print(). */
-	link_t bfs_link;
-	int depth;
-} btree_node_t;
-
-/** B-tree structure. */
-typedef struct {
-	btree_node_t *root;	/**< B-tree root node pointer. */
-	list_t leaf_list;	/**< List of leaves. */
-} btree_t;
-
-extern void btree_init(void);
-
-extern void btree_create(btree_t *t);
-extern void btree_destroy(btree_t *t);
-
-extern void btree_insert(btree_t *t, btree_key_t key, void *value,
-    btree_node_t *leaf_node);
-extern void btree_remove(btree_t *t, btree_key_t key, btree_node_t *leaf_node);
-extern void *btree_search(btree_t *t, btree_key_t key, btree_node_t **leaf_node);
-
-extern btree_node_t *btree_leaf_node_left_neighbour(btree_t *t,
-    btree_node_t *node);
-extern btree_node_t *btree_leaf_node_right_neighbour(btree_t *t,
-    btree_node_t *node);
-
-extern void btree_print(btree_t *t);
-
-extern unsigned long btree_count(btree_t *t);
-
-#endif
-
-/** @}
- */
Index: kernel/generic/include/adt/hash_table.h
===================================================================
--- kernel/generic/include/adt/hash_table.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/include/adt/hash_table.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -53,5 +53,5 @@
 
 	/** Returns the hash of the key. */
-	size_t (*key_hash)(void *key);
+	size_t (*key_hash)(const void *key);
 
 	/** True if the items are equal (have the same lookup keys). */
@@ -59,5 +59,5 @@
 
 	/** Returns true if the key is equal to the item's lookup key. */
-	bool (*key_equal)(void *key, const ht_link_t *item);
+	bool (*key_equal)(const void *key, const ht_link_t *item);
 
 	/** Hash table item removal callback.
@@ -94,8 +94,8 @@
 extern void hash_table_insert(hash_table_t *, ht_link_t *);
 extern bool hash_table_insert_unique(hash_table_t *, ht_link_t *);
-extern ht_link_t *hash_table_find(const hash_table_t *, void *);
+extern ht_link_t *hash_table_find(const hash_table_t *, const void *);
 extern ht_link_t *hash_table_find_next(const hash_table_t *, ht_link_t *,
     ht_link_t *);
-extern size_t hash_table_remove(hash_table_t *, void *);
+extern size_t hash_table_remove(hash_table_t *, const void *);
 extern void hash_table_remove_item(hash_table_t *, ht_link_t *);
 extern void hash_table_apply(hash_table_t *, bool (*)(ht_link_t *, void *),
Index: kernel/generic/include/adt/list.h
===================================================================
--- kernel/generic/include/adt/list.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/include/adt/list.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -150,5 +150,5 @@
  *
  */
-NO_TRACE static inline void link_initialize(link_t *link)
+_NO_TRACE static inline void link_initialize(link_t *link)
 {
 	link->prev = NULL;
@@ -163,5 +163,5 @@
  *
  */
-NO_TRACE static inline void list_initialize(list_t *list)
+_NO_TRACE static inline void list_initialize(list_t *list)
 {
 	list->head.prev = &list->head;
@@ -199,5 +199,5 @@
  *
  */
-NO_TRACE static inline void list_prepend(link_t *link, list_t *list)
+_NO_TRACE static inline void list_prepend(link_t *link, list_t *list)
 {
 	list_insert_after(link, &list->head);
@@ -212,5 +212,5 @@
  *
  */
-NO_TRACE static inline void list_append(link_t *link, list_t *list)
+_NO_TRACE static inline void list_append(link_t *link, list_t *list)
 {
 	list_insert_before(link, &list->head);
@@ -225,5 +225,5 @@
  *
  */
-NO_TRACE static inline void list_remove(link_t *link)
+_NO_TRACE static inline void list_remove(link_t *link)
 {
 	if ((link->prev != NULL) && (link->next != NULL)) {
@@ -242,5 +242,5 @@
  *
  */
-NO_TRACE static inline bool list_empty(const list_t *list)
+_NO_TRACE static inline bool list_empty(const list_t *list)
 {
 	return (list->head.next == &list->head);
@@ -310,5 +310,5 @@
  *
  */
-NO_TRACE static inline void headless_list_split_or_concat(link_t *part1, link_t *part2)
+_NO_TRACE static inline void headless_list_split_or_concat(link_t *part1, link_t *part2)
 {
 	part1->prev->next = part2;
@@ -331,5 +331,5 @@
  *
  */
-NO_TRACE static inline void headless_list_split(link_t *part1, link_t *part2)
+_NO_TRACE static inline void headless_list_split(link_t *part1, link_t *part2)
 {
 	headless_list_split_or_concat(part1, part2);
@@ -346,5 +346,5 @@
  *
  */
-NO_TRACE static inline void headless_list_concat(link_t *part1, link_t *part2)
+_NO_TRACE static inline void headless_list_concat(link_t *part1, link_t *part2)
 {
 	headless_list_split_or_concat(part1, part2);
@@ -361,5 +361,5 @@
  *
  */
-NO_TRACE static inline void list_concat(list_t *list1, list_t *list2)
+_NO_TRACE static inline void list_concat(list_t *list1, list_t *list2)
 {
 	list_splice(list2, list1->head.prev);
Index: kernel/generic/include/adt/odict.h
===================================================================
--- kernel/generic/include/adt/odict.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/include/adt/odict.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ODICT_H_
-#define LIBC_ODICT_H_
+#ifndef _LIBC_ODICT_H_
+#define _LIBC_ODICT_H_
 
 #include <errno.h>
Index: kernel/generic/include/bitops.h
===================================================================
--- kernel/generic/include/bitops.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/include/bitops.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -52,5 +52,5 @@
  *
  */
-NO_TRACE static inline uint8_t fnzb32(uint32_t arg)
+_NO_TRACE static inline uint8_t fnzb32(uint32_t arg)
 {
 	uint8_t n = 0;
@@ -87,5 +87,5 @@
  *
  */
-NO_TRACE static inline uint8_t fnzb64(uint64_t arg)
+_NO_TRACE static inline uint8_t fnzb64(uint64_t arg)
 {
 	uint8_t n = 0;
Index: kernel/generic/include/context.h
===================================================================
--- kernel/generic/include/context.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/include/context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -91,5 +91,5 @@
  *
  */
-NO_TRACE static inline void context_restore(context_t *ctx)
+_NO_TRACE static inline void context_restore(context_t *ctx)
 {
 	context_restore_arch(ctx);
Index: kernel/generic/include/ddi/ddi.h
===================================================================
--- kernel/generic/include/ddi/ddi.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/include/ddi/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -60,4 +60,7 @@
 extern void ddi_parea_register(parea_t *);
 
+extern void *pio_map(void *, size_t);
+extern void pio_unmap(void *, void *, size_t);
+
 extern sys_errno_t sys_physmem_map(uintptr_t, size_t, unsigned int, void *,
     uintptr_t);
Index: kernel/generic/include/lib/elf_load.h
===================================================================
--- kernel/generic/include/lib/elf_load.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/include/lib/elf_load.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,16 +38,5 @@
 #include <abi/elf.h>
 
-/**
- * ELF error return codes
- */
-#define EE_OK             0  /* No error */
-#define EE_INVALID        1  /* Invalid ELF image */
-#define EE_MEMORY         2  /* Cannot allocate address space */
-#define EE_INCOMPATIBLE   3  /* ELF image is not compatible with current architecture */
-#define EE_UNSUPPORTED    4  /* Non-supported ELF (e.g. dynamic ELFs) */
-#define EE_IRRECOVERABLE  5  /* Irrecoverable error. */
-
-extern unsigned int elf_load(elf_header_t *, as_t *);
-extern const char *elf_error(unsigned int rc);
+extern errno_t elf_load(elf_header_t *, as_t *);
 
 #endif
Index: kernel/generic/include/lib/refcount.h
===================================================================
--- kernel/generic/include/lib/refcount.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/include/lib/refcount.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,6 +37,6 @@
  */
 
-#ifndef LIBC_REFCOUNT_H_
-#define LIBC_REFCOUNT_H_
+#ifndef _LIBC_REFCOUNT_H_
+#define _LIBC_REFCOUNT_H_
 
 #include <assert.h>
Index: kernel/generic/include/macros.h
===================================================================
--- kernel/generic/include/macros.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/include/macros.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -49,5 +49,5 @@
  *
  */
-NO_TRACE static inline int overlaps(uint64_t s1, uint64_t sz1, uint64_t s2,
+_NO_TRACE static inline int overlaps(uint64_t s1, uint64_t sz1, uint64_t s2,
     uint64_t sz2)
 {
@@ -78,5 +78,5 @@
  *
  */
-NO_TRACE static inline int iswithin(uint64_t s1, uint64_t sz1, uint64_t s2,
+_NO_TRACE static inline int iswithin(uint64_t s1, uint64_t sz1, uint64_t s2,
     uint64_t sz2)
 {
Index: kernel/generic/include/mm/as.h
===================================================================
--- kernel/generic/include/mm/as.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/include/mm/as.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -45,5 +45,4 @@
 #include <synch/mutex.h>
 #include <adt/list.h>
-#include <adt/btree.h>
 #include <adt/odict.h>
 #include <lib/elf.h>
@@ -59,4 +58,10 @@
  */
 #define KERNEL_ADDRESS_SPACE_SHADOWED  KERNEL_ADDRESS_SPACE_SHADOWED_ARCH
+
+/**
+ * Defined to be true if user address space and kernel address space do not
+ * share the same page table.
+ */
+#define KERNEL_SEPARATE_PTL0 KERNEL_SEPARATE_PTL0_ARCH
 
 #define KERNEL_ADDRESS_SPACE_START  KERNEL_ADDRESS_SPACE_START_ARCH
@@ -137,4 +142,48 @@
 } as_operations_t;
 
+/** Single anonymous page mapping. */
+typedef struct {
+	/** Containing pagemap structure */
+	struct as_pagemap *pagemap;
+	/** Link to @c shinfo->pagemap ordered dictionary */
+	odlink_t lpagemap;
+	/** Virtual address */
+	uintptr_t vaddr;
+	/** Physical frame address */
+	uintptr_t frame;
+} as_page_mapping_t;
+
+/** Map of anonymous pages in a shared area. */
+typedef struct as_pagemap {
+	/**
+	 * Dictionary ordered by virtual address. Members are of type
+	 * as_page_mapping_t
+	 */
+	odict_t map;
+} as_pagemap_t;
+
+/** Used space interval */
+typedef struct {
+	/** Containing used_space structure */
+	struct used_space *used_space;
+	/** Link to @c used_space->ivals */
+	odlink_t lused_space;
+	/** First page address */
+	uintptr_t page;
+	/** Count of pages */
+	size_t count;
+} used_space_ival_t;
+
+/** Map of used space in an address space area */
+typedef struct used_space {
+	/**
+	 * Dictionary of intervals by start address.
+	 * Members are of type @c used_space_ival_t.
+	 */
+	odict_t ivals;
+	/** Total number of used pages. */
+	size_t pages;
+} used_space_t;
+
 /**
  * This structure contains information associated with the shared address space
@@ -150,8 +199,6 @@
 	bool shared;
 
-	/**
-	 * B+tree containing complete map of anonymous pages of the shared area.
-	 */
-	btree_t pagemap;
+	/** Complete map of anonymous pages of the shared area. */
+	as_pagemap_t pagemap;
 
 	/** Address space area backend. */
@@ -221,12 +268,9 @@
 	size_t pages;
 
-	/** Number of resident pages in the area. */
-	size_t resident;
-
 	/** Base address of this area. */
 	uintptr_t base;
 
 	/** Map of used space. */
-	btree_t used_space;
+	used_space_t used_space;
 
 	/**
@@ -283,9 +327,19 @@
 extern as_area_t *as_area_next(as_area_t *);
 
+extern void as_pagemap_initialize(as_pagemap_t *);
+extern void as_pagemap_finalize(as_pagemap_t *);
+extern as_page_mapping_t *as_pagemap_first(as_pagemap_t *);
+extern as_page_mapping_t *as_pagemap_next(as_page_mapping_t *);
+extern errno_t as_pagemap_find(as_pagemap_t *, uintptr_t, uintptr_t *);
+extern void as_pagemap_insert(as_pagemap_t *, uintptr_t, uintptr_t);
+extern void as_pagemap_remove(as_page_mapping_t *);
+
 extern unsigned int as_area_get_flags(as_area_t *);
 extern bool as_area_check_access(as_area_t *, pf_access_t);
 extern size_t as_area_get_size(uintptr_t);
-extern bool used_space_insert(as_area_t *, uintptr_t, size_t);
-extern bool used_space_remove(as_area_t *, uintptr_t, size_t);
+extern used_space_ival_t *used_space_first(used_space_t *);
+extern used_space_ival_t *used_space_next(used_space_ival_t *);
+extern used_space_ival_t *used_space_find_gteq(used_space_t *, uintptr_t);
+extern bool used_space_insert(used_space_t *, uintptr_t, size_t);
 
 /* Interface to be implemented by architectures. */
Index: kernel/generic/include/proc/program.h
===================================================================
--- kernel/generic/include/proc/program.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/include/proc/program.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -50,5 +50,5 @@
 	struct task *task;           /**< Program task */
 	struct thread *main_thread;  /**< Program main thread */
-	unsigned int loader_status;  /**< Binary loader error status */
+	errno_t loader_status;  /**< Binary loader error status */
 } program_t;
 
Index: kernel/generic/include/str.h
===================================================================
--- kernel/generic/include/str.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/include/str.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,6 @@
 /*
  * Copyright (c) 2001-2004 Jakub Jermar
+ * Copyright (c) 2005 Martin Decky
+ * Copyright (c) 2011 Oleg Romanenko
  * All rights reserved.
  *
@@ -36,10 +38,10 @@
 #define KERN_STR_H_
 
+#include <errno.h>
 #include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
-#include <errno.h>
 
-/**< Common Unicode characters */
+/* Common Unicode characters */
 #define U_SPECIAL      '?'
 
@@ -61,9 +63,9 @@
 #define U_CURSOR       0x2588
 
-/**< No size limit constant */
+/** No size limit constant */
 #define STR_NO_LIMIT  ((size_t) -1)
 
-/**< Maximum size of a string containing cnt characters */
-#define STR_BOUNDS(cnt)  ((cnt) << 2)
+/** Maximum size of a string containing @c length characters */
+#define STR_BOUNDS(length)  ((length) << 2)
 
 extern wchar_t str_decode(const char *str, size_t *offset, size_t sz);
@@ -92,7 +94,4 @@
 extern void wstr_to_str(char *dest, size_t size, const wchar_t *src);
 
-extern char *str_dup(const char *src);
-extern char *str_ndup(const char *src, size_t n);
-
 extern char *str_chr(const char *str, wchar_t ch);
 
@@ -100,5 +99,9 @@
 extern bool wstr_remove(wchar_t *str, size_t pos);
 
-extern errno_t str_uint64_t(const char *, char **, unsigned int, bool, uint64_t *);
+extern char *str_dup(const char *src);
+extern char *str_ndup(const char *src, size_t n);
+
+extern errno_t str_uint64_t(const char *, char **, unsigned int, bool,
+    uint64_t *);
 
 extern void order_suffix(const uint64_t, uint64_t *, char *);
Index: kernel/generic/include/synch/spinlock.h
===================================================================
--- kernel/generic/include/synch/spinlock.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/include/synch/spinlock.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -103,5 +103,5 @@
  * @param lock  Pointer to spinlock_t structure.
  */
-NO_TRACE static inline void spinlock_lock(spinlock_t *lock)
+_NO_TRACE static inline void spinlock_lock(spinlock_t *lock)
 {
 	preemption_disable();
@@ -115,5 +115,5 @@
  * @param lock  Pointer to spinlock_t structure.
  */
-NO_TRACE static inline void spinlock_unlock(spinlock_t *lock)
+_NO_TRACE static inline void spinlock_unlock(spinlock_t *lock)
 {
 	atomic_flag_clear_explicit(&lock->flag, memory_order_release);
Index: kernel/generic/include/trace.h
===================================================================
--- kernel/generic/include/trace.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/include/trace.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -36,5 +36,5 @@
 #define KERN_TRACE_H_
 
-#define NO_TRACE  __attribute__((no_instrument_function))
+#define _NO_TRACE  __attribute__((no_instrument_function))
 
 #endif
Index: kernel/generic/include/types/adt/odict.h
===================================================================
--- kernel/generic/include/types/adt/odict.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/include/types/adt/odict.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_ODICT_H_
-#define LIBC_TYPES_ODICT_H_
+#ifndef _LIBC_TYPES_ODICT_H_
+#define _LIBC_TYPES_ODICT_H_
 
 #include <adt/list.h>
Index: rnel/generic/src/adt/btree.c
===================================================================
--- kernel/generic/src/adt/btree.c	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,1070 +1,0 @@
-/*
- * 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 kernel_generic_adt
- * @{
- */
-
-/**
- * @file
- * @brief B+tree implementation.
- *
- * This file implements B+tree type and operations.
- *
- * The B+tree has the following properties:
- * @li it is a balanced 3-4-5 tree (i.e. BTREE_M = 5)
- * @li values (i.e. pointers to values) are stored only in leaves
- * @li leaves are linked in a list
- *
- * Be careful when using these trees. They need to allocate
- * and deallocate memory for their index nodes and as such
- * can sleep.
- */
-
-#include <adt/btree.h>
-#include <adt/list.h>
-#include <assert.h>
-#include <mm/slab.h>
-#include <panic.h>
-#include <stdio.h>
-#include <trace.h>
-
-static slab_cache_t *btree_node_cache;
-
-#define ROOT_NODE(n)   (!(n)->parent)
-#define INDEX_NODE(n)  ((n)->subtree[0] != NULL)
-#define LEAF_NODE(n)   ((n)->subtree[0] == NULL)
-
-#define FILL_FACTOR  ((BTREE_M - 1) / 2)
-
-#define MEDIAN_LOW_INDEX(n)   (((n)->keys-1) / 2)
-#define MEDIAN_HIGH_INDEX(n)  ((n)->keys / 2)
-#define MEDIAN_LOW(n)         ((n)->key[MEDIAN_LOW_INDEX((n))]);
-#define MEDIAN_HIGH(n)        ((n)->key[MEDIAN_HIGH_INDEX((n))]);
-
-/** Initialize B-trees. */
-void btree_init(void)
-{
-	btree_node_cache = slab_cache_create("btree_node_t",
-	    sizeof(btree_node_t), 0, NULL, NULL, SLAB_CACHE_MAGDEFERRED);
-}
-
-/** Initialize B-tree node.
- *
- * @param node B-tree node.
- *
- */
-NO_TRACE static void node_initialize(btree_node_t *node)
-{
-	unsigned int i;
-
-	node->keys = 0;
-
-	/* Clean also space for the extra key. */
-	for (i = 0; i < BTREE_MAX_KEYS + 1; i++) {
-		node->key[i] = 0;
-		node->value[i] = NULL;
-		node->subtree[i] = NULL;
-	}
-
-	node->subtree[i] = NULL;
-	node->parent = NULL;
-
-	link_initialize(&node->leaf_link);
-	link_initialize(&node->bfs_link);
-	node->depth = 0;
-}
-
-/** Create empty B-tree.
- *
- * @param t B-tree.
- *
- */
-void btree_create(btree_t *t)
-{
-	list_initialize(&t->leaf_list);
-	t->root = (btree_node_t *) slab_alloc(btree_node_cache, 0);
-	node_initialize(t->root);
-	list_append(&t->root->leaf_link, &t->leaf_list);
-}
-
-/** Destroy subtree rooted in a node.
- *
- * @param root Root of the subtree.
- *
- */
-NO_TRACE static void btree_destroy_subtree(btree_node_t *root)
-{
-	size_t i;
-
-	if (root->keys) {
-		for (i = 0; i < root->keys + 1; i++) {
-			if (root->subtree[i])
-				btree_destroy_subtree(root->subtree[i]);
-		}
-	}
-
-	slab_free(btree_node_cache, root);
-}
-
-/** Destroy empty B-tree. */
-void btree_destroy(btree_t *t)
-{
-	btree_destroy_subtree(t->root);
-}
-
-/** Insert key-value-rsubtree triplet into B-tree node.
- *
- * It is actually possible to have more keys than BTREE_MAX_KEYS.
- * This feature is used during splitting the node when the
- * number of keys is BTREE_MAX_KEYS + 1. Insert by left rotation
- * also makes use of this feature.
- *
- * @param node     B-tree node into which the new key is to be inserted.
- * @param key      The key to be inserted.
- * @param value    Pointer to value to be inserted.
- * @param rsubtree Pointer to the right subtree.
- *
- */
-NO_TRACE static void node_insert_key_and_rsubtree(btree_node_t *node,
-    btree_key_t key, void *value, btree_node_t *rsubtree)
-{
-	size_t i;
-
-	for (i = 0; i < node->keys; i++) {
-		if (key < node->key[i]) {
-			size_t j;
-
-			for (j = node->keys; j > i; j--) {
-				node->key[j] = node->key[j - 1];
-				node->value[j] = node->value[j - 1];
-				node->subtree[j + 1] = node->subtree[j];
-			}
-
-			break;
-		}
-	}
-
-	node->key[i] = key;
-	node->value[i] = value;
-	node->subtree[i + 1] = rsubtree;
-	node->keys++;
-}
-
-/** Find key by its left or right subtree.
- *
- * @param node    B-tree node.
- * @param subtree Left or right subtree of a key found in node.
- * @param right   If true, subtree is a right subtree. If false,
- *                subtree is a left subtree.
- *
- * @return Index of the key associated with the subtree.
- *
- */
-NO_TRACE static size_t find_key_by_subtree(btree_node_t *node,
-    btree_node_t *subtree, bool right)
-{
-	size_t i;
-
-	for (i = 0; i < node->keys + 1; i++) {
-		if (subtree == node->subtree[i])
-			return i - (int) (right != false);
-	}
-
-	panic("Node %p does not contain subtree %p.", node, subtree);
-}
-
-/** Remove key and its left subtree pointer from B-tree node.
- *
- * Remove the key and eliminate gaps in node->key array.
- * Note that the value pointer and the left subtree pointer
- * is removed from the node as well.
- *
- * @param node B-tree node.
- * @param key  Key to be removed.
- *
- */
-NO_TRACE static void node_remove_key_and_lsubtree(btree_node_t *node,
-    btree_key_t key)
-{
-	size_t i;
-	size_t j;
-
-	for (i = 0; i < node->keys; i++) {
-		if (key == node->key[i]) {
-			for (j = i + 1; j < node->keys; j++) {
-				node->key[j - 1] = node->key[j];
-				node->value[j - 1] = node->value[j];
-				node->subtree[j - 1] = node->subtree[j];
-			}
-
-			node->subtree[j - 1] = node->subtree[j];
-			node->keys--;
-
-			return;
-		}
-	}
-
-	panic("Node %p does not contain key %" PRIu64 ".", node, key);
-}
-
-/** Remove key and its right subtree pointer from B-tree node.
- *
- * Remove the key and eliminate gaps in node->key array.
- * Note that the value pointer and the right subtree pointer
- * is removed from the node as well.
- *
- * @param node B-tree node.
- * @param key  Key to be removed.
- *
- */
-NO_TRACE static void node_remove_key_and_rsubtree(btree_node_t *node,
-    btree_key_t key)
-{
-	size_t i, j;
-
-	for (i = 0; i < node->keys; i++) {
-		if (key == node->key[i]) {
-			for (j = i + 1; j < node->keys; j++) {
-				node->key[j - 1] = node->key[j];
-				node->value[j - 1] = node->value[j];
-				node->subtree[j] = node->subtree[j + 1];
-			}
-
-			node->keys--;
-			return;
-		}
-	}
-
-	panic("Node %p does not contain key %" PRIu64 ".", node, key);
-}
-
-/** Insert key-value-lsubtree triplet into B-tree node.
- *
- * It is actually possible to have more keys than BTREE_MAX_KEYS.
- * This feature is used during insert by right rotation.
- *
- * @param node     B-tree node into which the new key is to be inserted.
- * @param key      The key to be inserted.
- * @param value    Pointer to value to be inserted.
- * @param lsubtree Pointer to the left subtree.
- *
- */
-NO_TRACE static void node_insert_key_and_lsubtree(btree_node_t *node,
-    btree_key_t key, void *value, btree_node_t *lsubtree)
-{
-	size_t i;
-
-	for (i = 0; i < node->keys; i++) {
-		if (key < node->key[i]) {
-			size_t j;
-
-			for (j = node->keys; j > i; j--) {
-				node->key[j] = node->key[j - 1];
-				node->value[j] = node->value[j - 1];
-				node->subtree[j + 1] = node->subtree[j];
-			}
-
-			node->subtree[j + 1] = node->subtree[j];
-			break;
-		}
-	}
-
-	node->key[i] = key;
-	node->value[i] = value;
-	node->subtree[i] = lsubtree;
-
-	node->keys++;
-}
-
-/** Rotate one key-value-rsubtree triplet from the left sibling to the right sibling.
- *
- * The biggest key and its value and right subtree is rotated
- * from the left node to the right. If the node is an index node,
- * than the parent node key belonging to the left node takes part
- * in the rotation.
- *
- * @param lnode Left sibling.
- * @param rnode Right sibling.
- * @param idx   Index of the parent node key that is taking part
- *              in the rotation.
- *
- */
-NO_TRACE static void rotate_from_left(btree_node_t *lnode, btree_node_t *rnode,
-    size_t idx)
-{
-	btree_key_t key = lnode->key[lnode->keys - 1];
-
-	if (LEAF_NODE(lnode)) {
-		void *value = lnode->value[lnode->keys - 1];
-
-		node_remove_key_and_rsubtree(lnode, key);
-		node_insert_key_and_lsubtree(rnode, key, value, NULL);
-		lnode->parent->key[idx] = key;
-	} else {
-		btree_node_t *rsubtree = lnode->subtree[lnode->keys];
-
-		node_remove_key_and_rsubtree(lnode, key);
-		node_insert_key_and_lsubtree(rnode, lnode->parent->key[idx], NULL, rsubtree);
-		lnode->parent->key[idx] = key;
-
-		/* Fix parent link of the reconnected right subtree. */
-		rsubtree->parent = rnode;
-	}
-}
-
-/** Rotate one key-value-lsubtree triplet from the right sibling to the left sibling.
- *
- * The smallest key and its value and left subtree is rotated
- * from the right node to the left. If the node is an index node,
- * than the parent node key belonging to the right node takes part
- * in the rotation.
- *
- * @param lnode Left sibling.
- * @param rnode Right sibling.
- * @param idx   Index of the parent node key that is taking part
- *              in the rotation.
- *
- */
-NO_TRACE static void rotate_from_right(btree_node_t *lnode, btree_node_t *rnode,
-    size_t idx)
-{
-	btree_key_t key = rnode->key[0];
-
-	if (LEAF_NODE(rnode)) {
-		void *value = rnode->value[0];
-
-		node_remove_key_and_lsubtree(rnode, key);
-		node_insert_key_and_rsubtree(lnode, key, value, NULL);
-		rnode->parent->key[idx] = rnode->key[0];
-	} else {
-		btree_node_t *lsubtree = rnode->subtree[0];
-
-		node_remove_key_and_lsubtree(rnode, key);
-		node_insert_key_and_rsubtree(lnode, rnode->parent->key[idx], NULL, lsubtree);
-		rnode->parent->key[idx] = key;
-
-		/* Fix parent link of the reconnected left subtree. */
-		lsubtree->parent = lnode;
-	}
-}
-
-/** Insert key-value-rsubtree triplet and rotate the node to the left, if this operation can be done.
- *
- * Left sibling of the node (if it exists) is checked for free space.
- * If there is free space, the key is inserted and the smallest key of
- * the node is moved there. The index node which is the parent of both
- * nodes is fixed.
- *
- * @param node     B-tree node.
- * @param inskey   Key to be inserted.
- * @param insvalue Value to be inserted.
- * @param rsubtree Right subtree of inskey.
- *
- * @return True if the rotation was performed, false otherwise.
- *
- */
-NO_TRACE static bool try_insert_by_rotation_to_left(btree_node_t *node,
-    btree_key_t inskey, void *insvalue, btree_node_t *rsubtree)
-{
-	size_t idx;
-	btree_node_t *lnode;
-
-	/*
-	 * If this is root node, the rotation can not be done.
-	 */
-	if (ROOT_NODE(node))
-		return false;
-
-	idx = find_key_by_subtree(node->parent, node, true);
-	if ((int) idx == -1) {
-		/*
-		 * If this node is the leftmost subtree of its parent,
-		 * the rotation can not be done.
-		 */
-		return false;
-	}
-
-	lnode = node->parent->subtree[idx];
-	if (lnode->keys < BTREE_MAX_KEYS) {
-		/*
-		 * The rotaion can be done. The left sibling has free space.
-		 */
-		node_insert_key_and_rsubtree(node, inskey, insvalue, rsubtree);
-		rotate_from_right(lnode, node, idx);
-		return true;
-	}
-
-	return false;
-}
-
-/** Insert key-value-rsubtree triplet and rotate the node to the right, if this operation can be done.
- *
- * Right sibling of the node (if it exists) is checked for free space.
- * If there is free space, the key is inserted and the biggest key of
- * the node is moved there. The index node which is the parent of both
- * nodes is fixed.
- *
- * @param node     B-tree node.
- * @param inskey   Key to be inserted.
- * @param insvalue Value to be inserted.
- * @param rsubtree Right subtree of inskey.
- *
- * @return True if the rotation was performed, false otherwise.
- *
- */
-NO_TRACE static bool try_insert_by_rotation_to_right(btree_node_t *node,
-    btree_key_t inskey, void *insvalue, btree_node_t *rsubtree)
-{
-	size_t idx;
-	btree_node_t *rnode;
-
-	/*
-	 * If this is root node, the rotation can not be done.
-	 */
-	if (ROOT_NODE(node))
-		return false;
-
-	idx = find_key_by_subtree(node->parent, node, false);
-	if (idx == node->parent->keys) {
-		/*
-		 * If this node is the rightmost subtree of its parent,
-		 * the rotation can not be done.
-		 */
-		return false;
-	}
-
-	rnode = node->parent->subtree[idx + 1];
-	if (rnode->keys < BTREE_MAX_KEYS) {
-		/*
-		 * The rotation can be done. The right sibling has free space.
-		 */
-		node_insert_key_and_rsubtree(node, inskey, insvalue, rsubtree);
-		rotate_from_left(node, rnode, idx);
-		return true;
-	}
-
-	return false;
-}
-
-/** Split full B-tree node and insert new key-value-right-subtree triplet.
- *
- * This function will split a node and return a pointer to a newly created
- * node containing keys greater than or equal to the greater of medians
- * (or median) of the old keys and the newly added key. It will also write
- * the median key to a memory address supplied by the caller.
- *
- * If the node being split is an index node, the median will not be
- * included in the new node. If the node is a leaf node,
- * the median will be copied there.
- *
- * @param node     B-tree node which is going to be split.
- * @param key      The key to be inserted.
- * @param value    Pointer to the value to be inserted.
- * @param rsubtree Pointer to the right subtree of the key being added.
- * @param median   Address in memory, where the median key will be stored.
- *
- * @return Newly created right sibling of node.
- *
- */
-NO_TRACE static btree_node_t *node_split(btree_node_t *node, btree_key_t key,
-    void *value, btree_node_t *rsubtree, btree_key_t *median)
-{
-	btree_node_t *rnode;
-	size_t i;
-	size_t j;
-
-	assert(median);
-	assert(node->keys == BTREE_MAX_KEYS);
-
-	/*
-	 * Use the extra space to store the extra node.
-	 */
-	node_insert_key_and_rsubtree(node, key, value, rsubtree);
-
-	/*
-	 * Compute median of keys.
-	 */
-	*median = MEDIAN_HIGH(node);
-
-	/*
-	 * Allocate and initialize new right sibling.
-	 */
-	rnode = (btree_node_t *) slab_alloc(btree_node_cache, 0);
-	node_initialize(rnode);
-	rnode->parent = node->parent;
-	rnode->depth = node->depth;
-
-	/*
-	 * Copy big keys, values and subtree pointers to the new right sibling.
-	 * If this is an index node, do not copy the median.
-	 */
-	i = (size_t) INDEX_NODE(node);
-	for (i += MEDIAN_HIGH_INDEX(node), j = 0; i < node->keys; i++, j++) {
-		rnode->key[j] = node->key[i];
-		rnode->value[j] = node->value[i];
-		rnode->subtree[j] = node->subtree[i];
-
-		/*
-		 * Fix parent links in subtrees.
-		 */
-		if (rnode->subtree[j])
-			rnode->subtree[j]->parent = rnode;
-	}
-
-	rnode->subtree[j] = node->subtree[i];
-	if (rnode->subtree[j])
-		rnode->subtree[j]->parent = rnode;
-
-	rnode->keys = j;  /* Set number of keys of the new node. */
-	node->keys /= 2;  /* Shrink the old node. */
-
-	return rnode;
-}
-
-/** Recursively insert into B-tree.
- *
- * @param t        B-tree.
- * @param key      Key to be inserted.
- * @param value    Value to be inserted.
- * @param rsubtree Right subtree of the inserted key.
- * @param node     Start inserting into this node.
- *
- */
-NO_TRACE static void _btree_insert(btree_t *t, btree_key_t key, void *value,
-    btree_node_t *rsubtree, btree_node_t *node)
-{
-	if (node->keys < BTREE_MAX_KEYS) {
-		/*
-		 * Node contains enough space, the key can be stored immediately.
-		 */
-		node_insert_key_and_rsubtree(node, key, value, rsubtree);
-	} else if (try_insert_by_rotation_to_left(node, key, value, rsubtree)) {
-		/*
-		 * The key-value-rsubtree triplet has been inserted because
-		 * some keys could have been moved to the left sibling.
-		 */
-	} else if (try_insert_by_rotation_to_right(node, key, value, rsubtree)) {
-		/*
-		 * The key-value-rsubtree triplet has been inserted because
-		 * some keys could have been moved to the right sibling.
-		 */
-	} else {
-		btree_node_t *rnode;
-		btree_key_t median;
-
-		/*
-		 * Node is full and both siblings (if both exist) are full too.
-		 * Split the node and insert the smallest key from the node containing
-		 * bigger keys (i.e. the new node) into its parent.
-		 */
-
-		rnode = node_split(node, key, value, rsubtree, &median);
-
-		if (LEAF_NODE(node)) {
-			list_insert_after(&rnode->leaf_link, &node->leaf_link);
-		}
-
-		if (ROOT_NODE(node)) {
-			/*
-			 * We split the root node. Create new root.
-			 */
-			t->root = (btree_node_t *) slab_alloc(btree_node_cache, 0);
-			node->parent = t->root;
-			rnode->parent = t->root;
-			node_initialize(t->root);
-
-			/*
-			 * Left-hand side subtree will be the old root (i.e. node).
-			 * Right-hand side subtree will be rnode.
-			 */
-			t->root->subtree[0] = node;
-
-			t->root->depth = node->depth + 1;
-		}
-		_btree_insert(t, median, NULL, rnode, node->parent);
-	}
-}
-
-/** Insert key-value pair into B-tree.
- *
- * @param t         B-tree.
- * @param key       Key to be inserted.
- * @param value     Value to be inserted.
- * @param leaf_node Leaf node where the insertion should begin.
- *
- */
-void btree_insert(btree_t *t, btree_key_t key, void *value,
-    btree_node_t *leaf_node)
-{
-	btree_node_t *lnode;
-
-	assert(value);
-
-	lnode = leaf_node;
-	if (!lnode) {
-		if (btree_search(t, key, &lnode))
-			panic("B-tree %p already contains key %" PRIu64 ".", t, key);
-	}
-
-	_btree_insert(t, key, value, NULL, lnode);
-}
-
-/** Rotate in a key from the left sibling or from the index node, if this operation can be done.
- *
- * @param rnode Node into which to add key from its left sibling
- *              or from the index node.
- *
- * @return True if the rotation was performed, false otherwise.
- *
- */
-NO_TRACE static bool try_rotation_from_left(btree_node_t *rnode)
-{
-	size_t idx;
-	btree_node_t *lnode;
-
-	/*
-	 * If this is root node, the rotation can not be done.
-	 */
-	if (ROOT_NODE(rnode))
-		return false;
-
-	idx = find_key_by_subtree(rnode->parent, rnode, true);
-	if ((int) idx == -1) {
-		/*
-		 * If this node is the leftmost subtree of its parent,
-		 * the rotation can not be done.
-		 */
-		return false;
-	}
-
-	lnode = rnode->parent->subtree[idx];
-	if (lnode->keys > FILL_FACTOR) {
-		rotate_from_left(lnode, rnode, idx);
-		return true;
-	}
-
-	return false;
-}
-
-/** Rotate in a key from the right sibling or from the index node, if this operation can be done.
- *
- * @param lnode Node into which to add key from its right sibling
- *              or from the index node.
- *
- * @return True if the rotation was performed, false otherwise.
- *
- */
-NO_TRACE static bool try_rotation_from_right(btree_node_t *lnode)
-{
-	size_t idx;
-	btree_node_t *rnode;
-
-	/*
-	 * If this is root node, the rotation can not be done.
-	 */
-	if (ROOT_NODE(lnode))
-		return false;
-
-	idx = find_key_by_subtree(lnode->parent, lnode, false);
-	if (idx == lnode->parent->keys) {
-		/*
-		 * If this node is the rightmost subtree of its parent,
-		 * the rotation can not be done.
-		 */
-		return false;
-	}
-
-	rnode = lnode->parent->subtree[idx + 1];
-	if (rnode->keys > FILL_FACTOR) {
-		rotate_from_right(lnode, rnode, idx);
-		return true;
-	}
-
-	return false;
-}
-
-/** Combine node with any of its siblings.
- *
- * The siblings are required to be below the fill factor.
- *
- * @param node Node to combine with one of its siblings.
- *
- * @return Pointer to the rightmost of the two nodes.
- *
- */
-NO_TRACE static btree_node_t *node_combine(btree_node_t *node)
-{
-	size_t idx;
-	btree_node_t *rnode;
-	size_t i;
-
-	assert(!ROOT_NODE(node));
-
-	idx = find_key_by_subtree(node->parent, node, false);
-	if (idx == node->parent->keys) {
-		/*
-		 * Rightmost subtree of its parent, combine with the left sibling.
-		 */
-		idx--;
-		rnode = node;
-		node = node->parent->subtree[idx];
-	} else
-		rnode = node->parent->subtree[idx + 1];
-
-	/* Index nodes need to insert parent node key in between left and right node. */
-	if (INDEX_NODE(node))
-		node->key[node->keys++] = node->parent->key[idx];
-
-	/* Copy the key-value-subtree triplets from the right node. */
-	for (i = 0; i < rnode->keys; i++) {
-		node->key[node->keys + i] = rnode->key[i];
-		node->value[node->keys + i] = rnode->value[i];
-
-		if (INDEX_NODE(node)) {
-			node->subtree[node->keys + i] = rnode->subtree[i];
-			rnode->subtree[i]->parent = node;
-		}
-	}
-
-	if (INDEX_NODE(node)) {
-		node->subtree[node->keys + i] = rnode->subtree[i];
-		rnode->subtree[i]->parent = node;
-	}
-
-	node->keys += rnode->keys;
-	return rnode;
-}
-
-/** Recursively remove B-tree node.
- *
- * @param t    B-tree.
- * @param key  Key to be removed from the B-tree along with its associated value.
- * @param node Node where the key being removed resides.
- *
- */
-NO_TRACE static void _btree_remove(btree_t *t, btree_key_t key,
-    btree_node_t *node)
-{
-	if (ROOT_NODE(node)) {
-		if ((node->keys == 1) && (node->subtree[0])) {
-			/*
-			 * Free the current root and set new root.
-			 */
-			t->root = node->subtree[0];
-			t->root->parent = NULL;
-			slab_free(btree_node_cache, node);
-		} else {
-			/*
-			 * Remove the key from the root node.
-			 * Note that the right subtree is removed because when
-			 * combining two nodes, the left-side sibling is preserved
-			 * and the right-side sibling is freed.
-			 */
-			node_remove_key_and_rsubtree(node, key);
-		}
-
-		return;
-	}
-
-	if (node->keys <= FILL_FACTOR) {
-		/*
-		 * If the node is below the fill factor,
-		 * try to borrow keys from left or right sibling.
-		 */
-		if (!try_rotation_from_left(node))
-			try_rotation_from_right(node);
-	}
-
-	if (node->keys > FILL_FACTOR) {
-		size_t i;
-
-		/*
-		 * The key can be immediately removed.
-		 *
-		 * Note that the right subtree is removed because when
-		 * combining two nodes, the left-side sibling is preserved
-		 * and the right-side sibling is freed.
-		 */
-		node_remove_key_and_rsubtree(node, key);
-
-		for (i = 0; i < node->parent->keys; i++) {
-			if (node->parent->key[i] == key)
-				node->parent->key[i] = node->key[0];
-		}
-	} else {
-		size_t idx;
-		btree_node_t *rnode;
-		btree_node_t *parent;
-
-		/*
-		 * The node is below the fill factor as well as its left and right sibling.
-		 * Resort to combining the node with one of its siblings.
-		 * The node which is on the left is preserved and the node on the right is
-		 * freed.
-		 */
-		parent = node->parent;
-		node_remove_key_and_rsubtree(node, key);
-		rnode = node_combine(node);
-
-		if (LEAF_NODE(rnode))
-			list_remove(&rnode->leaf_link);
-
-		idx = find_key_by_subtree(parent, rnode, true);
-		assert((int) idx != -1);
-		slab_free(btree_node_cache, rnode);
-		_btree_remove(t, parent->key[idx], parent);
-	}
-}
-
-/** Remove B-tree node.
- *
- * @param t         B-tree.
- * @param key       Key to be removed from the B-tree along
- *                  with its associated value.
- * @param leaf_node If not NULL, pointer to the leaf node where
- *                  the key is found.
- *
- */
-void btree_remove(btree_t *t, btree_key_t key, btree_node_t *leaf_node)
-{
-	btree_node_t *lnode;
-
-	lnode = leaf_node;
-	if (!lnode) {
-		if (!btree_search(t, key, &lnode))
-			panic("B-tree %p does not contain key %" PRIu64 ".", t, key);
-	}
-
-	_btree_remove(t, key, lnode);
-}
-
-/** Search key in a B-tree.
- *
- * @param t         B-tree.
- * @param key       Key to be searched.
- * @param leaf_node Address where to put pointer to visited leaf node.
- *
- * @return Pointer to value or NULL if there is no such key.
- *
- */
-void *btree_search(btree_t *t, btree_key_t key, btree_node_t **leaf_node)
-{
-	btree_node_t *cur, *next;
-	bool descend;
-
-	/*
-	 * Iteratively descend to the leaf that can contain the searched key.
-	 */
-	for (cur = t->root; cur; cur = next) {
-		/*
-		 * Last iteration will set this with proper
-		 * leaf node address.
-		 */
-		*leaf_node = cur;
-
-		if (cur->keys == 0)
-			return NULL;
-
-		/*
-		 * The key can be in the leftmost subtree.
-		 * Test it separately.
-		 */
-		if (key < cur->key[0]) {
-			next = cur->subtree[0];
-			continue;
-		} else {
-			void *val;
-			size_t i;
-
-			/*
-			 * Now if the key is smaller than cur->key[i]
-			 * it can only mean that the value is in cur->subtree[i]
-			 * or it is not in the tree at all.
-			 */
-			descend = false;
-			for (i = 1; i < cur->keys; i++) {
-				if (key < cur->key[i]) {
-					next = cur->subtree[i];
-					val = cur->value[i - 1];
-
-					if (LEAF_NODE(cur))
-						return key == cur->key[i - 1] ? val : NULL;
-
-					descend = true;
-					break;
-				}
-			}
-
-			if (descend)
-				continue;
-
-			/*
-			 * Last possibility is that the key is
-			 * in the rightmost subtree.
-			 */
-			next = cur->subtree[i];
-			val = cur->value[i - 1];
-
-			if (LEAF_NODE(cur))
-				return key == cur->key[i - 1] ? val : NULL;
-		}
-	}
-
-	/*
-	 * The key was not found in the *leaf_node and
-	 * is smaller than any of its keys.
-	 */
-	return NULL;
-}
-
-/** Return pointer to B-tree leaf node's left neighbour.
- *
- * @param t    B-tree.
- * @param node Node whose left neighbour will be returned.
- *
- * @return Left neighbour of the node or NULL if the node
- *         does not have the left neighbour.
- *
- */
-btree_node_t *btree_leaf_node_left_neighbour(btree_t *t, btree_node_t *node)
-{
-	assert(LEAF_NODE(node));
-
-	if (node->leaf_link.prev != &t->leaf_list.head)
-		return list_get_instance(node->leaf_link.prev, btree_node_t, leaf_link);
-	else
-		return NULL;
-}
-
-/** Return pointer to B-tree leaf node's right neighbour.
- *
- * @param t    B-tree.
- * @param node Node whose right neighbour will be returned.
- *
- * @return Right neighbour of the node or NULL if the node
- *         does not have the right neighbour.
- *
- */
-btree_node_t *btree_leaf_node_right_neighbour(btree_t *t, btree_node_t *node)
-{
-	assert(LEAF_NODE(node));
-
-	if (node->leaf_link.next != &t->leaf_list.head)
-		return list_get_instance(node->leaf_link.next, btree_node_t, leaf_link);
-	else
-		return NULL;
-}
-
-/** Print B-tree.
- *
- * @param t Print out B-tree.
- *
- */
-void btree_print(btree_t *t)
-{
-	size_t i;
-	int depth = t->root->depth;
-	list_t list;
-
-	printf("Printing B-tree:\n");
-	list_initialize(&list);
-	list_append(&t->root->bfs_link, &list);
-
-	/*
-	 * Use BFS search to print out the tree.
-	 * Levels are distinguished from one another by node->depth.
-	 */
-	while (!list_empty(&list)) {
-		link_t *hlp;
-		btree_node_t *node;
-
-		hlp = list_first(&list);
-		assert(hlp != NULL);
-		node = list_get_instance(hlp, btree_node_t, bfs_link);
-		list_remove(hlp);
-
-		assert(node);
-
-		if (node->depth != depth) {
-			printf("\n");
-			depth = node->depth;
-		}
-
-		printf("(");
-
-		for (i = 0; i < node->keys; i++) {
-			printf("%" PRIu64 "%s", node->key[i], i < node->keys - 1 ? "," : "");
-			if (node->depth && node->subtree[i]) {
-				list_append(&node->subtree[i]->bfs_link, &list);
-			}
-		}
-
-		if (node->depth && node->subtree[i])
-			list_append(&node->subtree[i]->bfs_link, &list);
-
-		printf(")");
-	}
-
-	printf("\n");
-
-	printf("Printing list of leaves:\n");
-	list_foreach(t->leaf_list, leaf_link, btree_node_t, node) {
-		assert(node);
-
-		printf("(");
-
-		for (i = 0; i < node->keys; i++)
-			printf("%" PRIu64 "%s", node->key[i], i < node->keys - 1 ? "," : "");
-
-		printf(")");
-	}
-
-	printf("\n");
-}
-
-/** Return number of B-tree elements.
- *
- * @param t B-tree to count.
- *
- * @return Return number of B-tree elements.
- *
- */
-unsigned long btree_count(btree_t *t)
-{
-	unsigned long count = 0;
-
-	list_foreach(t->leaf_list, leaf_link, btree_node_t, node) {
-		count += node->keys;
-	}
-
-	return count;
-}
-
-/** @}
- */
Index: kernel/generic/src/adt/hash_table.c
===================================================================
--- kernel/generic/src/adt/hash_table.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/adt/hash_table.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -51,6 +51,6 @@
 #include <adt/hash_table.h>
 #include <adt/list.h>
+#include <assert.h>
 #include <stdlib.h>
-#include <assert.h>
 #include <str.h>
 
@@ -245,5 +245,5 @@
  *
  */
-ht_link_t *hash_table_find(const hash_table_t *h, void *key)
+ht_link_t *hash_table_find(const hash_table_t *h, const void *key)
 {
 	assert(h && h->bucket);
@@ -306,5 +306,5 @@
  * @return Returns the number of removed items.
  */
-size_t hash_table_remove(hash_table_t *h, void *key)
+size_t hash_table_remove(hash_table_t *h, const void *key)
 {
 	assert(h && h->bucket);
Index: kernel/generic/src/cap/cap.c
===================================================================
--- kernel/generic/src/cap/cap.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/cap/cap.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -98,16 +98,16 @@
 {
 	cap_t *cap = hash_table_get_inst(item, cap_t, caps_link);
-	return hash_mix(CAP_HANDLE_RAW(cap->handle));
-}
-
-static size_t caps_key_hash(void *key)
-{
-	cap_handle_t *handle = (cap_handle_t *) key;
-	return hash_mix(CAP_HANDLE_RAW(*handle));
-}
-
-static bool caps_key_equal(void *key, const ht_link_t *item)
-{
-	cap_handle_t *handle = (cap_handle_t *) key;
+	return hash_mix(cap_handle_raw(cap->handle));
+}
+
+static size_t caps_key_hash(const void *key)
+{
+	const cap_handle_t *handle = key;
+	return hash_mix(cap_handle_raw(*handle));
+}
+
+static bool caps_key_equal(const void *key, const ht_link_t *item)
+{
+	const cap_handle_t *handle = key;
 	cap_t *cap = hash_table_get_inst(item, cap_t, caps_link);
 	return *handle == cap->handle;
@@ -232,6 +232,6 @@
 	assert(mutex_locked(&task->cap_info->lock));
 
-	if ((CAP_HANDLE_RAW(handle) < CAPS_START) ||
-	    (CAP_HANDLE_RAW(handle) > CAPS_LAST))
+	if ((cap_handle_raw(handle) < CAPS_START) ||
+	    (cap_handle_raw(handle) > CAPS_LAST))
 		return NULL;
 	ht_link_t *link = hash_table_find(&task->cap_info->caps, &handle);
@@ -383,6 +383,6 @@
 void cap_free(task_t *task, cap_handle_t handle)
 {
-	assert(CAP_HANDLE_RAW(handle) >= CAPS_START);
-	assert(CAP_HANDLE_RAW(handle) <= CAPS_LAST);
+	assert(cap_handle_raw(handle) >= CAPS_START);
+	assert(cap_handle_raw(handle) <= CAPS_LAST);
 
 	mutex_lock(&task->cap_info->lock);
@@ -392,5 +392,5 @@
 
 	hash_table_remove_item(&task->cap_info->caps, &cap->caps_link);
-	ra_free(task->cap_info->handles, CAP_HANDLE_RAW(handle), 1);
+	ra_free(task->cap_info->handles, cap_handle_raw(handle), 1);
 	slab_free(cap_cache, cap);
 	mutex_unlock(&task->cap_info->lock);
Index: kernel/generic/src/console/kconsole.c
===================================================================
--- kernel/generic/src/console/kconsole.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/console/kconsole.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -156,5 +156,5 @@
 
 /** Print count times a character */
-NO_TRACE static void print_cc(wchar_t ch, size_t count)
+_NO_TRACE static void print_cc(wchar_t ch, size_t count)
 {
 	size_t i;
@@ -203,5 +203,5 @@
  *
  */
-NO_TRACE static int cmdtab_compl(char *input, size_t size, indev_t *indev,
+_NO_TRACE static int cmdtab_compl(char *input, size_t size, indev_t *indev,
     hints_enum_func_t hints_enum)
 {
@@ -290,5 +290,5 @@
 }
 
-NO_TRACE static cmd_info_t *parse_cmd(const wchar_t *cmdline)
+_NO_TRACE static cmd_info_t *parse_cmd(const wchar_t *cmdline)
 {
 	size_t start = 0;
@@ -331,5 +331,5 @@
 }
 
-NO_TRACE static wchar_t *clever_readline(const char *prompt, indev_t *indev,
+_NO_TRACE static wchar_t *clever_readline(const char *prompt, indev_t *indev,
     char *tmp)
 {
@@ -548,5 +548,5 @@
 }
 
-NO_TRACE static bool parse_int_arg(const char *text, size_t len,
+_NO_TRACE static bool parse_int_arg(const char *text, size_t len,
     sysarg_t *result)
 {
@@ -637,5 +637,5 @@
  *
  */
-NO_TRACE static bool parse_argument(const char *cmdline, size_t size,
+_NO_TRACE static bool parse_argument(const char *cmdline, size_t size,
     size_t *start, size_t *end)
 {
@@ -674,5 +674,5 @@
  *
  */
-NO_TRACE static cmd_info_t *parse_cmdline(const char *cmdline, size_t size)
+_NO_TRACE static cmd_info_t *parse_cmdline(const char *cmdline, size_t size)
 {
 	size_t start = 0;
Index: kernel/generic/src/ddi/ddi.c
===================================================================
--- kernel/generic/src/ddi/ddi.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/ddi/ddi.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -46,4 +46,5 @@
 #include <mm/frame.h>
 #include <mm/as.h>
+#include <mm/km.h>
 #include <mm/page.h>
 #include <synch/mutex.h>
@@ -56,4 +57,5 @@
 #include <trace.h>
 #include <bitops.h>
+#include <arch/asm.h>
 
 /** This lock protects the @c pareas ordered dictionary. */
@@ -121,5 +123,5 @@
  *
  */
-NO_TRACE static errno_t physmem_map(uintptr_t phys, size_t pages,
+_NO_TRACE static errno_t physmem_map(uintptr_t phys, size_t pages,
     unsigned int flags, uintptr_t *virt, uintptr_t bound)
 {
@@ -227,5 +229,5 @@
 }
 
-NO_TRACE static errno_t physmem_unmap(uintptr_t virt)
+_NO_TRACE static errno_t physmem_unmap(uintptr_t virt)
 {
 	assert(TASK);
@@ -312,5 +314,5 @@
  *
  */
-NO_TRACE static errno_t iospace_enable(task_id_t id, uintptr_t ioaddr, size_t size)
+_NO_TRACE static errno_t iospace_enable(task_id_t id, uintptr_t ioaddr, size_t size)
 {
 	/*
@@ -353,5 +355,5 @@
  *
  */
-NO_TRACE static errno_t iospace_disable(task_id_t id, uintptr_t ioaddr, size_t size)
+_NO_TRACE static errno_t iospace_disable(task_id_t id, uintptr_t ioaddr, size_t size)
 {
 	/*
@@ -413,5 +415,5 @@
 }
 
-NO_TRACE static errno_t dmamem_map(uintptr_t virt, size_t size, unsigned int map_flags,
+_NO_TRACE static errno_t dmamem_map(uintptr_t virt, size_t size, unsigned int map_flags,
     unsigned int flags, uintptr_t *phys)
 {
@@ -422,5 +424,5 @@
 }
 
-NO_TRACE static errno_t dmamem_map_anonymous(size_t size, uintptr_t constraint,
+_NO_TRACE static errno_t dmamem_map_anonymous(size_t size, uintptr_t constraint,
     unsigned int map_flags, unsigned int flags, uintptr_t *phys,
     uintptr_t *virt, uintptr_t bound)
@@ -451,5 +453,5 @@
 }
 
-NO_TRACE static errno_t dmamem_unmap(uintptr_t virt, size_t size)
+_NO_TRACE static errno_t dmamem_unmap(uintptr_t virt, size_t size)
 {
 	// TODO: implement unlocking & unmap
@@ -457,5 +459,5 @@
 }
 
-NO_TRACE static errno_t dmamem_unmap_anonymous(uintptr_t virt)
+_NO_TRACE static errno_t dmamem_unmap_anonymous(uintptr_t virt)
 {
 	return as_area_destroy(TASK->as, virt);
@@ -527,4 +529,22 @@
 		return dmamem_unmap_anonymous(virt);
 }
+void *pio_map(void *phys, size_t size)
+{
+#ifdef IO_SPACE_BOUNDARY
+	if (phys < IO_SPACE_BOUNDARY)
+		return phys;
+#endif
+	return (void *) km_map((uintptr_t) phys, size, KM_NATURAL_ALIGNMENT,
+	    PAGE_READ | PAGE_WRITE | PAGE_NOT_CACHEABLE);
+}
+
+void pio_unmap(void *phys, void *virt, size_t size)
+{
+#ifdef IO_SPACE_BOUNDARY
+	if (phys < IO_SPACE_BOUNDARY)
+		return;
+#endif
+	km_unmap((uintptr_t) virt, size);
+}
 
 /** @}
Index: kernel/generic/src/ddi/irq.c
===================================================================
--- kernel/generic/src/ddi/irq.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/ddi/irq.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -73,7 +73,7 @@
 
 static size_t irq_ht_hash(const ht_link_t *);
-static size_t irq_ht_key_hash(void *);
+static size_t irq_ht_key_hash(const void *);
 static bool irq_ht_equal(const ht_link_t *, const ht_link_t *);
-static bool irq_ht_key_equal(void *, const ht_link_t *);
+static bool irq_ht_key_equal(const void *, const ht_link_t *);
 
 static hash_table_ops_t irq_ht_ops = {
@@ -208,7 +208,7 @@
 
 /** Return the hash of the key. */
-size_t irq_ht_key_hash(void *key)
-{
-	inr_t *inr = (inr_t *) key;
+size_t irq_ht_key_hash(const void *key)
+{
+	const inr_t *inr = key;
 	return hash_mix(*inr);
 }
@@ -223,7 +223,7 @@
 
 /** Return true if the key is equal to the item's lookup key. */
-bool irq_ht_key_equal(void *key, const ht_link_t *item)
-{
-	inr_t *inr = (inr_t *) key;
+bool irq_ht_key_equal(const void *key, const ht_link_t *item)
+{
+	const inr_t *inr = key;
 	irq_t *irq = hash_table_get_inst(item, irq_t, link);
 	return irq->inr == *inr;
Index: kernel/generic/src/interrupt/interrupt.c
===================================================================
--- kernel/generic/src/interrupt/interrupt.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/interrupt/interrupt.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -99,5 +99,5 @@
  *
  */
-NO_TRACE void exc_dispatch(unsigned int n, istate_t *istate)
+_NO_TRACE void exc_dispatch(unsigned int n, istate_t *istate)
 {
 #if (IVT_ITEMS > 0)
@@ -159,5 +159,5 @@
  *
  */
-NO_TRACE static void exc_undef(unsigned int n, istate_t *istate)
+_NO_TRACE static void exc_undef(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "Unhandled exception %u.", n);
@@ -165,5 +165,5 @@
 }
 
-static NO_TRACE void
+static _NO_TRACE void
 fault_from_uspace_core(istate_t *istate, const char *fmt, va_list args)
 {
@@ -185,5 +185,5 @@
  *
  */
-NO_TRACE void fault_from_uspace(istate_t *istate, const char *fmt, ...)
+_NO_TRACE void fault_from_uspace(istate_t *istate, const char *fmt, ...)
 {
 	va_list args;
@@ -197,5 +197,5 @@
  *
  */
-NO_TRACE void fault_if_from_uspace(istate_t *istate, const char *fmt, ...)
+_NO_TRACE void fault_if_from_uspace(istate_t *istate, const char *fmt, ...)
 {
 	if (!istate_from_uspace(istate))
@@ -233,5 +233,5 @@
  *
  */
-NO_TRACE static int cmd_exc_print(cmd_arg_t *argv)
+_NO_TRACE static int cmd_exc_print(cmd_arg_t *argv)
 {
 	bool excs_all;
Index: kernel/generic/src/ipc/event.c
===================================================================
--- kernel/generic/src/ipc/event.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/ipc/event.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -153,10 +153,10 @@
 				call->priv = ++event->counter;
 
-				IPC_SET_IMETHOD(call->data, event->imethod);
-				IPC_SET_ARG1(call->data, a1);
-				IPC_SET_ARG2(call->data, a2);
-				IPC_SET_ARG3(call->data, a3);
-				IPC_SET_ARG4(call->data, a4);
-				IPC_SET_ARG5(call->data, a5);
+				ipc_set_imethod(&call->data, event->imethod);
+				ipc_set_arg1(&call->data, a1);
+				ipc_set_arg2(&call->data, a2);
+				ipc_set_arg3(&call->data, a3);
+				ipc_set_arg4(&call->data, a4);
+				ipc_set_arg5(&call->data, a5);
 
 				call->data.task_id = TASK ? TASK->taskid : 0;
Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/ipc/ipc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -387,5 +387,5 @@
 {
 	_ipc_call_actions_internal(phone, call, false);
-	IPC_SET_RETVAL(call->data, err);
+	ipc_set_retval(&call->data, err);
 	_ipc_answer_free_call(call, false);
 }
@@ -485,5 +485,5 @@
 		assert(call);
 
-		IPC_SET_IMETHOD(call->data, IPC_M_PHONE_HUNGUP);
+		ipc_set_imethod(&call->data, IPC_M_PHONE_HUNGUP);
 		call->request_method = IPC_M_PHONE_HUNGUP;
 		call->flags |= IPC_CALL_DISCARD_ANSWER;
@@ -634,5 +634,5 @@
 
 		ipc_data_t old = call->data;
-		IPC_SET_RETVAL(call->data, EHANGUP);
+		ipc_set_retval(&call->data, EHANGUP);
 		answer_preprocess(call, &old);
 		_ipc_answer_free_call(call, true);
@@ -690,5 +690,5 @@
 			assert(call);
 
-			IPC_SET_IMETHOD(call->data, IPC_M_PHONE_HUNGUP);
+			ipc_set_imethod(&call->data, IPC_M_PHONE_HUNGUP);
 			call->request_method = IPC_M_PHONE_HUNGUP;
 			call->flags |= IPC_CALL_DISCARD_ANSWER;
@@ -909,7 +909,7 @@
 		printf("%-8" PRIun " %-6" PRIun " %-6" PRIun " %-6" PRIun
 		    " %-6" PRIun " %-6" PRIun " %-7x",
-		    IPC_GET_IMETHOD(call->data), IPC_GET_ARG1(call->data),
-		    IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data),
-		    IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data),
+		    ipc_get_imethod(&call->data), ipc_get_arg1(&call->data),
+		    ipc_get_arg2(&call->data), ipc_get_arg3(&call->data),
+		    ipc_get_arg4(&call->data), ipc_get_arg5(&call->data),
 		    call->flags);
 
@@ -931,5 +931,5 @@
 	mutex_lock(&phone->lock);
 	if (phone->state != IPC_PHONE_FREE) {
-		printf("%-11d %7" PRIun " ", (int) CAP_HANDLE_RAW(cap->handle),
+		printf("%-11d %7" PRIun " ", (int) cap_handle_raw(cap->handle),
 		    atomic_load(&phone->active_calls));
 
Index: kernel/generic/src/ipc/irq.c
===================================================================
--- kernel/generic/src/ipc/irq.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/ipc/irq.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -539,10 +539,10 @@
 
 		/* Set up args */
-		IPC_SET_IMETHOD(call->data, irq->notif_cfg.imethod);
-		IPC_SET_ARG1(call->data, irq->notif_cfg.scratch[1]);
-		IPC_SET_ARG2(call->data, irq->notif_cfg.scratch[2]);
-		IPC_SET_ARG3(call->data, irq->notif_cfg.scratch[3]);
-		IPC_SET_ARG4(call->data, irq->notif_cfg.scratch[4]);
-		IPC_SET_ARG5(call->data, irq->notif_cfg.scratch[5]);
+		ipc_set_imethod(&call->data, irq->notif_cfg.imethod);
+		ipc_set_arg1(&call->data, irq->notif_cfg.scratch[1]);
+		ipc_set_arg2(&call->data, irq->notif_cfg.scratch[2]);
+		ipc_set_arg3(&call->data, irq->notif_cfg.scratch[3]);
+		ipc_set_arg4(&call->data, irq->notif_cfg.scratch[4]);
+		ipc_set_arg5(&call->data, irq->notif_cfg.scratch[5]);
 
 		send_call(irq, call);
@@ -576,10 +576,10 @@
 		call->priv = ++irq->notif_cfg.counter;
 
-		IPC_SET_IMETHOD(call->data, irq->notif_cfg.imethod);
-		IPC_SET_ARG1(call->data, a1);
-		IPC_SET_ARG2(call->data, a2);
-		IPC_SET_ARG3(call->data, a3);
-		IPC_SET_ARG4(call->data, a4);
-		IPC_SET_ARG5(call->data, a5);
+		ipc_set_imethod(&call->data, irq->notif_cfg.imethod);
+		ipc_set_arg1(&call->data, a1);
+		ipc_set_arg2(&call->data, a2);
+		ipc_set_arg3(&call->data, a3);
+		ipc_set_arg4(&call->data, a4);
+		ipc_set_arg5(&call->data, a5);
 
 		send_call(irq, call);
Index: kernel/generic/src/ipc/kbox.c
===================================================================
--- kernel/generic/src/ipc/kbox.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/ipc/kbox.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -121,5 +121,5 @@
 
 	LOG("Continue with hangup message.");
-	IPC_SET_RETVAL(call->data, 0);
+	ipc_set_retval(&call->data, 0);
 	ipc_answer(&TASK->kb.box, call);
 
@@ -174,5 +174,5 @@
 			continue;  /* Try again. */
 
-		switch (IPC_GET_IMETHOD(call->data)) {
+		switch (ipc_get_imethod(&call->data)) {
 
 		case IPC_M_DEBUG:
Index: kernel/generic/src/ipc/ops/conctmeto.c
===================================================================
--- kernel/generic/src/ipc/ops/conctmeto.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/ipc/ops/conctmeto.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -59,5 +59,5 @@
 
 	/* Remember the handle */
-	IPC_SET_ARG5(call->data, (sysarg_t) phandle);
+	ipc_set_arg5(&call->data, (sysarg_t) phandle);
 
 	return EOK;
@@ -66,7 +66,7 @@
 static errno_t request_forget(call_t *call)
 {
-	cap_phone_handle_t phandle = (cap_handle_t) IPC_GET_ARG5(call->data);
+	cap_phone_handle_t phandle = (cap_handle_t) ipc_get_arg5(&call->data);
 
-	if (CAP_HANDLE_RAW(phandle) < 0)
+	if (cap_handle_raw(phandle) < 0)
 		return EOK;
 
@@ -88,11 +88,11 @@
 
 	/* Set the recipient-assigned label */
-	pobj->phone->label = IPC_GET_ARG5(answer->data);
+	pobj->phone->label = ipc_get_arg5(&answer->data);
 
 	/* Restore phone handle in answer's ARG5 */
-	IPC_SET_ARG5(answer->data, IPC_GET_ARG5(*olddata));
+	ipc_set_arg5(&answer->data, ipc_get_arg5(olddata));
 
 	/* If the user accepted the call, connect */
-	if (IPC_GET_RETVAL(answer->data) == EOK) {
+	if (ipc_get_retval(&answer->data) == EOK) {
 		/* Hand over reference from pobj to the answerbox */
 		(void) ipc_phone_connect(pobj->phone, &TASK->answerbox);
@@ -107,11 +107,11 @@
 static errno_t answer_process(call_t *answer)
 {
-	cap_phone_handle_t phandle = (cap_handle_t) IPC_GET_ARG5(answer->data);
+	cap_phone_handle_t phandle = (cap_handle_t) ipc_get_arg5(&answer->data);
 	/* Move the reference from answer->priv to pobj */
 	kobject_t *pobj = (kobject_t *) answer->priv;
 	answer->priv = 0;
 
-	if (IPC_GET_RETVAL(answer->data)) {
-		if (CAP_HANDLE_RAW(phandle) >= 0) {
+	if (ipc_get_retval(&answer->data)) {
+		if (cap_handle_raw(phandle) >= 0) {
 			/*
 			 * Cleanup the unpublished capability and drop
Index: kernel/generic/src/ipc/ops/concttome.c
===================================================================
--- kernel/generic/src/ipc/ops/concttome.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/ipc/ops/concttome.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -49,8 +49,8 @@
 		 * Set the sender-assigned label to the new phone.
 		 */
-		pobj->phone->label = IPC_GET_ARG5(call->data);
+		pobj->phone->label = ipc_get_arg5(&call->data);
 	}
 	call->priv = (sysarg_t) pobj;
-	IPC_SET_ARG5(call->data, CAP_HANDLE_RAW(phandle));
+	ipc_set_arg5(&call->data, cap_handle_raw(phandle));
 	return 0;
 }
@@ -58,8 +58,8 @@
 static errno_t answer_cleanup(call_t *answer, ipc_data_t *olddata)
 {
-	cap_phone_handle_t phandle = (cap_handle_t) IPC_GET_ARG5(*olddata);
+	cap_phone_handle_t phandle = (cap_handle_t) ipc_get_arg5(olddata);
 	kobject_t *pobj = (kobject_t *) answer->priv;
 
-	if (CAP_HANDLE_VALID(phandle)) {
+	if (cap_handle_valid(phandle)) {
 		kobject_put(pobj);
 		cap_free(TASK, phandle);
@@ -71,11 +71,11 @@
 static errno_t answer_preprocess(call_t *answer, ipc_data_t *olddata)
 {
-	cap_phone_handle_t phandle = (cap_handle_t) IPC_GET_ARG5(*olddata);
+	cap_phone_handle_t phandle = (cap_handle_t) ipc_get_arg5(olddata);
 	kobject_t *pobj = (kobject_t *) answer->priv;
 
-	if (IPC_GET_RETVAL(answer->data) != EOK) {
+	if (ipc_get_retval(&answer->data) != EOK) {
 		/* The connection was not accepted */
 		answer_cleanup(answer, olddata);
-	} else if (CAP_HANDLE_VALID(phandle)) {
+	} else if (cap_handle_valid(phandle)) {
 		/*
 		 * The connection was accepted
@@ -94,9 +94,9 @@
 		} else {
 			/* The answerbox is shutting down. */
-			IPC_SET_RETVAL(answer->data, ENOENT);
+			ipc_set_retval(&answer->data, ENOENT);
 			answer_cleanup(answer, olddata);
 		}
 	} else {
-		IPC_SET_RETVAL(answer->data, ELIMIT);
+		ipc_set_retval(&answer->data, ELIMIT);
 	}
 
Index: kernel/generic/src/ipc/ops/dataread.c
===================================================================
--- kernel/generic/src/ipc/ops/dataread.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/ipc/ops/dataread.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -43,11 +43,11 @@
 static errno_t request_preprocess(call_t *call, phone_t *phone)
 {
-	size_t size = IPC_GET_ARG2(call->data);
+	size_t size = ipc_get_arg2(&call->data);
 
 	if (size > DATA_XFER_LIMIT) {
-		int flags = IPC_GET_ARG3(call->data);
+		int flags = ipc_get_arg3(&call->data);
 
 		if (flags & IPC_XF_RESTRICT)
-			IPC_SET_ARG2(call->data, DATA_XFER_LIMIT);
+			ipc_set_arg2(&call->data, DATA_XFER_LIMIT);
 		else
 			return ELIMIT;
@@ -61,10 +61,10 @@
 	assert(!answer->buffer);
 
-	if (!IPC_GET_RETVAL(answer->data)) {
+	if (!ipc_get_retval(&answer->data)) {
 		/* The recipient agreed to send data. */
-		uintptr_t src = IPC_GET_ARG1(answer->data);
-		uintptr_t dst = IPC_GET_ARG1(*olddata);
-		size_t max_size = IPC_GET_ARG2(*olddata);
-		size_t size = IPC_GET_ARG2(answer->data);
+		uintptr_t src = ipc_get_arg1(&answer->data);
+		uintptr_t dst = ipc_get_arg1(olddata);
+		size_t max_size = ipc_get_arg2(olddata);
+		size_t size = ipc_get_arg2(&answer->data);
 
 		if (size && size <= max_size) {
@@ -73,9 +73,9 @@
 			 * information is not lost.
 			 */
-			IPC_SET_ARG1(answer->data, dst);
+			ipc_set_arg1(&answer->data, dst);
 
 			answer->buffer = malloc(size);
 			if (!answer->buffer) {
-				IPC_SET_RETVAL(answer->data, ENOMEM);
+				ipc_set_retval(&answer->data, ENOMEM);
 				return EOK;
 			}
@@ -83,5 +83,5 @@
 			    (void *) src, size);
 			if (rc) {
-				IPC_SET_RETVAL(answer->data, rc);
+				ipc_set_retval(&answer->data, rc);
 				/*
 				 * answer->buffer will be cleaned up in
@@ -91,7 +91,7 @@
 			}
 		} else if (!size) {
-			IPC_SET_RETVAL(answer->data, EOK);
+			ipc_set_retval(&answer->data, EOK);
 		} else {
-			IPC_SET_RETVAL(answer->data, ELIMIT);
+			ipc_set_retval(&answer->data, ELIMIT);
 		}
 	}
@@ -103,11 +103,11 @@
 {
 	if (answer->buffer) {
-		uintptr_t dst = IPC_GET_ARG1(answer->data);
-		size_t size = IPC_GET_ARG2(answer->data);
+		uintptr_t dst = ipc_get_arg1(&answer->data);
+		size_t size = ipc_get_arg2(&answer->data);
 		errno_t rc;
 
 		rc = copy_to_uspace((void *) dst, answer->buffer, size);
 		if (rc)
-			IPC_SET_RETVAL(answer->data, rc);
+			ipc_set_retval(&answer->data, rc);
 	}
 
Index: kernel/generic/src/ipc/ops/datawrite.c
===================================================================
--- kernel/generic/src/ipc/ops/datawrite.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/ipc/ops/datawrite.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -43,13 +43,13 @@
 static errno_t request_preprocess(call_t *call, phone_t *phone)
 {
-	uintptr_t src = IPC_GET_ARG1(call->data);
-	size_t size = IPC_GET_ARG2(call->data);
+	uintptr_t src = ipc_get_arg1(&call->data);
+	size_t size = ipc_get_arg2(&call->data);
 
 	if (size > DATA_XFER_LIMIT) {
-		int flags = IPC_GET_ARG3(call->data);
+		int flags = ipc_get_arg3(&call->data);
 
 		if (flags & IPC_XF_RESTRICT) {
 			size = DATA_XFER_LIMIT;
-			IPC_SET_ARG2(call->data, size);
+			ipc_set_arg2(&call->data, size);
 		} else
 			return ELIMIT;
@@ -75,9 +75,9 @@
 	assert(answer->buffer);
 
-	if (!IPC_GET_RETVAL(answer->data)) {
+	if (!ipc_get_retval(&answer->data)) {
 		/* The recipient agreed to receive data. */
-		uintptr_t dst = (uintptr_t)IPC_GET_ARG1(answer->data);
-		size_t size = (size_t)IPC_GET_ARG2(answer->data);
-		size_t max_size = (size_t)IPC_GET_ARG2(*olddata);
+		uintptr_t dst = (uintptr_t)ipc_get_arg1(&answer->data);
+		size_t size = (size_t)ipc_get_arg2(&answer->data);
+		size_t max_size = (size_t)ipc_get_arg2(olddata);
 
 		if (size <= max_size) {
@@ -85,7 +85,7 @@
 			    answer->buffer, size);
 			if (rc)
-				IPC_SET_RETVAL(answer->data, rc);
+				ipc_set_retval(&answer->data, rc);
 		} else {
-			IPC_SET_RETVAL(answer->data, ELIMIT);
+			ipc_set_retval(&answer->data, ELIMIT);
 		}
 	}
Index: kernel/generic/src/ipc/ops/debug.c
===================================================================
--- kernel/generic/src/ipc/ops/debug.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/ipc/ops/debug.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -47,11 +47,11 @@
 {
 	if (answer->buffer) {
-		uintptr_t dst = IPC_GET_ARG1(answer->data);
-		size_t size = IPC_GET_ARG2(answer->data);
+		uintptr_t dst = ipc_get_arg1(&answer->data);
+		size_t size = ipc_get_arg2(&answer->data);
 		errno_t rc;
 
 		rc = copy_to_uspace((void *) dst, answer->buffer, size);
 		if (rc)
-			IPC_SET_RETVAL(answer->data, rc);
+			ipc_set_retval(&answer->data, rc);
 	}
 
Index: kernel/generic/src/ipc/ops/pagein.c
===================================================================
--- kernel/generic/src/ipc/ops/pagein.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/ipc/ops/pagein.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -68,5 +68,5 @@
 		return EOK;
 
-	if (!IPC_GET_RETVAL(answer->data)) {
+	if (!ipc_get_retval(&answer->data)) {
 
 		pte_t pte;
@@ -74,5 +74,5 @@
 
 		page_table_lock(AS, true);
-		bool found = page_mapping_find(AS, IPC_GET_ARG1(answer->data),
+		bool found = page_mapping_find(AS, ipc_get_arg1(&answer->data),
 		    false, &pte);
 		if (found & PTE_PRESENT(&pte)) {
@@ -86,7 +86,7 @@
 				frame_reference_add(ADDR2PFN(frame));
 			}
-			IPC_SET_ARG1(answer->data, frame);
+			ipc_set_arg1(&answer->data, frame);
 		} else {
-			IPC_SET_RETVAL(answer->data, ENOENT);
+			ipc_set_retval(&answer->data, ENOENT);
 		}
 		page_table_unlock(AS, true);
Index: kernel/generic/src/ipc/ops/sharein.c
===================================================================
--- kernel/generic/src/ipc/ops/sharein.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/ipc/ops/sharein.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -43,5 +43,5 @@
 static errno_t answer_preprocess(call_t *answer, ipc_data_t *olddata)
 {
-	if (!IPC_GET_RETVAL(answer->data)) {
+	if (!ipc_get_retval(&answer->data)) {
 		irq_spinlock_lock(&answer->sender->lock, true);
 		as_t *as = answer->sender->as;
@@ -49,9 +49,9 @@
 
 		uintptr_t dst_base = (uintptr_t) -1;
-		errno_t rc = as_area_share(AS, IPC_GET_ARG1(answer->data),
-		    IPC_GET_ARG1(*olddata), as, IPC_GET_ARG2(answer->data),
-		    &dst_base, IPC_GET_ARG2(*olddata));
-		IPC_SET_ARG5(answer->data, dst_base);
-		IPC_SET_RETVAL(answer->data, rc);
+		errno_t rc = as_area_share(AS, ipc_get_arg1(&answer->data),
+		    ipc_get_arg1(olddata), as, ipc_get_arg2(&answer->data),
+		    &dst_base, ipc_get_arg2(olddata));
+		ipc_set_arg5(&answer->data, dst_base);
+		ipc_set_retval(&answer->data, rc);
 	}
 
Index: kernel/generic/src/ipc/ops/shareout.c
===================================================================
--- kernel/generic/src/ipc/ops/shareout.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/ipc/ops/shareout.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -44,9 +44,9 @@
 static errno_t request_preprocess(call_t *call, phone_t *phone)
 {
-	size_t size = as_area_get_size(IPC_GET_ARG1(call->data));
+	size_t size = as_area_get_size(ipc_get_arg1(&call->data));
 
 	if (!size)
 		return EPERM;
-	IPC_SET_ARG2(call->data, size);
+	ipc_set_arg2(&call->data, size);
 
 	return EOK;
@@ -57,5 +57,5 @@
 	errno_t rc = EOK;
 
-	if (!IPC_GET_RETVAL(answer->data)) {
+	if (!ipc_get_retval(&answer->data)) {
 		/* Accepted, handle as_area receipt */
 
@@ -65,14 +65,14 @@
 
 		uintptr_t dst_base = (uintptr_t) -1;
-		rc = as_area_share(as, IPC_GET_ARG1(*olddata),
-		    IPC_GET_ARG2(*olddata), AS, IPC_GET_ARG3(*olddata),
-		    &dst_base, IPC_GET_ARG1(answer->data));
+		rc = as_area_share(as, ipc_get_arg1(olddata),
+		    ipc_get_arg2(olddata), AS, ipc_get_arg3(olddata),
+		    &dst_base, ipc_get_arg1(&answer->data));
 
 		if (rc == EOK) {
-			rc = copy_to_uspace((void *) IPC_GET_ARG2(answer->data),
+			rc = copy_to_uspace((void *) ipc_get_arg2(&answer->data),
 			    &dst_base, sizeof(dst_base));
 		}
 
-		IPC_SET_RETVAL(answer->data, rc);
+		ipc_set_retval(&answer->data, rc);
 	}
 
Index: kernel/generic/src/ipc/ops/stchngath.c
===================================================================
--- kernel/generic/src/ipc/ops/stchngath.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/ipc/ops/stchngath.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -46,5 +46,5 @@
 
 	kobject_t *sender_obj = kobject_get(TASK,
-	    (cap_handle_t) IPC_GET_ARG5(call->data), KOBJECT_TYPE_PHONE);
+	    (cap_handle_t) ipc_get_arg5(&call->data), KOBJECT_TYPE_PHONE);
 	if (!sender_obj)
 		return ENOENT;
@@ -62,5 +62,5 @@
 
 	/* Remember the third party task hash. */
-	IPC_SET_ARG5(call->data, (sysarg_t) other_task_s);
+	ipc_set_arg5(&call->data, (sysarg_t) other_task_s);
 
 	kobject_put(sender_obj);
@@ -72,5 +72,5 @@
 	errno_t rc = EOK;
 
-	if (!IPC_GET_RETVAL(answer->data)) {
+	if (!ipc_get_retval(&answer->data)) {
 		/* The recipient authorized the change of state. */
 		task_t *other_task_s;
@@ -78,8 +78,8 @@
 
 		kobject_t *recipient_obj = kobject_get(TASK,
-		    (cap_handle_t) IPC_GET_ARG1(answer->data),
+		    (cap_handle_t) ipc_get_arg1(&answer->data),
 		    KOBJECT_TYPE_PHONE);
 		if (!recipient_obj) {
-			IPC_SET_RETVAL(answer->data, ENOENT);
+			ipc_set_retval(&answer->data, ENOENT);
 			return ENOENT;
 		}
@@ -88,5 +88,5 @@
 		if (recipient_obj->phone->state != IPC_PHONE_CONNECTED) {
 			mutex_unlock(&recipient_obj->phone->lock);
-			IPC_SET_RETVAL(answer->data, EINVAL);
+			ipc_set_retval(&answer->data, EINVAL);
 			kobject_put(recipient_obj);
 			return EINVAL;
@@ -94,5 +94,5 @@
 
 		other_task_r = recipient_obj->phone->callee->task;
-		other_task_s = (task_t *) IPC_GET_ARG5(*olddata);
+		other_task_s = (task_t *) ipc_get_arg5(olddata);
 
 		/*
@@ -101,15 +101,15 @@
 		 */
 		if (other_task_r != other_task_s) {
-			IPC_SET_RETVAL(answer->data, EINVAL);
+			ipc_set_retval(&answer->data, EINVAL);
 			rc = EINVAL;
 		} else {
 			rc = event_task_notify_5(other_task_r,
 			    EVENT_TASK_STATE_CHANGE, false,
-			    IPC_GET_ARG1(*olddata),
-			    IPC_GET_ARG2(*olddata),
-			    IPC_GET_ARG3(*olddata),
+			    ipc_get_arg1(olddata),
+			    ipc_get_arg2(olddata),
+			    ipc_get_arg3(olddata),
 			    LOWER32(olddata->task_id),
 			    UPPER32(olddata->task_id));
-			IPC_SET_RETVAL(answer->data, rc);
+			ipc_set_retval(&answer->data, rc);
 		}
 
Index: kernel/generic/src/ipc/sysipc.c
===================================================================
--- kernel/generic/src/ipc/sysipc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/ipc/sysipc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -131,5 +131,5 @@
 static inline bool answer_need_old(call_t *call)
 {
-	switch (IPC_GET_IMETHOD(call->data)) {
+	switch (ipc_get_imethod(&call->data)) {
 	case IPC_M_CONNECT_TO_ME:
 	case IPC_M_CONNECT_ME_TO:
@@ -192,5 +192,5 @@
 	spinlock_unlock(&answer->forget_lock);
 
-	if ((errno_t) IPC_GET_RETVAL(answer->data) == EHANGUP) {
+	if ((errno_t) ipc_get_retval(&answer->data) == EHANGUP) {
 		phone_t *phone = answer->caller_phone;
 		mutex_lock(&phone->lock);
@@ -223,5 +223,5 @@
 static errno_t request_preprocess(call_t *call, phone_t *phone)
 {
-	call->request_method = IPC_GET_IMETHOD(call->data);
+	call->request_method = ipc_get_imethod(&call->data);
 	return SYSIPC_OP(request_preprocess, call, phone);
 }
@@ -238,7 +238,7 @@
 static void process_answer(call_t *call)
 {
-	if (((errno_t) IPC_GET_RETVAL(call->data) == EHANGUP) &&
+	if (((errno_t) ipc_get_retval(&call->data) == EHANGUP) &&
 	    (call->flags & IPC_CALL_FORWARDED))
-		IPC_SET_RETVAL(call->data, EFORWARD);
+		ipc_set_retval(&call->data, EFORWARD);
 
 	SYSIPC_OP(answer_process, call);
@@ -326,5 +326,5 @@
 		process_answer(call);
 	} else
-		IPC_SET_RETVAL(call->data, rc);
+		ipc_set_retval(&call->data, rc);
 
 	memcpy(data->args, call->data.args, sizeof(data->args));
@@ -385,8 +385,8 @@
 	}
 
-	IPC_SET_IMETHOD(call->data, imethod);
-	IPC_SET_ARG1(call->data, arg1);
-	IPC_SET_ARG2(call->data, arg2);
-	IPC_SET_ARG3(call->data, arg3);
+	ipc_set_imethod(&call->data, imethod);
+	ipc_set_arg1(&call->data, arg1);
+	ipc_set_arg2(&call->data, arg2);
+	ipc_set_arg3(&call->data, arg3);
 
 	/*
@@ -394,5 +394,5 @@
 	 * the limits of the fast version.
 	 */
-	IPC_SET_ARG5(call->data, 0);
+	ipc_set_arg5(&call->data, 0);
 
 	/* Set the user-defined label */
@@ -505,5 +505,5 @@
 	}
 
-	if (!method_is_forwardable(IPC_GET_IMETHOD(call->data))) {
+	if (!method_is_forwardable(ipc_get_imethod(&call->data))) {
 		rc = EPERM;
 		goto error;
@@ -518,20 +518,20 @@
 	 * If the interface and method is immutable, don't change anything.
 	 */
-	if (!method_is_immutable(IPC_GET_IMETHOD(call->data))) {
-		if (method_is_system(IPC_GET_IMETHOD(call->data))) {
-			if (IPC_GET_IMETHOD(call->data) ==
+	if (!method_is_immutable(ipc_get_imethod(&call->data))) {
+		if (method_is_system(ipc_get_imethod(&call->data))) {
+			if (ipc_get_imethod(&call->data) ==
 			    IPC_M_CONNECT_TO_ME) {
 				kobject_put((kobject_t *) call->priv);
 				call->priv = 0;
 				cap_free(TASK,
-				    (cap_handle_t) IPC_GET_ARG5(call->data));
+				    (cap_handle_t) ipc_get_arg5(&call->data));
 			}
 
-			IPC_SET_ARG1(call->data, imethod);
-			IPC_SET_ARG2(call->data, arg1);
-			IPC_SET_ARG3(call->data, arg2);
+			ipc_set_arg1(&call->data, imethod);
+			ipc_set_arg2(&call->data, arg1);
+			ipc_set_arg3(&call->data, arg2);
 
 			if (slow)
-				IPC_SET_ARG4(call->data, arg3);
+				ipc_set_arg4(&call->data, arg3);
 
 			/*
@@ -540,11 +540,11 @@
 			 */
 		} else {
-			IPC_SET_IMETHOD(call->data, imethod);
-			IPC_SET_ARG1(call->data, arg1);
-			IPC_SET_ARG2(call->data, arg2);
+			ipc_set_imethod(&call->data, imethod);
+			ipc_set_arg1(&call->data, arg1);
+			ipc_set_arg2(&call->data, arg2);
 			if (slow) {
-				IPC_SET_ARG3(call->data, arg3);
-				IPC_SET_ARG4(call->data, arg4);
-				IPC_SET_ARG5(call->data, arg5);
+				ipc_set_arg3(&call->data, arg3);
+				ipc_set_arg4(&call->data, arg4);
+				ipc_set_arg5(&call->data, arg5);
 			}
 		}
@@ -563,5 +563,5 @@
 
 error:
-	IPC_SET_RETVAL(call->data, EFORWARD);
+	ipc_set_retval(&call->data, EFORWARD);
 	(void) answer_preprocess(call, need_old ? &old : NULL);
 	if (after_forward)
@@ -632,7 +632,7 @@
 
 	return sys_ipc_forward_common(chandle, phandle,
-	    IPC_GET_IMETHOD(newdata), IPC_GET_ARG1(newdata),
-	    IPC_GET_ARG2(newdata), IPC_GET_ARG3(newdata),
-	    IPC_GET_ARG4(newdata), IPC_GET_ARG5(newdata), mode, true);
+	    ipc_get_imethod(&newdata), ipc_get_arg1(&newdata),
+	    ipc_get_arg2(&newdata), ipc_get_arg3(&newdata),
+	    ipc_get_arg4(&newdata), ipc_get_arg5(&newdata), mode, true);
 }
 
@@ -671,9 +671,9 @@
 		saved = false;
 
-	IPC_SET_RETVAL(call->data, retval);
-	IPC_SET_ARG1(call->data, arg1);
-	IPC_SET_ARG2(call->data, arg2);
-	IPC_SET_ARG3(call->data, arg3);
-	IPC_SET_ARG4(call->data, arg4);
+	ipc_set_retval(&call->data, retval);
+	ipc_set_arg1(&call->data, arg1);
+	ipc_set_arg2(&call->data, arg2);
+	ipc_set_arg3(&call->data, arg3);
+	ipc_set_arg4(&call->data, arg4);
 
 	/*
@@ -681,5 +681,5 @@
 	 * the limits of the fast version.
 	 */
-	IPC_SET_ARG5(call->data, 0);
+	ipc_set_arg5(&call->data, 0);
 	errno_t rc = answer_preprocess(call, saved ? &saved_data : NULL);
 
@@ -841,5 +841,5 @@
 
 error:
-	if (CAP_HANDLE_VALID(handle))
+	if (cap_handle_valid(handle))
 		cap_free(TASK, handle);
 
@@ -858,5 +858,5 @@
 		saved = false;
 
-	IPC_SET_RETVAL(call->data, EPARTY);
+	ipc_set_retval(&call->data, EPARTY);
 	(void) answer_preprocess(call, saved ? &saved_data : NULL);
 	call->flags |= IPC_CALL_AUTO_REPLY;
Index: kernel/generic/src/lib/elf.c
===================================================================
--- kernel/generic/src/lib/elf.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/lib/elf.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -50,14 +50,5 @@
 #include <lib/elf_load.h>
 
-static const char *error_codes[] = {
-	"no error",
-	"invalid image",
-	"address space error",
-	"incompatible image",
-	"unsupported image type",
-	"irrecoverable error"
-};
-
-static int load_segment(elf_segment_header_t *, elf_header_t *, as_t *);
+static errno_t load_segment(elf_segment_header_t *, elf_header_t *, as_t *);
 
 /** ELF loader
@@ -67,8 +58,8 @@
  * @param flags  A combination of ELD_F_*
  *
- * @return EE_OK on success
+ * @return EOK on success
  *
  */
-unsigned int elf_load(elf_header_t *header, as_t *as)
+errno_t elf_load(elf_header_t *header, as_t *as)
 {
 	/* Identify ELF */
@@ -77,5 +68,5 @@
 	    (header->e_ident[EI_MAG2] != ELFMAG2) ||
 	    (header->e_ident[EI_MAG3] != ELFMAG3))
-		return EE_INVALID;
+		return EINVAL;
 
 	/* Identify ELF compatibility */
@@ -85,16 +76,16 @@
 	    (header->e_version != EV_CURRENT) ||
 	    (header->e_ident[EI_CLASS] != ELF_CLASS))
-		return EE_INCOMPATIBLE;
+		return EINVAL;
 
 	if (header->e_phentsize != sizeof(elf_segment_header_t))
-		return EE_INCOMPATIBLE;
+		return EINVAL;
 
 	/* Check if the object type is supported. */
 	if (header->e_type != ET_EXEC)
-		return EE_UNSUPPORTED;
+		return ENOTSUP;
 
 	/* Check if the ELF image starts on a page boundary */
 	if (ALIGN_UP((uintptr_t) header, PAGE_SIZE) != (uintptr_t) header)
-		return EE_UNSUPPORTED;
+		return ENOTSUP;
 
 	/* Walk through all segment headers and process them. */
@@ -108,24 +99,10 @@
 			continue;
 
-		int rc = load_segment(seghdr, header, as);
-		if (rc != EE_OK)
+		errno_t rc = load_segment(seghdr, header, as);
+		if (rc != EOK)
 			return rc;
 	}
 
-	return EE_OK;
-}
-
-/** Print error message according to error code.
- *
- * @param rc Return code returned by elf_load().
- *
- * @return NULL terminated description of error.
- *
- */
-const char *elf_error(unsigned int rc)
-{
-	assert(rc < sizeof(error_codes) / sizeof(char *));
-
-	return error_codes[rc];
+	return EOK;
 }
 
@@ -136,8 +113,8 @@
  * @param as    Address space into wich the ELF is being loaded.
  *
- * @return EE_OK on success, error code otherwise.
+ * @return EOK on success, error code otherwise.
  *
  */
-int load_segment(elf_segment_header_t *entry, elf_header_t *elf, as_t *as)
+errno_t load_segment(elf_segment_header_t *entry, elf_header_t *elf, as_t *as)
 {
 	mem_backend_data_t backend_data;
@@ -146,5 +123,5 @@
 		if ((entry->p_offset % entry->p_align) !=
 		    (entry->p_vaddr % entry->p_align))
-			return EE_INVALID;
+			return EINVAL;
 	}
 
@@ -177,5 +154,5 @@
 	    AS_AREA_ATTR_NONE, &elf_backend, &backend_data, &base, 0);
 	if (!area)
-		return EE_MEMORY;
+		return ENOMEM;
 
 	/*
@@ -184,5 +161,5 @@
 	 */
 
-	return EE_OK;
+	return EOK;
 }
 
Index: kernel/generic/src/lib/ra.c
===================================================================
--- kernel/generic/src/lib/ra.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/lib/ra.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -67,14 +67,14 @@
 
 /** Return the hash of the key */
-static size_t used_key_hash(void *key)
-{
-	uintptr_t *base = (uintptr_t *) key;
+static size_t used_key_hash(const void *key)
+{
+	const uintptr_t *base = key;
 	return hash_mix(*base);
 }
 
 /** Return true if the key is equal to the item's lookup key */
-static bool used_key_equal(void *key, const ht_link_t *item)
-{
-	uintptr_t *base = (uintptr_t *) key;
+static bool used_key_equal(const void *key, const ht_link_t *item)
+{
+	const uintptr_t *base = key;
 	ra_segment_t *seg = hash_table_get_inst(item, ra_segment_t, uh_link);
 	return seg->base == *base;
Index: kernel/generic/src/lib/str.c
===================================================================
--- kernel/generic/src/lib/str.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/lib/str.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,8 @@
 /*
  * Copyright (c) 2001-2004 Jakub Jermar
+ * Copyright (c) 2005 Martin Decky
+ * Copyright (c) 2008 Jiri Svoboda
+ * Copyright (c) 2011 Martin Sucha
+ * Copyright (c) 2011 Oleg Romanenko
  * All rights reserved.
  *
@@ -103,12 +107,14 @@
 
 #include <str.h>
-#include <cpu.h>
-#include <arch/asm.h>
-#include <arch.h>
+
+#include <assert.h>
 #include <errno.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+
 #include <align.h>
-#include <assert.h>
 #include <macros.h>
-#include <stdlib.h>
 
 /** Check the condition if wchar_t is signed */
@@ -616,4 +622,112 @@
 }
 
+/** Convert wide string to string.
+ *
+ * Convert wide string @a src to string. The output is written to the buffer
+ * specified by @a dest and @a size. @a size must be non-zero and the string
+ * written will always be well-formed.
+ *
+ * @param dest	Destination buffer.
+ * @param size	Size of the destination buffer.
+ * @param src	Source wide string.
+ */
+void wstr_to_str(char *dest, size_t size, const wchar_t *src)
+{
+	wchar_t ch;
+	size_t src_idx;
+	size_t dest_off;
+
+	/* There must be space for a null terminator in the buffer. */
+	assert(size > 0);
+
+	src_idx = 0;
+	dest_off = 0;
+
+	while ((ch = src[src_idx++]) != 0) {
+		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
+			break;
+	}
+
+	dest[dest_off] = '\0';
+}
+
+/** Find first occurence of character in string.
+ *
+ * @param str String to search.
+ * @param ch  Character to look for.
+ *
+ * @return Pointer to character in @a str or NULL if not found.
+ */
+char *str_chr(const char *str, wchar_t ch)
+{
+	wchar_t acc;
+	size_t off = 0;
+	size_t last = 0;
+
+	while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) {
+		if (acc == ch)
+			return (char *) (str + last);
+		last = off;
+	}
+
+	return NULL;
+}
+
+/** Insert a wide character into a wide string.
+ *
+ * Insert a wide character into a wide string at position
+ * @a pos. The characters after the position are shifted.
+ *
+ * @param str     String to insert to.
+ * @param ch      Character to insert to.
+ * @param pos     Character index where to insert.
+ * @param max_pos Characters in the buffer.
+ *
+ * @return True if the insertion was sucessful, false if the position
+ *         is out of bounds.
+ *
+ */
+bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos)
+{
+	size_t len = wstr_length(str);
+
+	if ((pos > len) || (pos + 1 > max_pos))
+		return false;
+
+	size_t i;
+	for (i = len; i + 1 > pos; i--)
+		str[i + 1] = str[i];
+
+	str[pos] = ch;
+
+	return true;
+}
+
+/** Remove a wide character from a wide string.
+ *
+ * Remove a wide character from a wide string at position
+ * @a pos. The characters after the position are shifted.
+ *
+ * @param str String to remove from.
+ * @param pos Character index to remove.
+ *
+ * @return True if the removal was sucessful, false if the position
+ *         is out of bounds.
+ *
+ */
+bool wstr_remove(wchar_t *str, size_t pos)
+{
+	size_t len = wstr_length(str);
+
+	if (pos >= len)
+		return false;
+
+	size_t i;
+	for (i = pos + 1; i <= len; i++)
+		str[i - 1] = str[i];
+
+	return true;
+}
+
 /** Duplicate string.
  *
@@ -675,113 +789,4 @@
 	str_ncpy(dest, size + 1, src, size);
 	return dest;
-}
-
-/** Convert wide string to string.
- *
- * Convert wide string @a src to string. The output is written to the buffer
- * specified by @a dest and @a size. @a size must be non-zero and the string
- * written will always be well-formed.
- *
- * @param dest	Destination buffer.
- * @param size	Size of the destination buffer.
- * @param src	Source wide string.
- */
-void wstr_to_str(char *dest, size_t size, const wchar_t *src)
-{
-	wchar_t ch;
-	size_t src_idx;
-	size_t dest_off;
-
-	/* There must be space for a null terminator in the buffer. */
-	assert(size > 0);
-
-	src_idx = 0;
-	dest_off = 0;
-
-	while ((ch = src[src_idx++]) != 0) {
-		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
-			break;
-	}
-
-	dest[dest_off] = '\0';
-}
-
-/** Find first occurence of character in string.
- *
- * @param str String to search.
- * @param ch  Character to look for.
- *
- * @return Pointer to character in @a str or NULL if not found.
- *
- */
-char *str_chr(const char *str, wchar_t ch)
-{
-	wchar_t acc;
-	size_t off = 0;
-	size_t last = 0;
-
-	while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) {
-		if (acc == ch)
-			return (char *) (str + last);
-		last = off;
-	}
-
-	return NULL;
-}
-
-/** Insert a wide character into a wide string.
- *
- * Insert a wide character into a wide string at position
- * @a pos. The characters after the position are shifted.
- *
- * @param str     String to insert to.
- * @param ch      Character to insert to.
- * @param pos     Character index where to insert.
- * @param max_pos Characters in the buffer.
- *
- * @return True if the insertion was sucessful, false if the position
- *         is out of bounds.
- *
- */
-bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos)
-{
-	size_t len = wstr_length(str);
-
-	if ((pos > len) || (pos + 1 > max_pos))
-		return false;
-
-	size_t i;
-	for (i = len; i + 1 > pos; i--)
-		str[i + 1] = str[i];
-
-	str[pos] = ch;
-
-	return true;
-}
-
-/** Remove a wide character from a wide string.
- *
- * Remove a wide character from a wide string at position
- * @a pos. The characters after the position are shifted.
- *
- * @param str String to remove from.
- * @param pos Character index to remove.
- *
- * @return True if the removal was sucessful, false if the position
- *         is out of bounds.
- *
- */
-bool wstr_remove(wchar_t *str, size_t pos)
-{
-	size_t len = wstr_length(str);
-
-	if (pos >= len)
-		return false;
-
-	size_t i;
-	for (i = pos + 1; i <= len; i++)
-		str[i - 1] = str[i];
-
-	return true;
 }
 
Index: kernel/generic/src/main/kinit.c
===================================================================
--- kernel/generic/src/main/kinit.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/main/kinit.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -291,6 +291,6 @@
 			log(LF_OTHER, LVL_ERROR,
 			    "init[%zu]: Init binary load failed "
-			    "(error %s, loader status %u)", i,
-			    str_error_name(rc), programs[i].loader_status);
+			    "(error %s, loader status %s)", i,
+			    str_error_name(rc), str_error_name(programs[i].loader_status));
 		}
 	}
Index: kernel/generic/src/main/main.c
===================================================================
--- kernel/generic/src/main/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/main/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -83,5 +83,4 @@
 #include <ipc/ipc.h>
 #include <macros.h>
-#include <adt/btree.h>
 #include <smp/smp.h>
 #include <ddi/ddi.h>
@@ -161,5 +160,5 @@
  *
  */
-NO_TRACE void main_bsp(void)
+_NO_TRACE void main_bsp(void)
 {
 	config.cpu_count = 1;
@@ -249,5 +248,4 @@
 	ra_init();
 	sysinfo_init();
-	btree_init();
 	as_init();
 	page_init();
Index: kernel/generic/src/mm/as.c
===================================================================
--- kernel/generic/src/mm/as.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/mm/as.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -63,5 +63,4 @@
 #include <synch/mutex.h>
 #include <adt/list.h>
-#include <adt/btree.h>
 #include <proc/task.h>
 #include <proc/thread.h>
@@ -89,8 +88,12 @@
 as_operations_t *as_operations = NULL;
 
-/** Slab for as_t objects.
- *
- */
+/** Cache for as_t objects */
 static slab_cache_t *as_cache;
+
+/** Cache for as_page_mapping_t objects */
+static slab_cache_t *as_page_mapping_cache;
+
+/** Cache for used_space_ival_t objects */
+static slab_cache_t *used_space_ival_cache;
 
 /** ASID subsystem lock.
@@ -116,5 +119,13 @@
 static int as_areas_cmp(void *, void *);
 
-NO_TRACE static errno_t as_constructor(void *obj, unsigned int flags)
+static void used_space_initialize(used_space_t *);
+static void used_space_finalize(used_space_t *);
+static void *used_space_getkey(odlink_t *);
+static int used_space_cmp(void *, void *);
+static used_space_ival_t *used_space_last(used_space_t *);
+static void used_space_remove_ival(used_space_ival_t *);
+static void used_space_shorten_ival(used_space_ival_t *, size_t);
+
+_NO_TRACE static errno_t as_constructor(void *obj, unsigned int flags)
 {
 	as_t *as = (as_t *) obj;
@@ -126,5 +137,5 @@
 }
 
-NO_TRACE static size_t as_destructor(void *obj)
+_NO_TRACE static size_t as_destructor(void *obj)
 {
 	return as_destructor_arch((as_t *) obj);
@@ -138,4 +149,10 @@
 	as_cache = slab_cache_create("as_t", sizeof(as_t), 0,
 	    as_constructor, as_destructor, SLAB_CACHE_MAGDEFERRED);
+
+	as_page_mapping_cache = slab_cache_create("as_page_mapping_t",
+	    sizeof(as_page_mapping_t), 0, NULL, NULL, SLAB_CACHE_MAGDEFERRED);
+
+	used_space_ival_cache = slab_cache_create("used_space_ival_t",
+	    sizeof(used_space_ival_t), 0, NULL, NULL, SLAB_CACHE_MAGDEFERRED);
 
 	AS_KERNEL = as_create(FLAG_AS_KERNEL);
@@ -177,5 +194,5 @@
 }
 
-/** Destroy adress space.
+/** Destroy address space.
  *
  * When there are no tasks referencing this address space (i.e. its refcount is
@@ -264,5 +281,5 @@
  *
  */
-NO_TRACE void as_hold(as_t *as)
+_NO_TRACE void as_hold(as_t *as)
 {
 	refcount_up(&as->refcount);
@@ -277,5 +294,5 @@
  *
  */
-NO_TRACE void as_release(as_t *as)
+_NO_TRACE void as_release(as_t *as)
 {
 	if (refcount_down(&as->refcount))
@@ -323,5 +340,5 @@
  * @return True if the two areas conflict, false otherwise.
  */
-NO_TRACE static bool area_is_conflicting(uintptr_t addr,
+_NO_TRACE static bool area_is_conflicting(uintptr_t addr,
     size_t count, bool guarded, as_area_t *area)
 {
@@ -363,5 +380,5 @@
  *
  */
-NO_TRACE static bool check_area_conflicts(as_t *as, uintptr_t addr,
+_NO_TRACE static bool check_area_conflicts(as_t *as, uintptr_t addr,
     size_t count, bool guarded, as_area_t *avoid)
 {
@@ -457,5 +474,5 @@
  *
  */
-NO_TRACE static uintptr_t as_get_unmapped_area(as_t *as, uintptr_t bound,
+_NO_TRACE static uintptr_t as_get_unmapped_area(as_t *as, uintptr_t bound,
     size_t size, bool guarded)
 {
@@ -524,4 +541,149 @@
 }
 
+/** Get key function for pagemap ordered dictionary.
+ *
+ * The key is the virtual address of the page (as_page_mapping_t.vaddr)
+ *
+ * @param odlink Link to as_pagemap_t.map ordered dictionary
+ * @return Pointer to virtual address cast as @c void *
+ */
+static void *as_pagemap_getkey(odlink_t *odlink)
+{
+	as_page_mapping_t *mapping;
+
+	mapping = odict_get_instance(odlink, as_page_mapping_t, lpagemap);
+	return (void *) &mapping->vaddr;
+}
+
+/** Comparison function for pagemap ordered dictionary.
+ *
+ * @param a Pointer to virtual address cast as @c void *
+ * @param b Pointer to virtual address cast as @c void *
+ * @return <0, =0, >0 if virtual address a is less than, equal to, or
+ *         greater than b, respectively.
+ */
+static int as_pagemap_cmp(void *a, void *b)
+{
+	uintptr_t va = *(uintptr_t *)a;
+	uintptr_t vb = *(uintptr_t *)b;
+
+	if (va < vb)
+		return -1;
+	else if (va == vb)
+		return 0;
+	else
+		return +1;
+}
+
+/** Initialize pagemap.
+ *
+ * @param pagemap Pagemap
+ */
+_NO_TRACE void as_pagemap_initialize(as_pagemap_t *pagemap)
+{
+	odict_initialize(&pagemap->map, as_pagemap_getkey, as_pagemap_cmp);
+}
+
+/** Finalize pagemap.
+ *
+ * Destroy any entries in the pagemap.
+ *
+ * @param pagemap Pagemap
+ */
+_NO_TRACE void as_pagemap_finalize(as_pagemap_t *pagemap)
+{
+	as_page_mapping_t *mapping = as_pagemap_first(pagemap);
+	while (mapping != NULL) {
+		as_pagemap_remove(mapping);
+		mapping = as_pagemap_first(pagemap);
+	}
+	odict_finalize(&pagemap->map);
+}
+
+/** Get first page mapping.
+ *
+ * @param pagemap Pagemap
+ * @return First mapping or @c NULL if there is none
+ */
+_NO_TRACE as_page_mapping_t *as_pagemap_first(as_pagemap_t *pagemap)
+{
+	odlink_t *odlink;
+
+	odlink = odict_first(&pagemap->map);
+	if (odlink == NULL)
+		return NULL;
+
+	return odict_get_instance(odlink, as_page_mapping_t, lpagemap);
+}
+
+/** Get next page mapping.
+ *
+ * @param cur Current mapping
+ * @return Next mapping or @c NULL if @a cur is the last one
+ */
+_NO_TRACE as_page_mapping_t *as_pagemap_next(as_page_mapping_t *cur)
+{
+	odlink_t *odlink;
+
+	odlink = odict_next(&cur->lpagemap, &cur->pagemap->map);
+	if (odlink == NULL)
+		return NULL;
+
+	return odict_get_instance(odlink, as_page_mapping_t, lpagemap);
+}
+
+/** Find frame by virtual address.
+ *
+ * @param pagemap Pagemap
+ * @param vaddr Virtual address of page
+ * @param rframe Place to store physical frame address
+ * @return EOK on succcess or ENOENT if no mapping found
+ */
+_NO_TRACE errno_t as_pagemap_find(as_pagemap_t *pagemap, uintptr_t vaddr,
+    uintptr_t *rframe)
+{
+	odlink_t *odlink;
+	as_page_mapping_t *mapping;
+
+	odlink = odict_find_eq(&pagemap->map, &vaddr, NULL);
+	if (odlink == NULL)
+		return ENOENT;
+
+	mapping = odict_get_instance(odlink, as_page_mapping_t, lpagemap);
+	*rframe = mapping->frame;
+	return EOK;
+}
+
+/** Insert new page mapping.
+ *
+ * This function can block to allocate kernel memory.
+ *
+ * @param pagemap Pagemap
+ * @param vaddr Virtual page address
+ * @param frame Physical frame address
+ */
+_NO_TRACE void as_pagemap_insert(as_pagemap_t *pagemap, uintptr_t vaddr,
+    uintptr_t frame)
+{
+	as_page_mapping_t *mapping;
+
+	mapping = slab_alloc(as_page_mapping_cache, 0);
+	mapping->pagemap = pagemap;
+	odlink_initialize(&mapping->lpagemap);
+	mapping->vaddr = vaddr;
+	mapping->frame = frame;
+	odict_insert(&mapping->lpagemap, &pagemap->map, NULL);
+}
+
+/** Remove page mapping.
+ *
+ * @param mapping Mapping
+ */
+_NO_TRACE void as_pagemap_remove(as_page_mapping_t *mapping)
+{
+	odict_remove(&mapping->lpagemap);
+	slab_free(as_page_mapping_cache, mapping);
+}
+
 /** Remove reference to address space area share info.
  *
@@ -531,5 +693,5 @@
  *
  */
-NO_TRACE static void sh_info_remove_reference(share_info_t *sh_info)
+_NO_TRACE static void sh_info_remove_reference(share_info_t *sh_info)
 {
 	bool dealloc = false;
@@ -541,14 +703,8 @@
 		dealloc = true;
 
-		/*
-		 * Now walk carefully the pagemap B+tree and free/remove
-		 * reference from all frames found there.
-		 */
-		list_foreach(sh_info->pagemap.leaf_list, leaf_link,
-		    btree_node_t, node) {
-			btree_key_t i;
-
-			for (i = 0; i < node->keys; i++)
-				frame_free((uintptr_t) node->value[i], 1);
+		as_page_mapping_t *mapping = as_pagemap_first(&sh_info->pagemap);
+		while (mapping != NULL) {
+			frame_free(mapping->frame, 1);
+			mapping = as_pagemap_next(mapping);
 		}
 
@@ -561,5 +717,5 @@
 			    sh_info->backend_shared_data);
 		}
-		btree_destroy(&sh_info->pagemap);
+		as_pagemap_finalize(&sh_info->pagemap);
 		free(sh_info);
 	}
@@ -636,5 +792,4 @@
 	area->attributes = attrs;
 	area->pages = pages;
-	area->resident = 0;
 	area->base = *base;
 	area->backend = backend;
@@ -665,5 +820,5 @@
 		si->backend_shared_data = NULL;
 		si->backend = backend;
-		btree_create(&si->pagemap);
+		as_pagemap_initialize(&si->pagemap);
 
 		area->sh_info = si;
@@ -689,5 +844,5 @@
 	}
 
-	btree_create(&area->used_space);
+	used_space_initialize(&area->used_space);
 	odict_insert(&area->las_areas, &as->as_areas, NULL);
 
@@ -706,5 +861,5 @@
  *
  */
-NO_TRACE static as_area_t *find_area_and_lock(as_t *as, uintptr_t va)
+_NO_TRACE static as_area_t *find_area_and_lock(as_t *as, uintptr_t va)
 {
 	assert(mutex_locked(&as->lock));
@@ -797,111 +952,96 @@
 
 		/*
+		 * Start TLB shootdown sequence.
+		 */
+
+		ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES,
+		    as->asid, area->base + P2SZ(pages),
+		    area->pages - pages);
+
+		/*
 		 * Remove frames belonging to used space starting from
 		 * the highest addresses downwards until an overlap with
-		 * the resized address space area is found. Note that this
-		 * is also the right way to remove part of the used_space
-		 * B+tree leaf list.
+		 * the resized address space area is found.
 		 */
 		bool cond = true;
 		while (cond) {
-			assert(!list_empty(&area->used_space.leaf_list));
-
-			btree_node_t *node =
-			    list_get_instance(list_last(&area->used_space.leaf_list),
-			    btree_node_t, leaf_link);
-
-			if ((cond = (node->keys != 0))) {
-				uintptr_t ptr = node->key[node->keys - 1];
-				size_t node_size =
-				    (size_t) node->value[node->keys - 1];
-				size_t i = 0;
-
-				if (overlaps(ptr, P2SZ(node_size), area->base,
-				    P2SZ(pages))) {
-
-					if (ptr + P2SZ(node_size) <= start_free) {
-						/*
-						 * The whole interval fits
-						 * completely in the resized
-						 * address space area.
-						 */
-						break;
-					}
-
+			used_space_ival_t *ival =
+			    used_space_last(&area->used_space);
+			assert(ival != NULL);
+
+			uintptr_t ptr = ival->page;
+			size_t pcount = ival->count;
+			size_t i = 0;
+
+			if (overlaps(ptr, P2SZ(pcount), area->base,
+			    P2SZ(pages))) {
+
+				if (ptr + P2SZ(pcount) <= start_free) {
 					/*
-					 * Part of the interval corresponding
-					 * to b and c overlaps with the resized
-					 * address space area.
+					 * The whole interval fits completely
+					 * in the resized address space area.
 					 */
-
-					/* We are almost done */
-					cond = false;
-					i = (start_free - ptr) >> PAGE_WIDTH;
-					if (!used_space_remove(area, start_free,
-					    node_size - i))
-						panic("Cannot remove used space.");
-				} else {
-					/*
-					 * The interval of used space can be
-					 * completely removed.
-					 */
-					if (!used_space_remove(area, ptr, node_size))
-						panic("Cannot remove used space.");
+					break;
 				}
 
 				/*
-				 * Start TLB shootdown sequence.
-				 *
-				 * The sequence is rather short and can be
-				 * repeated multiple times. The reason is that
-				 * we don't want to have used_space_remove()
-				 * inside the sequence as it may use a blocking
-				 * memory allocation for its B+tree. Blocking
-				 * while holding the tlblock spinlock is
-				 * forbidden and would hit a kernel assertion.
+				 * Part of the interval corresponding to b and
+				 * c overlaps with the resized address space
+				 * area.
 				 */
 
-				ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES,
-				    as->asid, area->base + P2SZ(pages),
-				    area->pages - pages);
-
-				for (; i < node_size; i++) {
-					pte_t pte;
-					bool found = page_mapping_find(as,
-					    ptr + P2SZ(i), false, &pte);
-
-					(void) found;
-					assert(found);
-					assert(PTE_VALID(&pte));
-					assert(PTE_PRESENT(&pte));
-
-					if ((area->backend) &&
-					    (area->backend->frame_free)) {
-						area->backend->frame_free(area,
-						    ptr + P2SZ(i),
-						    PTE_GET_FRAME(&pte));
-					}
-
-					page_mapping_remove(as, ptr + P2SZ(i));
+				/* We are almost done */
+				cond = false;
+				i = (start_free - ptr) >> PAGE_WIDTH;
+
+				/* Shorten the interval to @c i pages */
+				used_space_shorten_ival(ival, i);
+			} else {
+				/*
+				 * The interval of used space can be completely
+				 * removed.
+				 */
+				used_space_remove_ival(ival);
+			}
+
+			for (; i < pcount; i++) {
+				pte_t pte;
+				bool found = page_mapping_find(as,
+				    ptr + P2SZ(i), false, &pte);
+
+				(void) found;
+				assert(found);
+				assert(PTE_VALID(&pte));
+				assert(PTE_PRESENT(&pte));
+
+				if ((area->backend) &&
+				    (area->backend->frame_free)) {
+					area->backend->frame_free(area,
+					    ptr + P2SZ(i),
+					    PTE_GET_FRAME(&pte));
 				}
 
-				/*
-				 * Finish TLB shootdown sequence.
-				 */
-
-				tlb_invalidate_pages(as->asid,
-				    area->base + P2SZ(pages),
-				    area->pages - pages);
-
-				/*
-				 * Invalidate software translation caches
-				 * (e.g. TSB on sparc64, PHT on ppc32).
-				 */
-				as_invalidate_translation_cache(as,
-				    area->base + P2SZ(pages),
-				    area->pages - pages);
-				tlb_shootdown_finalize(ipl);
+				page_mapping_remove(as, ptr + P2SZ(i));
 			}
+
 		}
+
+		/*
+		 * Finish TLB shootdown sequence.
+		 */
+
+		tlb_invalidate_pages(as->asid,
+		    area->base + P2SZ(pages),
+		    area->pages - pages);
+
+		/*
+		 * Invalidate software translation caches
+		 * (e.g. TSB on sparc64, PHT on ppc32).
+		 */
+		as_invalidate_translation_cache(as,
+		    area->base + P2SZ(pages),
+		    area->pages - pages);
+		tlb_shootdown_finalize(ipl);
+
 		page_table_unlock(as, false);
 	} else {
@@ -962,5 +1102,4 @@
 
 	page_table_lock(as, false);
-
 	/*
 	 * Start TLB shootdown sequence.
@@ -970,34 +1109,32 @@
 
 	/*
-	 * Visit only the pages mapped by used_space B+tree.
-	 */
-	list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
-	    node) {
-		btree_key_t i;
-
-		for (i = 0; i < node->keys; i++) {
-			uintptr_t ptr = node->key[i];
-			size_t size;
-
-			for (size = 0; size < (size_t) node->value[i]; size++) {
-				pte_t pte;
-				bool found = page_mapping_find(as,
-				    ptr + P2SZ(size), false, &pte);
-
-				(void) found;
-				assert(found);
-				assert(PTE_VALID(&pte));
-				assert(PTE_PRESENT(&pte));
-
-				if ((area->backend) &&
-				    (area->backend->frame_free)) {
-					area->backend->frame_free(area,
-					    ptr + P2SZ(size),
-					    PTE_GET_FRAME(&pte));
-				}
-
-				page_mapping_remove(as, ptr + P2SZ(size));
+	 * Visit only the pages mapped by used_space.
+	 */
+	used_space_ival_t *ival = used_space_first(&area->used_space);
+	while (ival != NULL) {
+		uintptr_t ptr = ival->page;
+
+		for (size_t size = 0; size < ival->count; size++) {
+			pte_t pte;
+			bool found = page_mapping_find(as,
+			    ptr + P2SZ(size), false, &pte);
+
+			(void) found;
+			assert(found);
+			assert(PTE_VALID(&pte));
+			assert(PTE_PRESENT(&pte));
+
+			if ((area->backend) &&
+			    (area->backend->frame_free)) {
+				area->backend->frame_free(area,
+				    ptr + P2SZ(size),
+				    PTE_GET_FRAME(&pte));
 			}
+
+			page_mapping_remove(as, ptr + P2SZ(size));
 		}
+
+		used_space_remove_ival(ival);
+		ival = used_space_first(&area->used_space);
 	}
 
@@ -1017,8 +1154,6 @@
 	page_table_unlock(as, false);
 
-	btree_destroy(&area->used_space);
-
+	used_space_finalize(&area->used_space);
 	area->attributes |= AS_AREA_ATTR_PARTIAL;
-
 	sh_info_remove_reference(area->sh_info);
 
@@ -1170,5 +1305,5 @@
  *
  */
-NO_TRACE bool as_area_check_access(as_area_t *area, pf_access_t access)
+_NO_TRACE bool as_area_check_access(as_area_t *area, pf_access_t access)
 {
 	assert(mutex_locked(&area->lock));
@@ -1193,5 +1328,5 @@
  *
  */
-NO_TRACE static unsigned int area_flags_to_page_flags(unsigned int aflags)
+_NO_TRACE static unsigned int area_flags_to_page_flags(unsigned int aflags)
 {
 	unsigned int flags = PAGE_USER | PAGE_PRESENT;
@@ -1212,5 +1347,5 @@
 }
 
-/** Change adress space area flags.
+/** Change address space area flags.
  *
  * The idea is to have the same data, but with a different access mode.
@@ -1256,19 +1391,7 @@
 	mutex_unlock(&area->sh_info->lock);
 
-	/*
-	 * Compute total number of used pages in the used_space B+tree
-	 */
-	size_t used_pages = 0;
-
-	list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
-	    node) {
-		btree_key_t i;
-
-		for (i = 0; i < node->keys; i++)
-			used_pages += (size_t) node->value[i];
-	}
-
 	/* An array for storing frame numbers */
-	uintptr_t *old_frame = malloc(used_pages * sizeof(uintptr_t));
+	uintptr_t *old_frame = malloc(area->used_space.pages *
+	    sizeof(uintptr_t));
 	if (!old_frame) {
 		mutex_unlock(&area->lock);
@@ -1291,28 +1414,26 @@
 	size_t frame_idx = 0;
 
-	list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
-	    node) {
-		btree_key_t i;
-
-		for (i = 0; i < node->keys; i++) {
-			uintptr_t ptr = node->key[i];
-			size_t size;
-
-			for (size = 0; size < (size_t) node->value[i]; size++) {
-				pte_t pte;
-				bool found = page_mapping_find(as,
-				    ptr + P2SZ(size), false, &pte);
-
-				(void) found;
-				assert(found);
-				assert(PTE_VALID(&pte));
-				assert(PTE_PRESENT(&pte));
-
-				old_frame[frame_idx++] = PTE_GET_FRAME(&pte);
-
-				/* Remove old mapping */
-				page_mapping_remove(as, ptr + P2SZ(size));
-			}
+	used_space_ival_t *ival = used_space_first(&area->used_space);
+	while (ival != NULL) {
+		uintptr_t ptr = ival->page;
+		size_t size;
+
+		for (size = 0; size < ival->count; size++) {
+			pte_t pte;
+			bool found = page_mapping_find(as, ptr + P2SZ(size),
+			    false, &pte);
+
+			(void) found;
+			assert(found);
+			assert(PTE_VALID(&pte));
+			assert(PTE_PRESENT(&pte));
+
+			old_frame[frame_idx++] = PTE_GET_FRAME(&pte);
+
+			/* Remove old mapping */
+			page_mapping_remove(as, ptr + P2SZ(size));
 		}
+
+		ival = used_space_next(ival);
 	}
 
@@ -1344,22 +1465,20 @@
 	frame_idx = 0;
 
-	list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
-	    node) {
-		btree_key_t i;
-
-		for (i = 0; i < node->keys; i++) {
-			uintptr_t ptr = node->key[i];
-			size_t size;
-
-			for (size = 0; size < (size_t) node->value[i]; size++) {
-				page_table_lock(as, false);
-
-				/* Insert the new mapping */
-				page_mapping_insert(as, ptr + P2SZ(size),
-				    old_frame[frame_idx++], page_flags);
-
-				page_table_unlock(as, false);
-			}
+	ival = used_space_first(&area->used_space);
+	while (ival != NULL) {
+		uintptr_t ptr = ival->page;
+		size_t size;
+
+		for (size = 0; size < ival->count; size++) {
+			page_table_lock(as, false);
+
+			/* Insert the new mapping */
+			page_mapping_insert(as, ptr + P2SZ(size),
+			    old_frame[frame_idx++], page_flags);
+
+			page_table_unlock(as, false);
 		}
+
+		ival = used_space_next(ival);
 	}
 
@@ -1579,5 +1698,5 @@
  *
  */
-NO_TRACE unsigned int as_area_get_flags(as_area_t *area)
+_NO_TRACE unsigned int as_area_get_flags(as_area_t *area)
 {
 	assert(mutex_locked(&area->lock));
@@ -1627,5 +1746,5 @@
  *
  */
-NO_TRACE pte_t *page_table_create(unsigned int flags)
+_NO_TRACE pte_t *page_table_create(unsigned int flags)
 {
 	assert(as_operations);
@@ -1642,5 +1761,5 @@
  *
  */
-NO_TRACE void page_table_destroy(pte_t *page_table)
+_NO_TRACE void page_table_destroy(pte_t *page_table)
 {
 	assert(as_operations);
@@ -1663,5 +1782,5 @@
  *
  */
-NO_TRACE void page_table_lock(as_t *as, bool lock)
+_NO_TRACE void page_table_lock(as_t *as, bool lock)
 {
 	assert(as_operations);
@@ -1677,5 +1796,5 @@
  *
  */
-NO_TRACE void page_table_unlock(as_t *as, bool unlock)
+_NO_TRACE void page_table_unlock(as_t *as, bool unlock)
 {
 	assert(as_operations);
@@ -1692,5 +1811,5 @@
  *         are locked, otherwise false.
  */
-NO_TRACE bool page_table_locked(as_t *as)
+_NO_TRACE bool page_table_locked(as_t *as)
 {
 	assert(as_operations);
@@ -1725,10 +1844,180 @@
 }
 
+/** Initialize used space map.
+ *
+ * @param used_space Used space map
+ */
+static void used_space_initialize(used_space_t *used_space)
+{
+	odict_initialize(&used_space->ivals, used_space_getkey, used_space_cmp);
+	used_space->pages = 0;
+}
+
+/** Finalize used space map.
+ *
+ * @param used_space Used space map
+ */
+static void used_space_finalize(used_space_t *used_space)
+{
+	assert(odict_empty(&used_space->ivals));
+	odict_finalize(&used_space->ivals);
+}
+
+/** Get first interval of used space.
+ *
+ * @param used_space Used space map
+ * @return First interval or @c NULL if there are none
+ */
+used_space_ival_t *used_space_first(used_space_t *used_space)
+{
+	odlink_t *odlink = odict_first(&used_space->ivals);
+
+	if (odlink == NULL)
+		return NULL;
+
+	return odict_get_instance(odlink, used_space_ival_t, lused_space);
+}
+
+/** Get next interval of used space.
+ *
+ * @param cur Current interval
+ * @return Next interval or @c NULL if there are none
+ */
+used_space_ival_t *used_space_next(used_space_ival_t *cur)
+{
+	odlink_t *odlink = odict_next(&cur->lused_space,
+	    &cur->used_space->ivals);
+
+	if (odlink == NULL)
+		return NULL;
+
+	return odict_get_instance(odlink, used_space_ival_t, lused_space);
+}
+
+/** Get last interval of used space.
+ *
+ * @param used_space Used space map
+ * @return First interval or @c NULL if there are none
+ */
+static used_space_ival_t *used_space_last(used_space_t *used_space)
+{
+	odlink_t *odlink = odict_last(&used_space->ivals);
+
+	if (odlink == NULL)
+		return NULL;
+
+	return odict_get_instance(odlink, used_space_ival_t, lused_space);
+}
+
+/** Find the first interval that contains addresses greater than or equal to
+ * @a ptr.
+ *
+ * @param used_space Used space map
+ * @param ptr Virtual address
+ *
+ * @return Used space interval or @c NULL if none matches
+ */
+used_space_ival_t *used_space_find_gteq(used_space_t *used_space, uintptr_t ptr)
+{
+	odlink_t *odlink;
+	used_space_ival_t *ival;
+
+	/* Find last interval to start at address less than @a ptr */
+	odlink = odict_find_lt(&used_space->ivals, &ptr, NULL);
+	if (odlink != NULL) {
+		ival = odict_get_instance(odlink, used_space_ival_t,
+		    lused_space);
+
+		/* If the interval extends above @a ptr, return it */
+		if (ival->page + P2SZ(ival->count) > ptr)
+			return ival;
+
+		/*
+		 * Otherwise, if a next interval exists, it must match
+		 * the criteria.
+		 */
+		odlink = odict_next(&ival->lused_space, &used_space->ivals);
+	} else {
+		/*
+		 * No interval with lower base address, so if there is any
+		 * interval at all, it must match the criteria
+		 */
+		odlink = odict_first(&used_space->ivals);
+	}
+
+	if (odlink != NULL) {
+		ival = odict_get_instance(odlink, used_space_ival_t,
+		    lused_space);
+		return ival;
+	}
+
+	return NULL;
+}
+
+/** Get key function for used space ordered dictionary.
+ *
+ * The key is the virtual address of the first page
+ *
+ * @param odlink Ordered dictionary link (used_space_ival_t.lused_space)
+ * @return Pointer to virtual address of first page cast as @c void *.
+ */
+static void *used_space_getkey(odlink_t *odlink)
+{
+	used_space_ival_t *ival = odict_get_instance(odlink, used_space_ival_t,
+	    lused_space);
+	return (void *) &ival->page;
+}
+
+/** Compare function for used space ordered dictionary.
+ *
+ * @param a Pointer to virtual address of first page cast as @c void *
+ * @param b Pointer to virtual address of first page cast as @c void *
+ * @return Less than zero, zero, greater than zero if virtual address @a a
+ *         is less than, equal to, greater than virtual address b, respectively.
+ */
+static int used_space_cmp(void *a, void *b)
+{
+	uintptr_t va = *(uintptr_t *) a;
+	uintptr_t vb = *(uintptr_t *) b;
+
+	if (va < vb)
+		return -1;
+	else if (va == vb)
+		return 0;
+	else
+		return +1;
+}
+
+/** Remove used space interval.
+ *
+ * @param ival Used space interval
+ */
+static void used_space_remove_ival(used_space_ival_t *ival)
+{
+	ival->used_space->pages -= ival->count;
+	odict_remove(&ival->lused_space);
+	slab_free(used_space_ival_cache, ival);
+}
+
+/** Shorten used space interval.
+ *
+ * @param ival Used space interval
+ * @param count New number of pages in the interval
+ */
+static void used_space_shorten_ival(used_space_ival_t *ival, size_t count)
+{
+	assert(count > 0);
+	assert(count < ival->count);
+
+	ival->used_space->pages -= ival->count - count;
+	ival->count = count;
+}
+
 /** Mark portion of address space area as used.
  *
  * The address space area must be already locked.
  *
- * @param area  Address space area.
- * @param page  First page to be marked.
+ * @param used_space Used space map
+ * @param page First page to be marked.
  * @param count Number of page to be marked.
  *
@@ -1736,459 +2025,63 @@
  *
  */
-bool used_space_insert(as_area_t *area, uintptr_t page, size_t count)
-{
-	assert(mutex_locked(&area->lock));
+bool used_space_insert(used_space_t *used_space, uintptr_t page, size_t count)
+{
+	used_space_ival_t *a;
+	used_space_ival_t *b;
+	bool adj_a;
+	bool adj_b;
+	odlink_t *odlink;
+	used_space_ival_t *ival;
+
 	assert(IS_ALIGNED(page, PAGE_SIZE));
 	assert(count);
 
-	btree_node_t *leaf = NULL;
-	size_t pages = (size_t) btree_search(&area->used_space, page, &leaf);
-	if (pages) {
-		/*
-		 * We hit the beginning of some used space.
-		 */
+	/* Interval to the left */
+	odlink = odict_find_lt(&used_space->ivals, &page, NULL);
+	a = (odlink != NULL) ?
+	    odict_get_instance(odlink, used_space_ival_t, lused_space) :
+	    NULL;
+
+	/* Interval to the right */
+	b = (a != NULL) ? used_space_next(a) :
+	    used_space_first(used_space);
+
+	/* Check for conflict with left interval */
+	if (a != NULL && overlaps(a->page, P2SZ(a->count), page, P2SZ(count)))
 		return false;
-	}
-
-	assert(leaf != NULL);
-
-	if (!leaf->keys) {
-		btree_insert(&area->used_space, page, (void *) count, leaf);
-		goto success;
-	}
-
-	btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space, leaf);
-	if (node) {
-		uintptr_t left_pg = node->key[node->keys - 1];
-		uintptr_t right_pg = leaf->key[0];
-		size_t left_cnt = (size_t) node->value[node->keys - 1];
-		size_t right_cnt = (size_t) leaf->value[0];
-
-		/*
-		 * Examine the possibility that the interval fits
-		 * somewhere between the rightmost interval of
-		 * the left neigbour and the first interval of the leaf.
-		 */
-
-		if (page >= right_pg) {
-			/* Do nothing. */
-		} else if (overlaps(page, P2SZ(count), left_pg,
-		    P2SZ(left_cnt))) {
-			/* The interval intersects with the left interval. */
-			return false;
-		} else if (overlaps(page, P2SZ(count), right_pg,
-		    P2SZ(right_cnt))) {
-			/* The interval intersects with the right interval. */
-			return false;
-		} else if ((page == left_pg + P2SZ(left_cnt)) &&
-		    (page + P2SZ(count) == right_pg)) {
-			/*
-			 * The interval can be added by merging the two already
-			 * present intervals.
-			 */
-			node->value[node->keys - 1] += count + right_cnt;
-			btree_remove(&area->used_space, right_pg, leaf);
-			goto success;
-		} else if (page == left_pg + P2SZ(left_cnt)) {
-			/*
-			 * The interval can be added by simply growing the left
-			 * interval.
-			 */
-			node->value[node->keys - 1] += count;
-			goto success;
-		} else if (page + P2SZ(count) == right_pg) {
-			/*
-			 * The interval can be addded by simply moving base of
-			 * the right interval down and increasing its size
-			 * accordingly.
-			 */
-			leaf->value[0] += count;
-			leaf->key[0] = page;
-			goto success;
-		} else {
-			/*
-			 * The interval is between both neigbouring intervals,
-			 * but cannot be merged with any of them.
-			 */
-			btree_insert(&area->used_space, page, (void *) count,
-			    leaf);
-			goto success;
-		}
-	} else if (page < leaf->key[0]) {
-		uintptr_t right_pg = leaf->key[0];
-		size_t right_cnt = (size_t) leaf->value[0];
-
-		/*
-		 * Investigate the border case in which the left neighbour does
-		 * not exist but the interval fits from the left.
-		 */
-
-		if (overlaps(page, P2SZ(count), right_pg, P2SZ(right_cnt))) {
-			/* The interval intersects with the right interval. */
-			return false;
-		} else if (page + P2SZ(count) == right_pg) {
-			/*
-			 * The interval can be added by moving the base of the
-			 * right interval down and increasing its size
-			 * accordingly.
-			 */
-			leaf->key[0] = page;
-			leaf->value[0] += count;
-			goto success;
-		} else {
-			/*
-			 * The interval doesn't adjoin with the right interval.
-			 * It must be added individually.
-			 */
-			btree_insert(&area->used_space, page, (void *) count,
-			    leaf);
-			goto success;
-		}
-	}
-
-	node = btree_leaf_node_right_neighbour(&area->used_space, leaf);
-	if (node) {
-		uintptr_t left_pg = leaf->key[leaf->keys - 1];
-		uintptr_t right_pg = node->key[0];
-		size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
-		size_t right_cnt = (size_t) node->value[0];
-
-		/*
-		 * Examine the possibility that the interval fits
-		 * somewhere between the leftmost interval of
-		 * the right neigbour and the last interval of the leaf.
-		 */
-
-		if (page < left_pg) {
-			/* Do nothing. */
-		} else if (overlaps(page, P2SZ(count), left_pg,
-		    P2SZ(left_cnt))) {
-			/* The interval intersects with the left interval. */
-			return false;
-		} else if (overlaps(page, P2SZ(count), right_pg,
-		    P2SZ(right_cnt))) {
-			/* The interval intersects with the right interval. */
-			return false;
-		} else if ((page == left_pg + P2SZ(left_cnt)) &&
-		    (page + P2SZ(count) == right_pg)) {
-			/*
-			 * The interval can be added by merging the two already
-			 * present intervals.
-			 */
-			leaf->value[leaf->keys - 1] += count + right_cnt;
-			btree_remove(&area->used_space, right_pg, node);
-			goto success;
-		} else if (page == left_pg + P2SZ(left_cnt)) {
-			/*
-			 * The interval can be added by simply growing the left
-			 * interval.
-			 */
-			leaf->value[leaf->keys - 1] += count;
-			goto success;
-		} else if (page + P2SZ(count) == right_pg) {
-			/*
-			 * The interval can be addded by simply moving base of
-			 * the right interval down and increasing its size
-			 * accordingly.
-			 */
-			node->value[0] += count;
-			node->key[0] = page;
-			goto success;
-		} else {
-			/*
-			 * The interval is between both neigbouring intervals,
-			 * but cannot be merged with any of them.
-			 */
-			btree_insert(&area->used_space, page, (void *) count,
-			    leaf);
-			goto success;
-		}
-	} else if (page >= leaf->key[leaf->keys - 1]) {
-		uintptr_t left_pg = leaf->key[leaf->keys - 1];
-		size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
-
-		/*
-		 * Investigate the border case in which the right neighbour
-		 * does not exist but the interval fits from the right.
-		 */
-
-		if (overlaps(page, P2SZ(count), left_pg, P2SZ(left_cnt))) {
-			/* The interval intersects with the left interval. */
-			return false;
-		} else if (left_pg + P2SZ(left_cnt) == page) {
-			/*
-			 * The interval can be added by growing the left
-			 * interval.
-			 */
-			leaf->value[leaf->keys - 1] += count;
-			goto success;
-		} else {
-			/*
-			 * The interval doesn't adjoin with the left interval.
-			 * It must be added individually.
-			 */
-			btree_insert(&area->used_space, page, (void *) count,
-			    leaf);
-			goto success;
-		}
-	}
-
-	/*
-	 * Note that if the algorithm made it thus far, the interval can fit
-	 * only between two other intervals of the leaf. The two border cases
-	 * were already resolved.
-	 */
-	btree_key_t i;
-	for (i = 1; i < leaf->keys; i++) {
-		if (page < leaf->key[i]) {
-			uintptr_t left_pg = leaf->key[i - 1];
-			uintptr_t right_pg = leaf->key[i];
-			size_t left_cnt = (size_t) leaf->value[i - 1];
-			size_t right_cnt = (size_t) leaf->value[i];
-
-			/*
-			 * The interval fits between left_pg and right_pg.
-			 */
-
-			if (overlaps(page, P2SZ(count), left_pg,
-			    P2SZ(left_cnt))) {
-				/*
-				 * The interval intersects with the left
-				 * interval.
-				 */
-				return false;
-			} else if (overlaps(page, P2SZ(count), right_pg,
-			    P2SZ(right_cnt))) {
-				/*
-				 * The interval intersects with the right
-				 * interval.
-				 */
-				return false;
-			} else if ((page == left_pg + P2SZ(left_cnt)) &&
-			    (page + P2SZ(count) == right_pg)) {
-				/*
-				 * The interval can be added by merging the two
-				 * already present intervals.
-				 */
-				leaf->value[i - 1] += count + right_cnt;
-				btree_remove(&area->used_space, right_pg, leaf);
-				goto success;
-			} else if (page == left_pg + P2SZ(left_cnt)) {
-				/*
-				 * The interval can be added by simply growing
-				 * the left interval.
-				 */
-				leaf->value[i - 1] += count;
-				goto success;
-			} else if (page + P2SZ(count) == right_pg) {
-				/*
-				 * The interval can be addded by simply moving
-				 * base of the right interval down and
-				 * increasing its size accordingly.
-				 */
-				leaf->value[i] += count;
-				leaf->key[i] = page;
-				goto success;
-			} else {
-				/*
-				 * The interval is between both neigbouring
-				 * intervals, but cannot be merged with any of
-				 * them.
-				 */
-				btree_insert(&area->used_space, page,
-				    (void *) count, leaf);
-				goto success;
-			}
-		}
-	}
-
-	panic("Inconsistency detected while adding %zu pages of used "
-	    "space at %p.", count, (void *) page);
-
-success:
-	area->resident += count;
-	return true;
-}
-
-/** Mark portion of address space area as unused.
- *
- * The address space area must be already locked.
- *
- * @param area  Address space area.
- * @param page  First page to be marked.
- * @param count Number of page to be marked.
- *
- * @return False on failure or true on success.
- *
- */
-bool used_space_remove(as_area_t *area, uintptr_t page, size_t count)
-{
-	assert(mutex_locked(&area->lock));
-	assert(IS_ALIGNED(page, PAGE_SIZE));
-	assert(count);
-
-	btree_node_t *leaf;
-	size_t pages = (size_t) btree_search(&area->used_space, page, &leaf);
-	if (pages) {
-		/*
-		 * We are lucky, page is the beginning of some interval.
-		 */
-		if (count > pages) {
-			return false;
-		} else if (count == pages) {
-			btree_remove(&area->used_space, page, leaf);
-			goto success;
-		} else {
-			/*
-			 * Find the respective interval.
-			 * Decrease its size and relocate its start address.
-			 */
-			btree_key_t i;
-			for (i = 0; i < leaf->keys; i++) {
-				if (leaf->key[i] == page) {
-					leaf->key[i] += P2SZ(count);
-					leaf->value[i] -= count;
-					goto success;
-				}
-			}
-
-			goto error;
-		}
-	}
-
-	btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space,
-	    leaf);
-	if ((node) && (page < leaf->key[0])) {
-		uintptr_t left_pg = node->key[node->keys - 1];
-		size_t left_cnt = (size_t) node->value[node->keys - 1];
-
-		if (overlaps(left_pg, P2SZ(left_cnt), page, P2SZ(count))) {
-			if (page + P2SZ(count) == left_pg + P2SZ(left_cnt)) {
-				/*
-				 * The interval is contained in the rightmost
-				 * interval of the left neighbour and can be
-				 * removed by updating the size of the bigger
-				 * interval.
-				 */
-				node->value[node->keys - 1] -= count;
-				goto success;
-			} else if (page + P2SZ(count) <
-			    left_pg + P2SZ(left_cnt)) {
-				size_t new_cnt;
-
-				/*
-				 * The interval is contained in the rightmost
-				 * interval of the left neighbour but its
-				 * removal requires both updating the size of
-				 * the original interval and also inserting a
-				 * new interval.
-				 */
-				new_cnt = ((left_pg + P2SZ(left_cnt)) -
-				    (page + P2SZ(count))) >> PAGE_WIDTH;
-				node->value[node->keys - 1] -= count + new_cnt;
-				btree_insert(&area->used_space, page +
-				    P2SZ(count), (void *) new_cnt, leaf);
-				goto success;
-			}
-		}
-
+
+	/* Check for conflict with right interval */
+	if (b != NULL && overlaps(page, P2SZ(count), b->page, P2SZ(b->count)))
 		return false;
-	} else if (page < leaf->key[0])
-		return false;
-
-	if (page > leaf->key[leaf->keys - 1]) {
-		uintptr_t left_pg = leaf->key[leaf->keys - 1];
-		size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
-
-		if (overlaps(left_pg, P2SZ(left_cnt), page, P2SZ(count))) {
-			if (page + P2SZ(count) == left_pg + P2SZ(left_cnt)) {
-				/*
-				 * The interval is contained in the rightmost
-				 * interval of the leaf and can be removed by
-				 * updating the size of the bigger interval.
-				 */
-				leaf->value[leaf->keys - 1] -= count;
-				goto success;
-			} else if (page + P2SZ(count) < left_pg +
-			    P2SZ(left_cnt)) {
-				size_t new_cnt;
-
-				/*
-				 * The interval is contained in the rightmost
-				 * interval of the leaf but its removal
-				 * requires both updating the size of the
-				 * original interval and also inserting a new
-				 * interval.
-				 */
-				new_cnt = ((left_pg + P2SZ(left_cnt)) -
-				    (page + P2SZ(count))) >> PAGE_WIDTH;
-				leaf->value[leaf->keys - 1] -= count + new_cnt;
-				btree_insert(&area->used_space, page +
-				    P2SZ(count), (void *) new_cnt, leaf);
-				goto success;
-			}
-		}
-
-		return false;
-	}
-
-	/*
-	 * The border cases have been already resolved.
-	 * Now the interval can be only between intervals of the leaf.
-	 */
-	btree_key_t i;
-	for (i = 1; i < leaf->keys - 1; i++) {
-		if (page < leaf->key[i]) {
-			uintptr_t left_pg = leaf->key[i - 1];
-			size_t left_cnt = (size_t) leaf->value[i - 1];
-
-			/*
-			 * Now the interval is between intervals corresponding
-			 * to (i - 1) and i.
-			 */
-			if (overlaps(left_pg, P2SZ(left_cnt), page,
-			    P2SZ(count))) {
-				if (page + P2SZ(count) ==
-				    left_pg + P2SZ(left_cnt)) {
-					/*
-					 * The interval is contained in the
-					 * interval (i - 1) of the leaf and can
-					 * be removed by updating the size of
-					 * the bigger interval.
-					 */
-					leaf->value[i - 1] -= count;
-					goto success;
-				} else if (page + P2SZ(count) <
-				    left_pg + P2SZ(left_cnt)) {
-					size_t new_cnt;
-
-					/*
-					 * The interval is contained in the
-					 * interval (i - 1) of the leaf but its
-					 * removal requires both updating the
-					 * size of the original interval and
-					 * also inserting a new interval.
-					 */
-					new_cnt = ((left_pg + P2SZ(left_cnt)) -
-					    (page + P2SZ(count))) >>
-					    PAGE_WIDTH;
-					leaf->value[i - 1] -= count + new_cnt;
-					btree_insert(&area->used_space, page +
-					    P2SZ(count), (void *) new_cnt,
-					    leaf);
-					goto success;
-				}
-			}
-
-			return false;
-		}
-	}
-
-error:
-	panic("Inconsistency detected while removing %zu pages of used "
-	    "space from %p.", count, (void *) page);
-
-success:
-	area->resident -= count;
+
+	/* Check if A is adjacent to the new interval */
+	adj_a = (a != NULL) && (a->page + P2SZ(a->count) == page);
+	/* Check if the new interval is adjacent to B*/
+	adj_b = (b != NULL) && page + P2SZ(count) == b->page;
+
+	if (adj_a && adj_b) {
+		/* Fuse into a single interval */
+		a->count += count + b->count;
+		used_space_remove_ival(b);
+	} else if (adj_a) {
+		/* Append to A */
+		a->count += count;
+	} else if (adj_b) {
+		/* Prepend to B */
+		b->page = page;
+		b->count += count;
+	} else {
+		/* Create new interval */
+		ival = slab_alloc(used_space_ival_cache, 0);
+		ival->used_space = used_space;
+		odlink_initialize(&ival->lused_space);
+		ival->page = page;
+		ival->count = count;
+
+		odict_insert(&ival->lused_space, &used_space->ivals,
+		    NULL);
+	}
+
+	used_space->pages += count;
 	return true;
 }
@@ -2257,5 +2150,5 @@
 }
 
-/** Get list of adress space areas.
+/** Get list of address space areas.
  *
  * @param as    Address space.
Index: kernel/generic/src/mm/backend_anon.c
===================================================================
--- kernel/generic/src/mm/backend_anon.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/mm/backend_anon.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -48,5 +48,4 @@
 #include <synch/mutex.h>
 #include <adt/list.h>
-#include <adt/btree.h>
 #include <errno.h>
 #include <typedefs.h>
@@ -122,36 +121,32 @@
 	 */
 	mutex_lock(&area->sh_info->lock);
-	list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
-	    node) {
-		unsigned int i;
-
-		for (i = 0; i < node->keys; i++) {
-			uintptr_t base = node->key[i];
-			size_t count = (size_t) node->value[i];
-			unsigned int j;
-
-			for (j = 0; j < count; j++) {
-				pte_t pte;
-				bool found;
-
-				page_table_lock(area->as, false);
-				found = page_mapping_find(area->as,
-				    base + P2SZ(j), false, &pte);
-
-				(void)found;
-				assert(found);
-				assert(PTE_VALID(&pte));
-				assert(PTE_PRESENT(&pte));
-
-				btree_insert(&area->sh_info->pagemap,
-				    (base + P2SZ(j)) - area->base,
-				    (void *) PTE_GET_FRAME(&pte), NULL);
-				page_table_unlock(area->as, false);
-
-				pfn_t pfn = ADDR2PFN(PTE_GET_FRAME(&pte));
-				frame_reference_add(pfn);
-			}
-
+	used_space_ival_t *ival = used_space_first(&area->used_space);
+	while (ival != NULL) {
+		uintptr_t base = ival->page;
+		size_t count = ival->count;
+		unsigned int j;
+
+		for (j = 0; j < count; j++) {
+			pte_t pte;
+			bool found;
+
+			page_table_lock(area->as, false);
+			found = page_mapping_find(area->as, base + P2SZ(j),
+			    false, &pte);
+
+			(void)found;
+			assert(found);
+			assert(PTE_VALID(&pte));
+			assert(PTE_PRESENT(&pte));
+
+			as_pagemap_insert(&area->sh_info->pagemap,
+			    (base + P2SZ(j)) - area->base, PTE_GET_FRAME(&pte));
+			page_table_unlock(area->as, false);
+
+			pfn_t pfn = ADDR2PFN(PTE_GET_FRAME(&pte));
+			frame_reference_add(pfn);
 		}
+
+		ival = used_space_next(ival);
 	}
 	mutex_unlock(&area->sh_info->lock);
@@ -201,6 +196,4 @@
 	mutex_lock(&area->sh_info->lock);
 	if (area->sh_info->shared) {
-		btree_node_t *leaf;
-
 		/*
 		 * The area is shared, chances are that the mapping can be found
@@ -210,33 +203,19 @@
 		 * mapping, a new frame is allocated and the mapping is created.
 		 */
-		frame = (uintptr_t) btree_search(&area->sh_info->pagemap,
-		    upage - area->base, &leaf);
-		if (!frame) {
-			bool allocate = true;
-			unsigned int i;
+		errno_t rc = as_pagemap_find(&area->sh_info->pagemap,
+		    upage - area->base, &frame);
+		if (rc != EOK) {
+			/* Need to allocate the frame */
+			kpage = km_temporary_page_get(&frame,
+			    FRAME_NO_RESERVE);
+			memsetb((void *) kpage, PAGE_SIZE, 0);
+			km_temporary_page_put(kpage);
 
 			/*
-			 * Zero can be returned as a valid frame address.
-			 * Just a small workaround.
+			 * Insert the address of the newly allocated
+			 * frame to the pagemap.
 			 */
-			for (i = 0; i < leaf->keys; i++) {
-				if (leaf->key[i] == upage - area->base) {
-					allocate = false;
-					break;
-				}
-			}
-			if (allocate) {
-				kpage = km_temporary_page_get(&frame,
-				    FRAME_NO_RESERVE);
-				memsetb((void *) kpage, PAGE_SIZE, 0);
-				km_temporary_page_put(kpage);
-
-				/*
-				 * Insert the address of the newly allocated
-				 * frame to the pagemap.
-				 */
-				btree_insert(&area->sh_info->pagemap,
-				    upage - area->base, (void *) frame, leaf);
-			}
+			as_pagemap_insert(&area->sh_info->pagemap,
+			    upage - area->base, frame);
 		}
 		frame_reference_add(ADDR2PFN(frame));
@@ -280,5 +259,5 @@
 	 */
 	page_mapping_insert(AS, upage, frame, as_area_get_flags(area));
-	if (!used_space_insert(area, upage, 1))
+	if (!used_space_insert(&area->used_space, upage, 1))
 		panic("Cannot insert used space.");
 
Index: kernel/generic/src/mm/backend_elf.c
===================================================================
--- kernel/generic/src/mm/backend_elf.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/mm/backend_elf.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -153,6 +153,6 @@
 {
 	elf_segment_header_t *entry = area->backend_data.segment;
-	link_t *cur;
-	btree_node_t *leaf, *node;
+	used_space_ival_t *start;
+	used_space_ival_t *cur;
 	uintptr_t start_anon = entry->p_vaddr + entry->p_filesz;
 
@@ -164,11 +164,8 @@
 	 */
 	if (area->flags & AS_AREA_WRITE) {
-		node = list_get_instance(list_first(&area->used_space.leaf_list),
-		    btree_node_t, leaf_link);
+		start = used_space_first(&area->used_space);
 	} else {
-		(void) btree_search(&area->used_space, start_anon, &leaf);
-		node = btree_leaf_node_left_neighbour(&area->used_space, leaf);
-		if (!node)
-			node = leaf;
+		/* Find first interval containing addresses >= start_anon */
+		start = used_space_find_gteq(&area->used_space, start_anon);
 	}
 
@@ -177,57 +174,53 @@
 	 */
 	mutex_lock(&area->sh_info->lock);
-	for (cur = &node->leaf_link; cur != &area->used_space.leaf_list.head;
-	    cur = cur->next) {
+	cur = start;
+	while (cur != NULL) {
+		uintptr_t base = cur->page;
+		size_t count = cur->count;
 		unsigned int i;
 
-		node = list_get_instance(cur, btree_node_t, leaf_link);
-
-		for (i = 0; i < node->keys; i++) {
-			uintptr_t base = node->key[i];
-			size_t count = (size_t) node->value[i];
-			unsigned int j;
+		/*
+		 * Skip read-only areas of used space that are backed
+		 * by the ELF image.
+		 */
+		if (!(area->flags & AS_AREA_WRITE))
+			if (base >= entry->p_vaddr &&
+			    base + P2SZ(count) <= start_anon)
+				continue;
+
+		for (i = 0; i < count; i++) {
+			pte_t pte;
+			bool found;
 
 			/*
-			 * Skip read-only areas of used space that are backed
-			 * by the ELF image.
+			 * Skip read-only pages that are backed by the
+			 * ELF image.
 			 */
 			if (!(area->flags & AS_AREA_WRITE))
 				if (base >= entry->p_vaddr &&
-				    base + P2SZ(count) <= start_anon)
+				    base + P2SZ(i + 1) <= start_anon)
 					continue;
 
-			for (j = 0; j < count; j++) {
-				pte_t pte;
-				bool found;
-
-				/*
-				 * Skip read-only pages that are backed by the
-				 * ELF image.
-				 */
-				if (!(area->flags & AS_AREA_WRITE))
-					if (base >= entry->p_vaddr &&
-					    base + P2SZ(j + 1) <= start_anon)
-						continue;
-
-				page_table_lock(area->as, false);
-				found = page_mapping_find(area->as,
-				    base + P2SZ(j), false, &pte);
-
-				(void) found;
-				assert(found);
-				assert(PTE_VALID(&pte));
-				assert(PTE_PRESENT(&pte));
-
-				btree_insert(&area->sh_info->pagemap,
-				    (base + P2SZ(j)) - area->base,
-				    (void *) PTE_GET_FRAME(&pte), NULL);
-				page_table_unlock(area->as, false);
-
-				pfn_t pfn = ADDR2PFN(PTE_GET_FRAME(&pte));
-				frame_reference_add(pfn);
-			}
-
+			page_table_lock(area->as, false);
+			found = page_mapping_find(area->as,
+			    base + P2SZ(i), false, &pte);
+
+			(void) found;
+			assert(found);
+			assert(PTE_VALID(&pte));
+			assert(PTE_PRESENT(&pte));
+
+			as_pagemap_insert(&area->sh_info->pagemap,
+			    (base + P2SZ(i)) - area->base,
+			    PTE_GET_FRAME(&pte));
+			page_table_unlock(area->as, false);
+
+			pfn_t pfn = ADDR2PFN(PTE_GET_FRAME(&pte));
+			frame_reference_add(pfn);
 		}
-	}
+
+		cur = used_space_next(cur);
+	}
+
 	mutex_unlock(&area->sh_info->lock);
 }
@@ -267,5 +260,4 @@
 	elf_header_t *elf = area->backend_data.elf;
 	elf_segment_header_t *entry = area->backend_data.segment;
-	btree_node_t *leaf;
 	uintptr_t base;
 	uintptr_t frame;
@@ -301,31 +293,15 @@
 	mutex_lock(&area->sh_info->lock);
 	if (area->sh_info->shared) {
-		bool found = false;
-
 		/*
 		 * The address space area is shared.
 		 */
 
-		frame = (uintptr_t) btree_search(&area->sh_info->pagemap,
-		    upage - area->base, &leaf);
-		if (!frame) {
-			unsigned int i;
-
-			/*
-			 * Workaround for valid NULL address.
-			 */
-
-			for (i = 0; i < leaf->keys; i++) {
-				if (leaf->key[i] == upage - area->base) {
-					found = true;
-					break;
-				}
-			}
-		}
-		if (frame || found) {
+		errno_t rc = as_pagemap_find(&area->sh_info->pagemap,
+		    upage - area->base, &frame);
+		if (rc == EOK) {
 			frame_reference_add(ADDR2PFN(frame));
 			page_mapping_insert(AS, upage, frame,
 			    as_area_get_flags(area));
-			if (!used_space_insert(area, upage, 1))
+			if (!used_space_insert(&area->used_space, upage, 1))
 				panic("Cannot insert used space.");
 			mutex_unlock(&area->sh_info->lock);
@@ -415,6 +391,6 @@
 	if (dirty && area->sh_info->shared) {
 		frame_reference_add(ADDR2PFN(frame));
-		btree_insert(&area->sh_info->pagemap, upage - area->base,
-		    (void *) frame, leaf);
+		as_pagemap_insert(&area->sh_info->pagemap, upage - area->base,
+		    frame);
 	}
 
@@ -422,5 +398,5 @@
 
 	page_mapping_insert(AS, upage, frame, as_area_get_flags(area));
-	if (!used_space_insert(area, upage, 1))
+	if (!used_space_insert(&area->used_space, upage, 1))
 		panic("Cannot insert used space.");
 
Index: kernel/generic/src/mm/backend_phys.c
===================================================================
--- kernel/generic/src/mm/backend_phys.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/mm/backend_phys.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -143,5 +143,5 @@
 	    as_area_get_flags(area));
 
-	if (!used_space_insert(area, upage, 1))
+	if (!used_space_insert(&area->used_space, upage, 1))
 		panic("Cannot insert used space.");
 
Index: kernel/generic/src/mm/backend_user.c
===================================================================
--- kernel/generic/src/mm/backend_user.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/mm/backend_user.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -119,10 +119,10 @@
 
 	ipc_data_t data = { };
-	IPC_SET_IMETHOD(data, IPC_M_PAGE_IN);
-	IPC_SET_ARG1(data, upage - area->base);
-	IPC_SET_ARG2(data, PAGE_SIZE);
-	IPC_SET_ARG3(data, pager_info->id1);
-	IPC_SET_ARG4(data, pager_info->id2);
-	IPC_SET_ARG5(data, pager_info->id3);
+	ipc_set_imethod(&data, IPC_M_PAGE_IN);
+	ipc_set_arg1(&data, upage - area->base);
+	ipc_set_arg2(&data, PAGE_SIZE);
+	ipc_set_arg3(&data, pager_info->id1);
+	ipc_set_arg4(&data, pager_info->id2);
+	ipc_set_arg5(&data, pager_info->id3);
 
 	errno_t rc = ipc_req_internal(pager_info->pager, &data, (sysarg_t) true);
@@ -136,5 +136,5 @@
 	}
 
-	if (IPC_GET_RETVAL(data) != EOK)
+	if (ipc_get_retval(&data) != EOK)
 		return AS_PF_FAULT;
 
@@ -145,7 +145,7 @@
 	 */
 
-	uintptr_t frame = IPC_GET_ARG1(data);
+	uintptr_t frame = ipc_get_arg1(&data);
 	page_mapping_insert(AS, upage, frame, as_area_get_flags(area));
-	if (!used_space_insert(area, upage, 1))
+	if (!used_space_insert(&area->used_space, upage, 1))
 		panic("Cannot insert used space.");
 
Index: kernel/generic/src/mm/frame.c
===================================================================
--- kernel/generic/src/mm/frame.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/mm/frame.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -79,5 +79,5 @@
  *
  */
-NO_TRACE static void frame_initialize(frame_t *frame)
+_NO_TRACE static void frame_initialize(frame_t *frame)
 {
 	frame->refcount = 0;
@@ -100,5 +100,5 @@
  *
  */
-NO_TRACE static size_t zones_insert_zone(pfn_t base, size_t count,
+_NO_TRACE static size_t zones_insert_zone(pfn_t base, size_t count,
     zone_flags_t flags)
 {
@@ -156,5 +156,5 @@
  *
  */
-NO_TRACE static size_t frame_total_free_get_internal(void)
+_NO_TRACE static size_t frame_total_free_get_internal(void)
 {
 	size_t total = 0;
@@ -167,5 +167,5 @@
 }
 
-NO_TRACE size_t frame_total_free_get(void)
+_NO_TRACE size_t frame_total_free_get(void)
 {
 	size_t total;
@@ -190,5 +190,5 @@
  *
  */
-NO_TRACE size_t find_zone(pfn_t frame, size_t count, size_t hint)
+_NO_TRACE size_t find_zone(pfn_t frame, size_t count, size_t hint)
 {
 	if (hint >= zones.count)
@@ -211,5 +211,5 @@
 
 /** @return True if zone can allocate specified number of frames */
-NO_TRACE static bool zone_can_alloc(zone_t *zone, size_t count,
+_NO_TRACE static bool zone_can_alloc(zone_t *zone, size_t count,
     pfn_t constraint)
 {
@@ -239,5 +239,5 @@
  *
  */
-NO_TRACE static size_t find_free_zone_all(size_t count, zone_flags_t flags,
+_NO_TRACE static size_t find_free_zone_all(size_t count, zone_flags_t flags,
     pfn_t constraint, size_t hint)
 {
@@ -265,5 +265,5 @@
  *
  */
-NO_TRACE static bool is_high_priority(pfn_t base, size_t count)
+_NO_TRACE static bool is_high_priority(pfn_t base, size_t count)
 {
 	return (base + count <= FRAME_LOWPRIO);
@@ -285,5 +285,5 @@
  *
  */
-NO_TRACE static size_t find_free_zone_lowprio(size_t count, zone_flags_t flags,
+_NO_TRACE static size_t find_free_zone_lowprio(size_t count, zone_flags_t flags,
     pfn_t constraint, size_t hint)
 {
@@ -322,5 +322,5 @@
  *
  */
-NO_TRACE static size_t find_free_zone(size_t count, zone_flags_t flags,
+_NO_TRACE static size_t find_free_zone(size_t count, zone_flags_t flags,
     pfn_t constraint, size_t hint)
 {
@@ -346,5 +346,5 @@
 
 /** Return frame from zone. */
-NO_TRACE static frame_t *zone_get_frame(zone_t *zone, size_t index)
+_NO_TRACE static frame_t *zone_get_frame(zone_t *zone, size_t index)
 {
 	assert(index < zone->count);
@@ -366,5 +366,5 @@
  *
  */
-NO_TRACE static size_t zone_frame_alloc(zone_t *zone, size_t count,
+_NO_TRACE static size_t zone_frame_alloc(zone_t *zone, size_t count,
     pfn_t constraint)
 {
@@ -405,5 +405,5 @@
  *
  */
-NO_TRACE static size_t zone_frame_free(zone_t *zone, size_t index)
+_NO_TRACE static size_t zone_frame_free(zone_t *zone, size_t index)
 {
 	assert(zone->flags & ZONE_AVAILABLE);
@@ -427,5 +427,5 @@
 
 /** Mark frame in zone unavailable to allocation. */
-NO_TRACE static void zone_mark_unavailable(zone_t *zone, size_t index)
+_NO_TRACE static void zone_mark_unavailable(zone_t *zone, size_t index)
 {
 	assert(zone->flags & ZONE_AVAILABLE);
@@ -453,5 +453,5 @@
  *
  */
-NO_TRACE static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1,
+_NO_TRACE static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1,
     void *confdata)
 {
@@ -507,5 +507,5 @@
  *
  */
-NO_TRACE static void return_config_frames(size_t znum, pfn_t pfn, size_t count)
+_NO_TRACE static void return_config_frames(size_t znum, pfn_t pfn, size_t count)
 {
 	assert(zones.info[znum].flags & ZONE_AVAILABLE);
@@ -623,5 +623,5 @@
  *
  */
-NO_TRACE static void zone_construct(zone_t *zone, pfn_t start, size_t count,
+_NO_TRACE static void zone_construct(zone_t *zone, pfn_t start, size_t count,
     zone_flags_t flags, void *confdata)
 {
@@ -1037,5 +1037,5 @@
  *
  */
-NO_TRACE void frame_reference_add(pfn_t pfn)
+_NO_TRACE void frame_reference_add(pfn_t pfn)
 {
 	irq_spinlock_lock(&zones.lock, true);
@@ -1056,5 +1056,5 @@
  *
  */
-NO_TRACE void frame_mark_unavailable(pfn_t start, size_t count)
+_NO_TRACE void frame_mark_unavailable(pfn_t start, size_t count)
 {
 	irq_spinlock_lock(&zones.lock, true);
Index: kernel/generic/src/mm/page.c
===================================================================
--- kernel/generic/src/mm/page.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/mm/page.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -95,5 +95,5 @@
  *
  */
-NO_TRACE void page_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame,
+_NO_TRACE void page_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame,
     unsigned int flags)
 {
@@ -120,5 +120,5 @@
  *
  */
-NO_TRACE void page_mapping_remove(as_t *as, uintptr_t page)
+_NO_TRACE void page_mapping_remove(as_t *as, uintptr_t page)
 {
 	assert(page_table_locked(as));
@@ -144,5 +144,5 @@
  *         the PTE is not guaranteed to be present.
  */
-NO_TRACE bool page_mapping_find(as_t *as, uintptr_t page, bool nolock,
+_NO_TRACE bool page_mapping_find(as_t *as, uintptr_t page, bool nolock,
     pte_t *pte)
 {
@@ -165,5 +165,5 @@
  * @param pte      New PTE.
  */
-NO_TRACE void page_mapping_update(as_t *as, uintptr_t page, bool nolock,
+_NO_TRACE void page_mapping_update(as_t *as, uintptr_t page, bool nolock,
     pte_t *pte)
 {
Index: kernel/generic/src/mm/slab.c
===================================================================
--- kernel/generic/src/mm/slab.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/mm/slab.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -158,5 +158,5 @@
  *
  */
-NO_TRACE static slab_t *slab_space_alloc(slab_cache_t *cache,
+_NO_TRACE static slab_t *slab_space_alloc(slab_cache_t *cache,
     unsigned int flags)
 {
@@ -206,5 +206,5 @@
  *
  */
-NO_TRACE static size_t slab_space_free(slab_cache_t *cache, slab_t *slab)
+_NO_TRACE static size_t slab_space_free(slab_cache_t *cache, slab_t *slab)
 {
 	frame_free(KA2PA(slab->start), slab->cache->frames);
@@ -218,5 +218,5 @@
 
 /** Map object to slab structure */
-NO_TRACE static slab_t *obj2slab(void *obj)
+_NO_TRACE static slab_t *obj2slab(void *obj)
 {
 	return (slab_t *) frame_get_parent(ADDR2PFN(KA2PA(obj)), 0);
@@ -234,5 +234,5 @@
  *
  */
-NO_TRACE static size_t slab_obj_destroy(slab_cache_t *cache, void *obj,
+_NO_TRACE static size_t slab_obj_destroy(slab_cache_t *cache, void *obj,
     slab_t *slab)
 {
@@ -276,5 +276,5 @@
  *
  */
-NO_TRACE static void *slab_obj_create(slab_cache_t *cache, unsigned int flags)
+_NO_TRACE static void *slab_obj_create(slab_cache_t *cache, unsigned int flags)
 {
 	irq_spinlock_lock(&cache->slablock, true);
@@ -332,5 +332,5 @@
  *
  */
-NO_TRACE static slab_magazine_t *get_mag_from_cache(slab_cache_t *cache,
+_NO_TRACE static slab_magazine_t *get_mag_from_cache(slab_cache_t *cache,
     bool first)
 {
@@ -357,5 +357,5 @@
  *
  */
-NO_TRACE static void put_mag_to_cache(slab_cache_t *cache,
+_NO_TRACE static void put_mag_to_cache(slab_cache_t *cache,
     slab_magazine_t *mag)
 {
@@ -373,5 +373,5 @@
  *
  */
-NO_TRACE static size_t magazine_destroy(slab_cache_t *cache,
+_NO_TRACE static size_t magazine_destroy(slab_cache_t *cache,
     slab_magazine_t *mag)
 {
@@ -392,5 +392,5 @@
  *
  */
-NO_TRACE static slab_magazine_t *get_full_current_mag(slab_cache_t *cache)
+_NO_TRACE static slab_magazine_t *get_full_current_mag(slab_cache_t *cache)
 {
 	slab_magazine_t *cmag = cache->mag_cache[CPU->id].current;
@@ -429,5 +429,5 @@
  *
  */
-NO_TRACE static void *magazine_obj_get(slab_cache_t *cache)
+_NO_TRACE static void *magazine_obj_get(slab_cache_t *cache)
 {
 	if (!CPU)
@@ -459,5 +459,5 @@
  *
  */
-NO_TRACE static slab_magazine_t *make_empty_current_mag(slab_cache_t *cache)
+_NO_TRACE static slab_magazine_t *make_empty_current_mag(slab_cache_t *cache)
 {
 	slab_magazine_t *cmag = cache->mag_cache[CPU->id].current;
@@ -509,5 +509,5 @@
  *
  */
-NO_TRACE static int magazine_obj_put(slab_cache_t *cache, void *obj)
+_NO_TRACE static int magazine_obj_put(slab_cache_t *cache, void *obj)
 {
 	if (!CPU)
@@ -538,5 +538,5 @@
  *
  */
-NO_TRACE static size_t comp_objects(slab_cache_t *cache)
+_NO_TRACE static size_t comp_objects(slab_cache_t *cache)
 {
 	if (cache->flags & SLAB_CACHE_SLINSIDE)
@@ -550,5 +550,5 @@
  *
  */
-NO_TRACE static size_t badness(slab_cache_t *cache)
+_NO_TRACE static size_t badness(slab_cache_t *cache)
 {
 	size_t objects = comp_objects(cache);
@@ -564,5 +564,5 @@
  *
  */
-NO_TRACE static bool make_magcache(slab_cache_t *cache)
+_NO_TRACE static bool make_magcache(slab_cache_t *cache)
 {
 	assert(_slab_initialized >= 2);
@@ -585,5 +585,5 @@
  *
  */
-NO_TRACE static void _slab_cache_create(slab_cache_t *cache, const char *name,
+_NO_TRACE static void _slab_cache_create(slab_cache_t *cache, const char *name,
     size_t size, size_t align, errno_t (*constructor)(void *obj,
     unsigned int kmflag), size_t (*destructor)(void *obj), unsigned int flags)
@@ -660,5 +660,5 @@
  *
  */
-NO_TRACE static size_t _slab_reclaim(slab_cache_t *cache, unsigned int flags)
+_NO_TRACE static size_t _slab_reclaim(slab_cache_t *cache, unsigned int flags)
 {
 	if (cache->flags & SLAB_CACHE_NOMAGAZINE)
@@ -707,5 +707,5 @@
  *
  */
-NO_TRACE static void _slab_free(slab_cache_t *cache, void *obj, slab_t *slab)
+_NO_TRACE static void _slab_free(slab_cache_t *cache, void *obj, slab_t *slab)
 {
 	if (!obj)
Index: kernel/generic/src/proc/current.c
===================================================================
--- kernel/generic/src/proc/current.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/proc/current.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -70,5 +70,5 @@
  *
  */
-NO_TRACE void current_copy(current_t *src, current_t *dst)
+_NO_TRACE void current_copy(current_t *src, current_t *dst)
 {
 	assert(src->magic == MAGIC);
Index: kernel/generic/src/proc/program.c
===================================================================
--- kernel/generic/src/proc/program.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/proc/program.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -48,5 +48,5 @@
 #include <security/perm.h>
 #include <lib/elf_load.h>
-#include <errno.h>
+#include <str.h>
 #include <log.h>
 #include <syscall/copy.h>
@@ -76,5 +76,5 @@
 		return ENOMEM;
 
-	prg->loader_status = EE_OK;
+	prg->loader_status = EOK;
 	prg->task = task_create(as, name);
 	if (!prg->task) {
@@ -149,5 +149,5 @@
 
 	prg->loader_status = elf_load((elf_header_t *) image_addr, as);
-	if (prg->loader_status != EE_OK) {
+	if (prg->loader_status != EOK) {
 		as_release(as);
 		prg->task = NULL;
@@ -183,8 +183,8 @@
 
 	prg->loader_status = elf_load((elf_header_t *) program_loader, as);
-	if (prg->loader_status != EE_OK) {
+	if (prg->loader_status != EOK) {
 		as_release(as);
 		log(LF_OTHER, LVL_ERROR, "Cannot spawn loader (%s)",
-		    elf_error(prg->loader_status));
+		    str_error(prg->loader_status));
 		return ENOENT;
 	}
Index: kernel/generic/src/proc/task.c
===================================================================
--- kernel/generic/src/proc/task.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/proc/task.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -269,5 +269,5 @@
 {
 	/*
-	 * Remove the task from the task B+tree.
+	 * Remove the task from the task odict.
 	 */
 	irq_spinlock_lock(&tasks_lock, true);
Index: kernel/generic/src/proc/thread.c
===================================================================
--- kernel/generic/src/proc/thread.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/proc/thread.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -180,9 +180,9 @@
 	 * covered by the kernel identity mapping, which guarantees not to
 	 * nest TLB-misses infinitely (either via some hardware mechanism or
-	 * by the construciton of the assembly-language part of the TLB-miss
+	 * by the construction of the assembly-language part of the TLB-miss
 	 * handler).
 	 *
 	 * This restriction can be lifted once each architecture provides
-	 * a similar guarantee, for example by locking the kernel stack
+	 * a similar guarantee, for example, by locking the kernel stack
 	 * in the TLB whenever it is allocated from the high-memory and the
 	 * thread is being scheduled to run.
Index: kernel/generic/src/sysinfo/stats.c
===================================================================
--- kernel/generic/src/sysinfo/stats.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/sysinfo/stats.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -189,5 +189,5 @@
 			continue;
 
-		pages += area->resident;
+		pages += area->used_space.pages;
 		mutex_unlock(&area->lock);
 		area = as_area_next(area);
Index: kernel/generic/src/sysinfo/sysinfo.c
===================================================================
--- kernel/generic/src/sysinfo/sysinfo.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/sysinfo/sysinfo.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -62,5 +62,5 @@
  *
  */
-NO_TRACE static errno_t sysinfo_item_constructor(void *obj, unsigned int kmflag)
+_NO_TRACE static errno_t sysinfo_item_constructor(void *obj, unsigned int kmflag)
 {
 	sysinfo_item_t *item = (sysinfo_item_t *) obj;
@@ -82,5 +82,5 @@
  *
  */
-NO_TRACE static size_t sysinfo_item_destructor(void *obj)
+_NO_TRACE static size_t sysinfo_item_destructor(void *obj)
 {
 	sysinfo_item_t *item = (sysinfo_item_t *) obj;
@@ -124,5 +124,5 @@
  *
  */
-NO_TRACE static sysinfo_item_t *sysinfo_find_item(const char *name,
+_NO_TRACE static sysinfo_item_t *sysinfo_find_item(const char *name,
     sysinfo_item_t *subtree, sysinfo_return_t **ret, bool dry_run)
 {
@@ -190,5 +190,5 @@
  *
  */
-NO_TRACE static sysinfo_item_t *sysinfo_create_path(const char *name,
+_NO_TRACE static sysinfo_item_t *sysinfo_create_path(const char *name,
     sysinfo_item_t **psubtree)
 {
@@ -508,5 +508,5 @@
  *
  */
-NO_TRACE static void sysinfo_indent(size_t spaces)
+_NO_TRACE static void sysinfo_indent(size_t spaces)
 {
 	for (size_t i = 0; i < spaces; i++)
@@ -522,5 +522,5 @@
  *
  */
-NO_TRACE static void sysinfo_dump_internal(sysinfo_item_t *root, size_t spaces)
+_NO_TRACE static void sysinfo_dump_internal(sysinfo_item_t *root, size_t spaces)
 {
 	/* Walk all siblings */
@@ -622,5 +622,5 @@
  *
  */
-NO_TRACE static sysinfo_return_t sysinfo_get_item(const char *name,
+_NO_TRACE static sysinfo_return_t sysinfo_get_item(const char *name,
     sysinfo_item_t **root, bool dry_run)
 {
@@ -677,5 +677,5 @@
  *
  */
-NO_TRACE static sysinfo_return_t sysinfo_get_item_uspace(void *ptr, size_t size,
+_NO_TRACE static sysinfo_return_t sysinfo_get_item_uspace(void *ptr, size_t size,
     bool dry_run)
 {
@@ -720,5 +720,5 @@
  *
  */
-NO_TRACE static sysinfo_return_t sysinfo_get_keys(const char *name,
+_NO_TRACE static sysinfo_return_t sysinfo_get_keys(const char *name,
     sysinfo_item_t **root, bool dry_run)
 {
@@ -786,5 +786,5 @@
  *
  */
-NO_TRACE static sysinfo_return_t sysinfo_get_keys_uspace(void *ptr, size_t size,
+_NO_TRACE static sysinfo_return_t sysinfo_get_keys_uspace(void *ptr, size_t size,
     bool dry_run)
 {
Index: kernel/generic/src/udebug/udebug.c
===================================================================
--- kernel/generic/src/udebug/udebug.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/udebug/udebug.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -141,5 +141,5 @@
 		TASK->udebug.begin_call = NULL;
 
-		IPC_SET_RETVAL(db_call->data, 0);
+		ipc_set_retval(&db_call->data, 0);
 		ipc_answer(&TASK->answerbox, db_call);
 	} else if (TASK->udebug.dt_state == UDEBUG_TS_ACTIVE) {
@@ -160,6 +160,6 @@
 			assert(go_call);
 
-			IPC_SET_RETVAL(go_call->data, 0);
-			IPC_SET_ARG1(go_call->data, UDEBUG_EVENT_STOP);
+			ipc_set_retval(&go_call->data, 0);
+			ipc_set_arg1(&go_call->data, UDEBUG_EVENT_STOP);
 
 			THREAD->udebug.cur_event = UDEBUG_EVENT_STOP;
@@ -243,8 +243,8 @@
 	THREAD->udebug.go_call = NULL;
 
-	IPC_SET_RETVAL(call->data, 0);
-	IPC_SET_ARG1(call->data, etype);
-	IPC_SET_ARG2(call->data, id);
-	IPC_SET_ARG3(call->data, rc);
+	ipc_set_retval(&call->data, 0);
+	ipc_set_arg1(&call->data, etype);
+	ipc_set_arg2(&call->data, id);
+	ipc_set_arg3(&call->data, rc);
 
 	THREAD->udebug.syscall_args[0] = a1;
@@ -314,7 +314,7 @@
 
 	THREAD->udebug.go_call = NULL;
-	IPC_SET_RETVAL(call->data, 0);
-	IPC_SET_ARG1(call->data, UDEBUG_EVENT_THREAD_B);
-	IPC_SET_ARG2(call->data, (sysarg_t) thread);
+	ipc_set_retval(&call->data, 0);
+	ipc_set_arg1(&call->data, UDEBUG_EVENT_THREAD_B);
+	ipc_set_arg2(&call->data, (sysarg_t) thread);
 
 	/*
@@ -365,6 +365,6 @@
 
 	THREAD->udebug.go_call = NULL;
-	IPC_SET_RETVAL(call->data, 0);
-	IPC_SET_ARG1(call->data, UDEBUG_EVENT_THREAD_E);
+	ipc_set_retval(&call->data, 0);
+	ipc_set_arg1(&call->data, UDEBUG_EVENT_THREAD_E);
 
 	/* Prevent any further debug activity in thread. */
@@ -428,6 +428,6 @@
 				LOG("Answer GO call with EVENT_FINISHED.");
 
-				IPC_SET_RETVAL(thread->udebug.go_call->data, 0);
-				IPC_SET_ARG1(thread->udebug.go_call->data,
+				ipc_set_retval(&thread->udebug.go_call->data, 0);
+				ipc_set_arg1(&thread->udebug.go_call->data,
 				    UDEBUG_EVENT_FINISHED);
 
Index: kernel/generic/src/udebug/udebug_ipc.c
===================================================================
--- kernel/generic/src/udebug/udebug_ipc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/udebug/udebug_ipc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -53,5 +53,5 @@
 errno_t udebug_request_preprocess(call_t *call, phone_t *phone)
 {
-	switch (IPC_GET_ARG1(call->data)) {
+	switch (ipc_get_arg1(&call->data)) {
 		/* future UDEBUG_M_REGS_WRITE, UDEBUG_M_MEM_WRITE: */
 	default:
@@ -76,5 +76,5 @@
 	rc = udebug_begin(call, &active);
 	if (rc != EOK) {
-		IPC_SET_RETVAL(call->data, rc);
+		ipc_set_retval(&call->data, rc);
 		ipc_answer(&TASK->kb.box, call);
 		return;
@@ -86,5 +86,5 @@
 	 */
 	if (active) {
-		IPC_SET_RETVAL(call->data, EOK);
+		ipc_set_retval(&call->data, EOK);
 		ipc_answer(&TASK->kb.box, call);
 	}
@@ -102,5 +102,5 @@
 	rc = udebug_end();
 
-	IPC_SET_RETVAL(call->data, rc);
+	ipc_set_retval(&call->data, rc);
 	ipc_answer(&TASK->kb.box, call);
 }
@@ -116,8 +116,8 @@
 	udebug_evmask_t mask;
 
-	mask = IPC_GET_ARG2(call->data);
+	mask = ipc_get_arg2(&call->data);
 	rc = udebug_set_evmask(mask);
 
-	IPC_SET_RETVAL(call->data, rc);
+	ipc_set_retval(&call->data, rc);
 	ipc_answer(&TASK->kb.box, call);
 }
@@ -133,9 +133,9 @@
 	errno_t rc;
 
-	t = (thread_t *)IPC_GET_ARG2(call->data);
+	t = (thread_t *)ipc_get_arg2(&call->data);
 
 	rc = udebug_go(t, call);
 	if (rc != EOK) {
-		IPC_SET_RETVAL(call->data, rc);
+		ipc_set_retval(&call->data, rc);
 		ipc_answer(&TASK->kb.box, call);
 		return;
@@ -153,8 +153,8 @@
 	errno_t rc;
 
-	t = (thread_t *)IPC_GET_ARG2(call->data);
+	t = (thread_t *)ipc_get_arg2(&call->data);
 
 	rc = udebug_stop(t, call);
-	IPC_SET_RETVAL(call->data, rc);
+	ipc_set_retval(&call->data, rc);
 	ipc_answer(&TASK->kb.box, call);
 }
@@ -173,6 +173,6 @@
 	errno_t rc;
 
-	uspace_addr = IPC_GET_ARG2(call->data);	/* Destination address */
-	buf_size = IPC_GET_ARG3(call->data);	/* Dest. buffer size */
+	uspace_addr = ipc_get_arg2(&call->data);	/* Destination address */
+	buf_size = ipc_get_arg3(&call->data);	/* Dest. buffer size */
 
 	/*
@@ -182,5 +182,5 @@
 	rc = udebug_thread_read(&buffer, buf_size, &copied, &needed);
 	if (rc != EOK) {
-		IPC_SET_RETVAL(call->data, rc);
+		ipc_set_retval(&call->data, rc);
 		ipc_answer(&TASK->kb.box, call);
 		return;
@@ -191,13 +191,13 @@
 	 */
 
-	IPC_SET_RETVAL(call->data, 0);
-	/*
-	 * ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
-	 * same code in process_answer() can be used
-	 * (no way to distinguish method in answer)
-	 */
-	IPC_SET_ARG1(call->data, uspace_addr);
-	IPC_SET_ARG2(call->data, copied);
-	IPC_SET_ARG3(call->data, needed);
+	ipc_set_retval(&call->data, 0);
+	/*
+	 * ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
+	 * same code in process_answer() can be used
+	 * (no way to distinguish method in answer)
+	 */
+	ipc_set_arg1(&call->data, uspace_addr);
+	ipc_set_arg2(&call->data, copied);
+	ipc_set_arg3(&call->data, needed);
 	call->buffer = buffer;
 
@@ -219,6 +219,6 @@
 	void *data;
 
-	uspace_addr = IPC_GET_ARG2(call->data);	/* Destination address */
-	buf_size = IPC_GET_ARG3(call->data);	/* Dest. buffer size */
+	uspace_addr = ipc_get_arg2(&call->data);	/* Destination address */
+	buf_size = ipc_get_arg3(&call->data);	/* Dest. buffer size */
 
 	/*
@@ -238,14 +238,14 @@
 	 */
 
-	IPC_SET_RETVAL(call->data, 0);
-	/*
-	 * ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
-	 * same code in process_answer() can be used
-	 * (no way to distinguish method in answer)
-	 */
-	IPC_SET_ARG1(call->data, uspace_addr);
-	IPC_SET_ARG2(call->data, to_copy);
-
-	IPC_SET_ARG3(call->data, data_size);
+	ipc_set_retval(&call->data, 0);
+	/*
+	 * ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
+	 * same code in process_answer() can be used
+	 * (no way to distinguish method in answer)
+	 */
+	ipc_set_arg1(&call->data, uspace_addr);
+	ipc_set_arg2(&call->data, to_copy);
+
+	ipc_set_arg3(&call->data, data_size);
 	call->buffer = data;
 
@@ -268,6 +268,6 @@
 	as_area_info_t *data;
 
-	uspace_addr = IPC_GET_ARG2(call->data);	/* Destination address */
-	buf_size = IPC_GET_ARG3(call->data);	/* Dest. buffer size */
+	uspace_addr = ipc_get_arg2(&call->data);	/* Destination address */
+	buf_size = ipc_get_arg3(&call->data);	/* Dest. buffer size */
 
 	/*
@@ -276,5 +276,5 @@
 	data = as_get_area_info(AS, &data_size);
 	if (!data) {
-		IPC_SET_RETVAL(call->data, ENOMEM);
+		ipc_set_retval(&call->data, ENOMEM);
 		ipc_answer(&TASK->kb.box, call);
 		return;
@@ -292,14 +292,14 @@
 	 */
 
-	IPC_SET_RETVAL(call->data, 0);
-	/*
-	 * ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
-	 * same code in process_answer() can be used
-	 * (no way to distinguish method in answer)
-	 */
-	IPC_SET_ARG1(call->data, uspace_addr);
-	IPC_SET_ARG2(call->data, to_copy);
-
-	IPC_SET_ARG3(call->data, data_size);
+	ipc_set_retval(&call->data, 0);
+	/*
+	 * ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
+	 * same code in process_answer() can be used
+	 * (no way to distinguish method in answer)
+	 */
+	ipc_set_arg1(&call->data, uspace_addr);
+	ipc_set_arg2(&call->data, to_copy);
+
+	ipc_set_arg3(&call->data, data_size);
 	call->buffer = (uint8_t *) data;
 
@@ -319,9 +319,9 @@
 	void *buffer;
 
-	t = (thread_t *)IPC_GET_ARG2(call->data);
+	t = (thread_t *)ipc_get_arg2(&call->data);
 
 	rc = udebug_args_read(t, &buffer);
 	if (rc != EOK) {
-		IPC_SET_RETVAL(call->data, rc);
+		ipc_set_retval(&call->data, rc);
 		ipc_answer(&TASK->kb.box, call);
 		return;
@@ -332,14 +332,14 @@
 	 */
 
-	uspace_addr = IPC_GET_ARG3(call->data);
-
-	IPC_SET_RETVAL(call->data, 0);
-	/*
-	 * ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
-	 * same code in process_answer() can be used
-	 * (no way to distinguish method in answer)
-	 */
-	IPC_SET_ARG1(call->data, uspace_addr);
-	IPC_SET_ARG2(call->data, 6 * sizeof(sysarg_t));
+	uspace_addr = ipc_get_arg3(&call->data);
+
+	ipc_set_retval(&call->data, 0);
+	/*
+	 * ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
+	 * same code in process_answer() can be used
+	 * (no way to distinguish method in answer)
+	 */
+	ipc_set_arg1(&call->data, uspace_addr);
+	ipc_set_arg2(&call->data, 6 * sizeof(sysarg_t));
 	call->buffer = buffer;
 
@@ -359,9 +359,9 @@
 	errno_t rc;
 
-	t = (thread_t *) IPC_GET_ARG2(call->data);
+	t = (thread_t *) ipc_get_arg2(&call->data);
 
 	rc = udebug_regs_read(t, &buffer);
 	if (rc != EOK) {
-		IPC_SET_RETVAL(call->data, rc);
+		ipc_set_retval(&call->data, rc);
 		ipc_answer(&TASK->kb.box, call);
 		return;
@@ -374,15 +374,15 @@
 	 */
 
-	uspace_addr = IPC_GET_ARG3(call->data);
+	uspace_addr = ipc_get_arg3(&call->data);
 	to_copy = sizeof(istate_t);
 
-	IPC_SET_RETVAL(call->data, 0);
-	/*
-	 * ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
-	 * same code in process_answer() can be used
-	 * (no way to distinguish method in answer)
-	 */
-	IPC_SET_ARG1(call->data, uspace_addr);
-	IPC_SET_ARG2(call->data, to_copy);
+	ipc_set_retval(&call->data, 0);
+	/*
+	 * ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
+	 * same code in process_answer() can be used
+	 * (no way to distinguish method in answer)
+	 */
+	ipc_set_arg1(&call->data, uspace_addr);
+	ipc_set_arg2(&call->data, to_copy);
 
 	call->buffer = buffer;
@@ -404,11 +404,11 @@
 	errno_t rc;
 
-	uspace_dst = IPC_GET_ARG2(call->data);
-	uspace_src = IPC_GET_ARG3(call->data);
-	size = IPC_GET_ARG4(call->data);
+	uspace_dst = ipc_get_arg2(&call->data);
+	uspace_src = ipc_get_arg3(&call->data);
+	size = ipc_get_arg4(&call->data);
 
 	rc = udebug_mem_read(uspace_src, size, &buffer);
 	if (rc != EOK) {
-		IPC_SET_RETVAL(call->data, rc);
+		ipc_set_retval(&call->data, rc);
 		ipc_answer(&TASK->kb.box, call);
 		return;
@@ -417,12 +417,12 @@
 	assert(buffer != NULL);
 
-	IPC_SET_RETVAL(call->data, 0);
-	/*
-	 * ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
-	 * same code in process_answer() can be used
-	 * (no way to distinguish method in answer)
-	 */
-	IPC_SET_ARG1(call->data, uspace_dst);
-	IPC_SET_ARG2(call->data, size);
+	ipc_set_retval(&call->data, 0);
+	/*
+	 * ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
+	 * same code in process_answer() can be used
+	 * (no way to distinguish method in answer)
+	 */
+	ipc_set_arg1(&call->data, uspace_dst);
+	ipc_set_arg2(&call->data, size);
 	call->buffer = buffer;
 
@@ -439,5 +439,5 @@
 	int debug_method;
 
-	debug_method = IPC_GET_ARG1(call->data);
+	debug_method = ipc_get_arg1(&call->data);
 
 	if (debug_method != UDEBUG_M_BEGIN) {
@@ -450,5 +450,5 @@
 		 */
 		if (TASK->udebug.debugger != call->sender) {
-			IPC_SET_RETVAL(call->data, EINVAL);
+			ipc_set_retval(&call->data, EINVAL);
 			ipc_answer(&TASK->kb.box, call);
 			return;
Index: kernel/generic/src/udebug/udebug_ops.c
===================================================================
--- kernel/generic/src/udebug/udebug_ops.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/generic/src/udebug/udebug_ops.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -328,6 +328,6 @@
 	thread->udebug.go_call = NULL;
 
-	IPC_SET_RETVAL(call->data, 0);
-	IPC_SET_ARG1(call->data, UDEBUG_EVENT_STOP);
+	ipc_set_retval(&call->data, 0);
+	ipc_set_arg1(&call->data, UDEBUG_EVENT_STOP);
 
 	THREAD->udebug.cur_event = UDEBUG_EVENT_STOP;
Index: rnel/test/btree/btree1.c
===================================================================
--- kernel/test/btree/btree1.c	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,161 +1,0 @@
-/*
- * 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.
- */
-
-#include <test.h>
-#include <adt/btree.h>
-
-static void *data = (void *) 0xdeadbeef;
-
-const char *test_btree1(void)
-{
-	btree_t t;
-	int i;
-
-	btree_create(&t);
-
-	TPRINTF("Inserting keys.\n");
-	btree_insert(&t, 19, data, NULL);
-	btree_insert(&t, 20, data, NULL);
-	btree_insert(&t, 21, data, NULL);
-	btree_insert(&t, 0, data, NULL);
-	btree_insert(&t, 25, data, NULL);
-	btree_insert(&t, 22, data, NULL);
-	btree_insert(&t, 26, data, NULL);
-	btree_insert(&t, 23, data, NULL);
-	btree_insert(&t, 24, data, NULL);
-	btree_insert(&t, 5, data, NULL);
-	btree_insert(&t, 1, data, NULL);
-	btree_insert(&t, 4, data, NULL);
-	btree_insert(&t, 28, data, NULL);
-	btree_insert(&t, 29, data, NULL);
-	btree_insert(&t, 7, data, NULL);
-	btree_insert(&t, 8, data, NULL);
-	btree_insert(&t, 9, data, NULL);
-	btree_insert(&t, 17, data, NULL);
-	btree_insert(&t, 18, data, NULL);
-	btree_insert(&t, 2, data, NULL);
-	btree_insert(&t, 3, data, NULL);
-	btree_insert(&t, 6, data, NULL);
-	btree_insert(&t, 10, data, NULL);
-	btree_insert(&t, 11, data, NULL);
-	btree_insert(&t, 12, data, NULL);
-	btree_insert(&t, 13, data, NULL);
-	btree_insert(&t, 14, data, NULL);
-	btree_insert(&t, 15, data, NULL);
-	btree_insert(&t, 16, data, NULL);
-	btree_insert(&t, 27, data, NULL);
-
-	for (i = 30; i < 50; i++)
-		btree_insert(&t, i, data, NULL);
-	for (i = 100; i >= 50; i--)
-		btree_insert(&t, i, data, NULL);
-
-	if (!test_quiet)
-		btree_print(&t);
-
-	TPRINTF("Removing keys.\n");
-	btree_remove(&t, 50, NULL);
-	btree_remove(&t, 49, NULL);
-	btree_remove(&t, 51, NULL);
-	btree_remove(&t, 46, NULL);
-	btree_remove(&t, 45, NULL);
-	btree_remove(&t, 48, NULL);
-	btree_remove(&t, 53, NULL);
-	btree_remove(&t, 47, NULL);
-	btree_remove(&t, 52, NULL);
-	btree_remove(&t, 54, NULL);
-	btree_remove(&t, 65, NULL);
-	btree_remove(&t, 60, NULL);
-	btree_remove(&t, 99, NULL);
-	btree_remove(&t, 97, NULL);
-	btree_remove(&t, 57, NULL);
-	btree_remove(&t, 58, NULL);
-	btree_remove(&t, 61, NULL);
-	btree_remove(&t, 64, NULL);
-	btree_remove(&t, 56, NULL);
-	btree_remove(&t, 41, NULL);
-
-	for (i = 5; i < 20; i++)
-		btree_remove(&t, i, NULL);
-
-	btree_remove(&t, 2, NULL);
-	btree_remove(&t, 43, NULL);
-	btree_remove(&t, 22, NULL);
-	btree_remove(&t, 100, NULL);
-	btree_remove(&t, 98, NULL);
-	btree_remove(&t, 96, NULL);
-	btree_remove(&t, 66, NULL);
-	btree_remove(&t, 1, NULL);
-
-	for (i = 70; i < 90; i++)
-		btree_remove(&t, i, NULL);
-
-	btree_remove(&t, 20, NULL);
-	btree_remove(&t, 0, NULL);
-	btree_remove(&t, 40, NULL);
-	btree_remove(&t, 3, NULL);
-	btree_remove(&t, 4, NULL);
-	btree_remove(&t, 21, NULL);
-	btree_remove(&t, 44, NULL);
-	btree_remove(&t, 55, NULL);
-	btree_remove(&t, 62, NULL);
-	btree_remove(&t, 26, NULL);
-	btree_remove(&t, 27, NULL);
-	btree_remove(&t, 28, NULL);
-	btree_remove(&t, 29, NULL);
-	btree_remove(&t, 30, NULL);
-	btree_remove(&t, 31, NULL);
-	btree_remove(&t, 32, NULL);
-	btree_remove(&t, 33, NULL);
-	btree_remove(&t, 93, NULL);
-	btree_remove(&t, 95, NULL);
-	btree_remove(&t, 94, NULL);
-	btree_remove(&t, 69, NULL);
-	btree_remove(&t, 68, NULL);
-	btree_remove(&t, 92, NULL);
-	btree_remove(&t, 91, NULL);
-	btree_remove(&t, 67, NULL);
-	btree_remove(&t, 63, NULL);
-	btree_remove(&t, 90, NULL);
-	btree_remove(&t, 59, NULL);
-	btree_remove(&t, 23, NULL);
-	btree_remove(&t, 24, NULL);
-	btree_remove(&t, 25, NULL);
-	btree_remove(&t, 37, NULL);
-	btree_remove(&t, 38, NULL);
-	btree_remove(&t, 42, NULL);
-	btree_remove(&t, 39, NULL);
-	btree_remove(&t, 34, NULL);
-	btree_remove(&t, 35, NULL);
-	btree_remove(&t, 36, NULL);
-
-	if (!test_quiet)
-		btree_print(&t);
-
-	return NULL;
-}
Index: rnel/test/btree/btree1.def
===================================================================
--- kernel/test/btree/btree1.def	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,6 +1,0 @@
-{
-	"btree1",
-	"Test B-tree operations",
-	&test_btree1,
-	true
-},
Index: kernel/test/test.c
===================================================================
--- kernel/test/test.c	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/test/test.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -41,5 +41,4 @@
 test_t tests[] = {
 #include <atomic/atomic1.def>
-#include <btree/btree1.def>
 #include <debug/mips1.def>
 #include <fault/fault1.def>
Index: kernel/test/test.h
===================================================================
--- kernel/test/test.h	(revision c878693123930f0906703462cf2807430679517e)
+++ kernel/test/test.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -58,5 +58,4 @@
 
 extern const char *test_atomic1(void);
-extern const char *test_btree1(void);
 extern const char *test_mips1(void);
 extern const char *test_fault1(void);
Index: release/Makefile
===================================================================
--- release/Makefile	(revision c878693123930f0906703462cf2807430679517e)
+++ release/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,4 +39,5 @@
 	arm32/integratorcp \
 	arm32/raspberrypi \
+	arm64/virt \
 	ia32 \
 	ia64/i460GX \
Index: tools/autotool.py
===================================================================
--- tools/autotool.py	(revision c878693123930f0906703462cf2807430679517e)
+++ tools/autotool.py	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,3 +1,3 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python
 #
 # Copyright (c) 2010 Martin Decky
@@ -201,4 +201,8 @@
 		target = "arm-helenos"
 
+	if (config['PLATFORM'] == "arm64"):
+		platform = config['PLATFORM']
+		target = "aarch64-helenos"
+
 	if (config['PLATFORM'] == "ia32"):
 		platform = config['PLATFORM']
@@ -633,5 +637,5 @@
 
 		# Platform-specific utilities
-		if ((config['BARCH'] == "amd64") or (config['BARCH'] == "ia32") or (config['BARCH'] == "ppc32") or (config['BARCH'] == "sparc64")):
+		if (config['BARCH'] in ('amd64', 'arm64', 'ia32', 'ppc32', 'sparc64')):
 			common['GENISOIMAGE'] = check_app_alternatives(["genisoimage", "mkisofs", "xorriso"], ["--version"], "ISO 9660 creation utility", "usually part of genisoimage")
 			if common['GENISOIMAGE'] == 'xorriso':
Index: tools/build-ccheck.sh
===================================================================
--- tools/build-ccheck.sh	(revision c878693123930f0906703462cf2807430679517e)
+++ tools/build-ccheck.sh	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,5 +1,5 @@
 #!/bin/bash
 #
-# Copyright (c) 2018 Jiri Svoboda
+# Copyright (c) 2019 Jiri Svoboda
 # All rights reserved.
 #
@@ -29,5 +29,5 @@
 
 SYCEK_GIT="https://github.com/jxsvoboda/sycek"
-SYCEK_REV="42fe0d77819f0ec05f17e40ea54c7b62073c8e97"
+SYCEK_REV="4dc1760741efdd84506478ab6effd68812b4726a"
 
 if [ ! -d sycek ]; then
Index: tools/config.py
===================================================================
--- tools/config.py	(revision c878693123930f0906703462cf2807430679517e)
+++ tools/config.py	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -47,4 +47,147 @@
 PRESETS_DIR = 'defaults'
 
+class BinaryOp:
+	def __init__(self, operator, left, right):
+		assert operator in ('&', '|', '=', '!=')
+
+		self._operator = operator
+		self._left = left
+		self._right = right
+
+	def evaluate(self, config):
+		if self._operator == '&':
+			return self._left.evaluate(config) and \
+			    self._right.evaluate(config)
+		if self._operator == '|':
+			return self._left.evaluate(config) or \
+			    self._right.evaluate(config)
+
+		# '=' or '!='
+		if not self._left in config:
+			config_val = ''
+		else:
+			config_val = config[self._left]
+			if config_val == '*':
+				config_val = 'y'
+
+		if self._operator == '=':
+			return self._right == config_val
+		return self._right != config_val
+
+# Expression parser
+class CondParser:
+	TOKEN_EOE = 0
+	TOKEN_SPECIAL = 1
+	TOKEN_STRING = 2
+
+	def __init__(self, text):
+		self._text = text
+
+	def parse(self):
+		self._position = -1
+		self._next_char()
+		self._next_token()
+
+		res = self._parse_expr()
+		if self._token_type != self.TOKEN_EOE:
+			self._error("Expected end of expression")
+		return res
+
+	def _next_char(self):
+		self._position += 1
+		if self._position >= len(self._text):
+			self._char = None
+		else:
+			self._char = self._text[self._position]
+		self._is_special_char = self._char in \
+		    ('&', '|', '=', '!', '(', ')')
+
+	def _error(self, msg):
+		raise RuntimeError("Error parsing expression: %s:\n%s\n%s^" %
+		    (msg, self._text, " " * self._token_position))
+
+	def _next_token(self):
+		self._token_position = self._position
+
+		# End of expression
+		if self._char == None:
+			self._token = None
+			self._token_type = self.TOKEN_EOE
+			return
+
+		# '&', '|', '=', '!=', '(', ')'
+		if self._is_special_char:
+			self._token = self._char
+			self._next_char()
+			if self._token == '!':
+				if self._char != '=':
+					self._error("Expected '='")
+				self._token += self._char
+				self._next_char()
+			self._token_type = self.TOKEN_SPECIAL
+			return
+
+		# <var> or <val>
+		self._token = ''
+		self._token_type = self.TOKEN_STRING
+		while True:
+			self._token += self._char
+			self._next_char()
+			if self._is_special_char or self._char == None:
+				break
+
+	def _parse_expr(self):
+		""" <expr> ::= <or_expr> ('&' <or_expr>)* """
+
+		left = self._parse_or_expr()
+		while self._token == '&':
+			self._next_token()
+			left = BinaryOp('&', left, self._parse_or_expr())
+		return left
+
+	def _parse_or_expr(self):
+		""" <or_expr> ::= <factor> ('|' <factor>)* """
+
+		left = self._parse_factor()
+		while self._token == '|':
+			self._next_token()
+			left = BinaryOp('|', left, self._parse_factor())
+		return left
+
+	def _parse_factor(self):
+		""" <factor> ::= <var> <cond> | '(' <expr> ')' """
+
+		if self._token == '(':
+			self._next_token()
+			res = self._parse_expr()
+			if self._token != ')':
+				self._error("Expected ')'")
+			self._next_token()
+			return res
+
+		if self._token_type == self.TOKEN_STRING:
+			var = self._token
+			self._next_token()
+			return self._parse_cond(var)
+
+		self._error("Expected '(' or <var>")
+
+	def _parse_cond(self, var):
+		""" <cond> ::= '=' <val> | '!=' <val> """
+
+		if self._token not in ('=', '!='):
+			self._error("Expected '=' or '!='")
+
+		oper = self._token
+		self._next_token()
+
+		if self._token_type != self.TOKEN_STRING:
+			self._error("Expected <val>")
+
+		val = self._token
+		self._next_token()
+
+		return BinaryOp(oper, var, val)
+
 def read_config(fname, config):
 	"Read saved values from last configuration run or a preset file"
@@ -59,76 +202,4 @@
 	inf.close()
 
-def check_condition(text, config, rules):
-	"Check that the condition specified on input line is True (only CNF and DNF is supported)"
-
-	ctype = 'cnf'
-
-	if (')|' in text) or ('|(' in text):
-		ctype = 'dnf'
-
-	if ctype == 'cnf':
-		conds = text.split('&')
-	else:
-		conds = text.split('|')
-
-	for cond in conds:
-		if cond.startswith('(') and cond.endswith(')'):
-			cond = cond[1:-1]
-
-		inside = check_inside(cond, config, ctype)
-
-		if (ctype == 'cnf') and (not inside):
-			return False
-
-		if (ctype == 'dnf') and inside:
-			return True
-
-	if ctype == 'cnf':
-		return True
-
-	return False
-
-def check_inside(text, config, ctype):
-	"Check for condition"
-
-	if ctype == 'cnf':
-		conds = text.split('|')
-	else:
-		conds = text.split('&')
-
-	for cond in conds:
-		res = re.match(r'^(.*?)(!?=)(.*)$', cond)
-		if not res:
-			raise RuntimeError("Invalid condition: %s" % cond)
-
-		condname = res.group(1)
-		oper = res.group(2)
-		condval = res.group(3)
-
-		if not condname in config:
-			varval = ''
-		else:
-			varval = config[condname]
-			if (varval == '*'):
-				varval = 'y'
-
-		if ctype == 'cnf':
-			if (oper == '=') and (condval == varval):
-				return True
-
-			if (oper == '!=') and (condval != varval):
-				return True
-		else:
-			if (oper == '=') and (condval != varval):
-				return False
-
-			if (oper == '!=') and (condval == varval):
-				return False
-
-	if ctype == 'cnf':
-		return False
-
-	return True
-
 def parse_rules(fname, rules):
 	"Parse rules file"
@@ -149,4 +220,6 @@
 
 			cond = res.group(1)
+			if cond:
+				cond = CondParser(cond).parse()
 			varname = res.group(2)
 			vartype = res.group(3)
@@ -232,5 +305,5 @@
 		varname, vartype, name, choices, cond = rule
 
-		if cond and (not check_condition(cond, config, rules)):
+		if cond and not cond.evaluate(config):
 			continue
 
@@ -279,7 +352,6 @@
 
 	# First check that this rule would make sense
-	if cond:
-		if not check_condition(cond, config, rules):
-			return random_choices(config, rules, start_index + 1)
+	if cond and not cond.evaluate(config):
+		return random_choices(config, rules, start_index + 1)
 
 	# Remember previous choices for backtracking
@@ -487,5 +559,5 @@
 
 	for varname, vartype, name, choices, cond in rules:
-		if cond and (not check_condition(cond, config, rules)):
+		if cond and not cond.evaluate(config):
 			continue
 
@@ -676,5 +748,5 @@
 				varname, vartype, name, choices, cond = rule
 
-				if cond and (not check_condition(cond, config, rules)):
+				if cond and not cond.evaluate(config):
 					continue
 
Index: tools/ew.py
===================================================================
--- tools/ew.py	(revision c878693123930f0906703462cf2807430679517e)
+++ tools/ew.py	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -89,4 +89,22 @@
 	return '-cpu 4Kc'
 
+def find_firmware(name, environ_var, default_paths, extra_info=None):
+	"""Find firmware image(s)."""
+
+	if environ_var in os.environ:
+		return os.environ[environ_var]
+
+	for path in default_paths:
+		if os.path.exists(path):
+			return path
+
+	sys.stderr.write("Cannot find %s binary image(s)!\n" % name)
+	sys.stderr.write(
+	    "Either set %s environment variable accordingly or place the image(s) in one of the default locations: %s.\n" %
+	    (environ_var, ", ".join(default_paths)))
+	if extra_info is not None:
+		sys.stderr.write(extra_info)
+	return None
+
 def platform_to_qemu_options(platform, machine, processor):
 	if platform == 'amd64':
@@ -94,4 +112,20 @@
 	elif platform == 'arm32':
 		return 'system-arm', '-M integratorcp'
+	elif platform == 'arm64':
+		# Search for the EDK2 firmware image
+		default_paths = (
+			'/usr/local/qemu-efi-aarch64/QEMU_EFI.fd', # Custom
+			'/usr/share/edk2/aarch64/QEMU_EFI.fd',     # Fedora
+			'/usr/share/qemu-efi-aarch64/QEMU_EFI.fd', # Ubuntu
+		)
+		extra_info = ("Pre-compiled binary can be obtained from "
+		    "http://snapshots.linaro.org/components/kernel/leg-virt-tianocore-edk2-upstream/latest/QEMU-AARCH64/RELEASE_GCC49/QEMU_EFI.fd.\n")
+		efi_path = find_firmware(
+		    "EDK2", 'EW_QEMU_EFI_AARCH64', default_paths, extra_info)
+		if efi_path is None:
+			raise Exception
+
+		return 'system-aarch64', \
+		    '-M virt -cpu cortex-a57 -m 1024 -bios %s' % efi_path
 	elif platform == 'ia32':
 		return 'system-i386', pc_options(32)
@@ -108,16 +142,10 @@
 		if processor == 'us':
 			return 'system-sparc64', '-M sun4u --prom-env boot-args="console=devices/\\hw\\pci0\\01:01.0\\com1\\a"'
-		elif processor == 'sun4v':
-			default_path = '/usr/local/opensparc/image/'
-		try:
-			if os.path.exists(default_path):
-				opensparc_bins = default_path
-			elif os.path.exists(os.environ['OPENSPARC_BINARIES']):
-				opensparc_bins = os.environ['OPENSPARC_BINARIES']
-			else:
-				raise Exception
-		except:
-			print("Cannot find OpenSPARC binary images!")
-			print("Either set OPENSPARC_BINARIES environment variable accordingly or place the images in %s." % (default_path))
+
+		# processor = 'sun4v'
+		opensparc_bins = find_firmware(
+		    "OpenSPARC", 'OPENSPARC_BINARIES',
+		    ('/usr/local/opensparc/image/', ))
+		if opensparc_bins is None:
 			raise Exception
 
@@ -135,5 +163,12 @@
 	hdisk_mk()
 
-	return ' -drive file=hdisk.img,index=0,media=disk,format=raw'
+	hdd_options = ''
+	if 'hdd' in overrides.keys():
+		if 'ata' in overrides['hdd'].keys():
+			hdd_options += ''
+		elif 'virtio-blk' in overrides['hdd'].keys():
+			hdd_options += ',if=virtio'
+
+	return ' -drive file=hdisk.img,index=0,media=disk,format=raw' + hdd_options
 
 def qemu_nic_ne2k_options():
@@ -201,6 +236,6 @@
 		cmdline += ' ' + options
 
-	cmdline += qemu_bd_options()
-
+	if (not 'hdd' in cfg.keys() or cfg['hdd']):
+		cmdline += qemu_bd_options()
 	if (not 'net' in cfg.keys()) or cfg['net']:
 		cmdline += qemu_net_options()
@@ -227,4 +262,11 @@
 	if cfg['image'] == 'image.iso':
 		cmdline += ' -boot d -cdrom image.iso'
+	elif cfg['image'] == 'image.iso@arm64':
+		# Define image.iso cdrom backend.
+		cmdline += ' -drive if=none,file=image.iso,id=cdrom,media=cdrom'
+		# Define scsi bus.
+		cmdline += ' -device virtio-scsi-device'
+		# Define cdrom frontend connected to this scsi bus.
+		cmdline += ' -device scsi-cd,drive=cdrom'
 	elif cfg['image'] == 'image.boot':
 		cmdline += ' -kernel image.boot'
@@ -269,4 +311,17 @@
 			'xhci' : False,
 			'tablet' : False
+		}
+	},
+	'arm64' : {
+		'virt' : {
+			'run' : qemu_run,
+			'image' : 'image.iso@arm64',
+			'audio' : False,
+			'console' : True,
+			'hdd' : False,
+			'net' : False,
+			'tablet' : False,
+			'usb' : False,
+			'xhci' : False
 		}
 	},
@@ -336,5 +391,5 @@
 def usage():
 	print("%s - emulator wrapper for running HelenOS\n" % os.path.basename(sys.argv[0]))
-	print("%s [-d] [-h] [-net e1k|rtl8139|ne2k|virtio-net] [-nohdd] [-nokvm] [-nonet] [-nosnd] [-nousb] [-noxhci] [-notablet]\n" %
+	print("%s [-d] [-h] [-net e1k|rtl8139|ne2k|virtio-net] [-hdd ata|virtio-blk] [-nohdd] [-nokvm] [-nonet] [-nosnd] [-nousb] [-noxhci] [-notablet]\n" %
 	    os.path.basename(sys.argv[0]))
 	print("-d\tDry run: do not run the emulation, just print the command line.")
@@ -357,4 +412,5 @@
 def run():
 	expect_nic = False
+	expect_hdd = False
 	expect_qemu = False
 
@@ -378,4 +434,17 @@
 			continue
 
+		if expect_hdd:
+			expect_hdd = False
+			if not 'hdd' in overrides.keys():
+				overrides['hdd'] = {}
+			if sys.argv[i] == 'ata':
+				overrides['hdd']['ata'] = True
+			elif sys.argv[i] == 'virtio-blk':
+				overrides['hdd']['virtio-blk'] = True
+			else:
+				usage()
+				exit()
+			continue
+
 		if expect_qemu:
 			expect_qemu = False
@@ -389,4 +458,6 @@
 		elif sys.argv[i] == '-net' and i < len(sys.argv) - 1:
 			expect_nic = True
+		elif sys.argv[i] == '-hdd' and i < len(sys.argv) - 1:
+			expect_hdd = True
 		elif sys.argv[i] == '-nohdd':
 			overrides['nohdd'] = True
Index: tools/grub/grub-update.sh
===================================================================
--- tools/grub/grub-update.sh	(revision c878693123930f0906703462cf2807430679517e)
+++ tools/grub/grub-update.sh	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -40,10 +40,15 @@
 grub_rev="bc220962e366b1b46769ed6f9fa5be603ba58ab5"
 
+build_ia32amd64_pc=false
+build_ia32amd64_efi=false
+build_arm64_efi=false
+
 function grub_build()
 {
-	target="$1"
-	platform="$2"
+	platform="$1"
+	conf_target="$2"
+	conf_platform="$3"
 
-	./configure --prefix="$builddir/$target-$platform" --target="$target" --with-platform="$platform" --disable-werror || exit 1
+	./configure --prefix="$builddir/$platform" --target="$conf_target" --with-platform="$conf_platform" --disable-werror || exit 1
 	make clean || exit 1
 	make install || exit 1
@@ -55,10 +60,52 @@
 	platform="$2"
 
-	rm -rf "$helenosdir"/boot/"$gdir"/"$platform" || exit 1
-	cp -R "$builddir"/"$platform"/lib64/grub/"$platform" "$helenosdir"/boot/"$gdir" || exit 1
-	rm -f "$helenosdir"/boot/"$gdir"/"$platform"/*.image || exit 1
-	rm -f "$helenosdir"/boot/"$gdir"/"$platform"/*.module || exit 1
-	git add "$helenosdir"/boot/"$gdir"/"$platform" || exit 1
+	echo "$grub_rev" > "$helenosdir"/boot/grub/"$gdir"/REVISION || exit 1
+	rm -rf "$helenosdir"/boot/grub/"$gdir"/"$platform" || exit 1
+	cp -R "$builddir"/"$platform"/lib*/grub/"$platform" "$helenosdir"/boot/grub/"$gdir" || exit 1
+	rm -f "$helenosdir"/boot/grub/"$gdir"/"$platform"/*.image || exit 1
+	rm -f "$helenosdir"/boot/grub/"$gdir"/"$platform"/*.module || exit 1
+	git add "$helenosdir"/boot/grub/"$gdir"/"$platform" || exit 1
 }
+
+function show_usage()
+{
+	echo "Script to generate/update prebuild Grub2 in HelenOS source tree"
+	echo
+	echo "Syntax:"
+	echo " $0 <target>"
+	echo
+	echo "Possible targets are:"
+	echo " ia32+amd64-pc"
+	echo " ia32+amd64-efi"
+	echo " arm64-efi"
+	echo " all             build all targets"
+	echo
+
+	exit 3
+}
+
+if [ "$#" -ne "1" ] ; then
+	show_usage
+fi
+
+case "$1" in
+	ia32+amd64-pc)
+		build_ia32amd64_pc=true
+		;;
+	ia32+amd64-efi)
+		build_ia32amd64_efi=true
+		;;
+	arm64-efi)
+		build_arm64_efi=true
+		;;
+	all)
+		build_ia32amd64_pc=true
+		build_ia32amd64_efi=true
+		build_arm64_efi=true
+		;;
+	*)
+		show_usage
+		;;
+esac
 
 # Prepare a clone of Grub2 repo
@@ -72,41 +119,68 @@
 git reset --hard "$grub_rev" || exit 1
 
-echo "$grub_rev" >"$helenosdir"/boot/grub.pc/REVISION || exit 1
-echo "$grub_rev" > "$helenosdir"/boot/grub.efi/REVISION || exit 1
+./autogen.sh || exit 1
 
-# Build each platform to a different directory
-./autogen.sh || exit 1
-grub_build i386 pc
-grub_build i386 efi
-grub_build x86_64 efi
+if $build_ia32amd64_pc ; then
+	cd "$workdir" || exit 1
+	grub_build i386-pc i386 pc
 
-# Extract El Torrito boot image for i386-pc
-cd "$helenosdir"/boot/grub.pc || exit 1
-rm -f pc.img || exit 1
-"$builddir"/i386-pc/bin/grub-mkrescue -o phony --xorriso="$origdir/getimage.sh" || exit 1
+	# Extract El Torrito boot image for i386-pc
+	cd "$helenosdir"/boot/grub/ia32-pc || exit 1
+	rm -f pc.img || exit 1
+	"$builddir"/i386-pc/bin/grub-mkrescue -o phony --xorriso="$origdir/getimage.sh" || exit 1
 
-# Extract El Torrito boot image for i386-efi
-cd "$helenosdir"/boot/grub.efi || exit 1
-rm -f efi.img.gz || exit 1
-"$builddir"/i386-efi/bin/grub-mkrescue -o phony --xorriso="$origdir/getimage.sh" || exit 1
-mv efi.img i386-efi.img
+	grub_files_update ia32-pc i386-pc
+fi
 
-# Extract El Torrito boot image for x86_64-efi
-cd "$helenosdir"/boot/grub.efi || exit 1
-rm -f efi.img.gz || exit 1
-"$builddir"/x86_64-efi/bin/grub-mkrescue -o phony --xorriso="$origdir/getimage.sh" || exit 1
+if $build_ia32amd64_efi ; then
+	cd "$workdir" || exit 1
 
-# Combine El Torrito boot images for x86_64-efi and i386-efi
-mkdir tmp || exit 1
-mcopy -ns -i i386-efi.img ::efi tmp || exit 1
-mcopy -s -i efi.img tmp/* :: || exit 1
-gzip efi.img || exit 1
-rm -rf tmp || exit 1
-rm -f i386-efi.img || exit 1
+	# Build each platform to a different directory
+	grub_build i386-efi i386 efi
+	grub_build x86_64-efi x86_64 efi
 
-# Update Grub files for all platforms
-grub_files_update grub.pc i386-pc
-grub_files_update grub.efi i386-efi
-grub_files_update grub.efi x86_64-efi
+	# Extract El Torrito boot image for i386-efi
+	cd "$helenosdir"/boot/grub/ia32-efi || exit 1
+	rm -f efi.img.gz || exit 1
+	"$builddir"/i386-efi/bin/grub-mkrescue -o phony --xorriso="$origdir/getimage.sh" || exit 1
+	mv efi.img i386-efi.img
+
+	# Extract El Torrito boot image for x86_64-efi
+	cd "$helenosdir"/boot/grub/ia32-efi || exit 1
+	rm -f efi.img.gz || exit 1
+	"$builddir"/x86_64-efi/bin/grub-mkrescue -o phony --xorriso="$origdir/getimage.sh" || exit 1
+
+	# Combine El Torrito boot images for x86_64-efi and i386-efi
+	mkdir tmp || exit 1
+	mcopy -ns -i i386-efi.img ::efi tmp || exit 1
+	mcopy -s -i efi.img tmp/* :: || exit 1
+	gzip efi.img || exit 1
+	rm -rf tmp || exit 1
+	rm -f i386-efi.img || exit 1
+
+	# Update Grub files for all platforms
+	grub_files_update ia32-efi i386-efi
+	grub_files_update ia32-efi x86_64-efi
+fi
+
+if $build_arm64_efi ; then
+	cd "$workdir" || exit 1
+
+	# Check that the expected compiler is present on PATH
+	if ! [ -x "$(command -v aarch64-linux-gnu-gcc)" ] ; then
+		echo "Error: aarch64-linux-gnu-gcc is missing" >&2
+		exit 1
+	fi
+
+	grub_build arm64-efi aarch64-linux-gnu efi
+
+	# Extract El Torrito boot image for arm64-efi
+	cd "$helenosdir"/boot/grub/arm64-efi || exit 1
+	rm -f efi.img.gz || exit 1
+	"$builddir"/arm64-efi/bin/grub-mkrescue -o phony --xorriso="$origdir/getimage.sh" || exit 1
+	gzip efi.img || exit 1
+
+	grub_files_update arm64-efi arm64-efi
+fi
 
 echo "GRUB update successful."
Index: tools/grub/mkimage.sh
===================================================================
--- tools/grub/mkimage.sh	(revision c878693123930f0906703462cf2807430679517e)
+++ tools/grub/mkimage.sh	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,5 +39,5 @@
 orig_dir="$(cd "$(dirname "$0")" && pwd)"
 grub_tools_dir="$orig_dir/grub-build/i386-pc/bin"
-grub_mod_dir="$orig_dir/../../boot/grub.pc/i386-pc"
+grub_mod_dir="$orig_dir/../../boot/grub/ia32-pc/i386-pc"
 
 "$grub_tools_dir"/grub-mkimage --directory "$grub_mod_dir" \
Index: tools/toolchain.sh
===================================================================
--- tools/toolchain.sh	(revision c878693123930f0906703462cf2807430679517e)
+++ tools/toolchain.sh	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -61,8 +61,10 @@
 	echo "Syntax:"
 	echo " $0 [--no-install] [--non-helenos-target] <platform>"
+	echo " $0 --test-version [<platform>]"
 	echo
 	echo "Possible target platforms are:"
 	echo " amd64      AMD64 (x86-64, x64)"
 	echo " arm32      ARM 32b"
+	echo " arm64      AArch64"
 	echo " ia32       IA-32 (x86, i386)"
 	echo " ia64       IA-64 (Itanium)"
@@ -95,4 +97,66 @@
 }
 
+test_version() {
+	echo "Cross-compiler toolchain build script"
+	echo
+	echo "Start testing the version of the installed software" 
+	echo
+	
+	if [ -z "$1" ] || [ "$1" == "all" ] ; then
+		PLATFORMS=("amd64" "arm32" "arm64" "ia32" "ia64" "mips32" "mips32eb" "ppc32" "riscv64" "sparc64")
+	else
+		PLATFORMS=("$1")
+	fi
+	
+	
+	if [ -z "${CROSS_PREFIX}" ] ; then
+		CROSS_PREFIX="/usr/local/cross"
+	fi
+
+	for i in "${PLATFORMS[@]}"
+	do
+		PLATFORM="$i"
+		set_target_from_platform "$PLATFORM"
+		PREFIX="${CROSS_PREFIX}/bin/${HELENOS_TARGET}"
+
+		echo "== $PLATFORM =="
+		test_app_version "Binutils" "ld" "GNU\ ld\ \(GNU\ Binutils\)\ ((\.|[0-9])+)" "$BINUTILS_VERSION"
+		test_app_version "GCC" "gcc" "gcc\ version\ ((\.|[0-9])+)" "$GCC_VERSION"
+		test_app_version "GDB" "gdb" "GNU\ gdb\ \(GDB\)\s+((\.|[0-9])+)" "$GDB_VERSION"
+	done
+
+	exit
+}
+
+test_app_version() {
+	PKGNAME="$1"
+	APPNAME="$2"
+	REGEX="$3"
+	INS_VERSION="$4"
+
+
+	APP="${PREFIX}-${APPNAME}"
+	if [ ! -e $APP ]; then
+		echo "- $PKGNAME is missing"
+	else
+		{
+			OUT=$(${APP} -v 2>&1)
+		} &> /dev/null
+
+		if [[ "$OUT" =~ $REGEX ]]; then
+	        VERSION="${BASH_REMATCH[1]}"
+	        if [ "$INS_VERSION" = "$VERSION" ]; then
+	        	echo "+ $PKGNAME is uptodate ($INS_VERSION)"
+	        else
+	        	echo "- $PKGNAME ($VERSION) is outdated ($INS_VERSION)"
+	        fi
+	    else
+	        echo "- $PKGNAME Unexpected output"
+	    fi
+	fi
+}
+
+
+
 change_title() {
 	echo -en "\e]0;$1\a"
@@ -212,4 +276,7 @@
 		"arm32")
 			GNU_ARCH="arm"
+			;;
+		"arm64")
+			GNU_ARCH="aarch64"
 			;;
 		"ia32")
@@ -408,4 +475,8 @@
 while [ "$#" -gt 1 ] ; do
 	case "$1" in
+		--test-version)
+			test_version "$2"
+			exit
+			;;
 		--no-install)
 			REAL_INSTALL=false
@@ -427,5 +498,8 @@
 
 case "$1" in
-	amd64|arm32|ia32|ia64|mips32|mips32eb|ppc32|riscv64|sparc64)
+	--test-version)
+		test_version
+		;;
+	amd64|arm32|arm64|ia32|ia64|mips32|mips32eb|ppc32|riscv64|sparc64)
 		prepare
 		build_target "$1"
@@ -435,4 +509,5 @@
 		build_target "amd64"
 		build_target "arm32"
+		build_target "arm64"
 		build_target "ia32"
 		build_target "ia64"
@@ -447,4 +522,5 @@
 		build_target "amd64"
 		build_target "arm32"
+		build_target "arm64"
 		build_target "ia32"
 		build_target "ia64"
@@ -458,4 +534,5 @@
 		build_target "amd64" &
 		build_target "arm32" &
+		build_target "arm64" &
 		build_target "ia32" &
 		build_target "ia64" &
@@ -473,16 +550,17 @@
 		wait
 
+		build_target "arm64" &
 		build_target "ia32" &
+		wait
+
 		build_target "ia64" &
+		build_target "mips32" &
 		wait
 
-		build_target "mips32" &
 		build_target "mips32eb" &
+		build_target "ppc32" &
 		wait
 
-		build_target "ppc32" &
 		build_target "riscv64" &
-		wait
-
 		build_target "sparc64" &
 		wait
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,5 +38,4 @@
 	app/bithenge \
 	app/blkdump \
-	app/bnchmark \
 	app/contacts \
 	app/corecfg \
@@ -51,4 +50,5 @@
 	app/getterm \
 	app/gunzip \
+	app/hbench \
 	app/init \
 	app/inet \
@@ -58,4 +58,5 @@
 	app/loc \
 	app/logset \
+	app/lprint \
 	app/mixerctl \
 	app/mkfat \
@@ -66,5 +67,5 @@
 	app/netecho \
 	app/nterm \
-	app/perf \
+	app/pci \
 	app/redir \
 	app/sbi \
@@ -151,4 +152,5 @@
 	drv/block/ddisk \
 	drv/block/usbmast \
+	drv/block/virtio-blk \
 	drv/bus/adb/cuda_adb \
 	drv/bus/isa \
@@ -166,4 +168,6 @@
 	drv/char/msim-con \
 	drv/char/ns8250 \
+	drv/char/pc-lpt \
+	drv/char/pl011 \
 	drv/char/pl050 \
 	drv/char/ski-con \
@@ -178,4 +182,5 @@
 	drv/hid/xtkbd \
 	drv/intctl/apic \
+	drv/intctl/gicv2 \
 	drv/intctl/i8259 \
 	drv/intctl/icp-ic \
@@ -188,4 +193,5 @@
 	drv/nic/virtio-net \
 	drv/platform/amdm37x \
+	drv/platform/arm64virt \
 	drv/platform/icp \
 	drv/platform/mac \
@@ -274,4 +280,5 @@
 
 export: $(BUILDS)
+	mkdir -p $(EXPORT_DIR)
 	$(MAKE) -r -C lib/posix export EXPORT_DIR=$(EXPORT_DIR)
 
Index: uspace/Makefile.common
===================================================================
--- uspace/Makefile.common	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/Makefile.common	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -120,6 +120,14 @@
 		STATIC_BUILD = y
 	else
-		ifeq ($(CONFIG_USE_SHARED_LIBS),y)
-			STATIC_BUILD = n
+		ifeq ($(CONFIG_BUILD_SHARED_LIBS),y)
+			ifeq ($(CONFIG_USE_SHARED_LIBS),y)
+				STATIC_BUILD = n
+			else
+				ifeq ($(LIBRARY),)
+					STATIC_BUILD = y
+				else
+					STATIC_BUILD = n
+				endif
+			endif
 		else
 			STATIC_BUILD = y
@@ -300,4 +308,8 @@
 LIBARGS := $(addprefix -L$(USPACE_PREFIX)/lib/, $(LIBS)) $(addprefix -l, $(LIBS))
 
+ifneq ($(LIBRARY),libc)
+	LIBTAGS := $(LIBC_PREFIX)/tag $(LIBTAGS)
+endif
+
 .PHONY: all all-test clean fasterclean depend
 
@@ -369,5 +381,5 @@
 	$(AR) rc $@ $(LOBJECTS)
 
-$(SLIBRARY): $(LIBRARY).la
+$(SLIBRARY): $(LIBRARY).la $(LIBTAGS)
 	$(CC) $(CFLAGS) $(LIB_LDFLAGS) $(EXTRA_LDFLAGS) -Wl,-Map,$@.map -o $@ -Wl,--whole-archive $(LIBRARY).la -Wl,--no-whole-archive $(LIBARGS) $(BASE_LIBS)
 
Index: uspace/app/bdsh/Makefile
===================================================================
--- uspace/app/bdsh/Makefile	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,4 +34,6 @@
 
 SOURCES = \
+	cmds/modules/module_aliases.c \
+	cmds/modules/modules.c \
 	cmds/modules/help/help.c \
 	cmds/modules/mkdir/mkdir.c \
@@ -51,4 +53,6 @@
 	cmds/modules/kcon/kcon.c \
 	cmds/modules/cmp/cmp.c \
+	cmds/builtins/builtin_aliases.c \
+	cmds/builtins/builtins.c \
 	cmds/builtins/batch/batch.c \
 	cmds/builtins/exit/exit.c \
Index: uspace/app/bdsh/cmds/builtins/builtin_aliases.c
===================================================================
--- uspace/app/bdsh/cmds/builtins/builtin_aliases.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/bdsh/cmds/builtins/builtin_aliases.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2008 Tim Post
+ * 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 BUILTIN_ALIASES_H
+#define BUILTIN_ALIASES_H
+
+#include <stdlib.h>
+#include "builtin_aliases.h"
+
+/* See modules/module_aliases.h for an explanation of this file */
+
+char *builtin_aliases[] = {
+	NULL, NULL
+};
+
+#endif
Index: uspace/app/bdsh/cmds/builtins/builtin_aliases.h
===================================================================
--- uspace/app/bdsh/cmds/builtins/builtin_aliases.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/cmds/builtins/builtin_aliases.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,10 +1,34 @@
+/*
+ * Copyright (c) 2008 Tim Post
+ * 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 BUILTIN_ALIASES_H
 #define BUILTIN_ALIASES_H
 
-/* See modules/module_aliases.h for an explanation of this file */
-
-char *builtin_aliases[] = {
-	NULL, NULL
-};
+extern char *builtin_aliases[];
 
 #endif
Index: uspace/app/bdsh/cmds/builtins/builtins.c
===================================================================
--- uspace/app/bdsh/cmds/builtins/builtins.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/bdsh/cmds/builtins/builtins.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2008 Tim Post
+ * 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 <stdlib.h>
+#include "builtins.h"
+
+#include "batch/entry.h"
+#include "cd/entry.h"
+#include "exit/entry.h"
+
+builtin_t builtins[] = {
+#include "batch/batch_def.inc"
+#include "cd/cd_def.inc"
+#include "exit/exit_def.inc"
+	{ NULL, NULL, NULL, NULL, 0 }
+};
Index: uspace/app/bdsh/cmds/builtins/builtins.h
===================================================================
--- uspace/app/bdsh/cmds/builtins/builtins.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/cmds/builtins/builtins.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,17 +1,36 @@
+/*
+ * Copyright (c) 2008 Tim Post
+ * 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 BUILTINS_H
 #define BUILTINS_H
 
-#include "config.h"
+#include "../cmds.h"
 
-#include "batch/entry.h"
-#include "cd/entry.h"
-#include "exit/entry.h"
-
-builtin_t builtins[] = {
-#include "batch/batch_def.inc"
-#include "cd/cd_def.inc"
-#include "exit/exit_def.inc"
-	{ NULL, NULL, NULL, NULL, 0 }
-};
+extern builtin_t builtins[];
 
 #endif
Index: uspace/app/bdsh/cmds/mknewcmd
===================================================================
--- uspace/app/bdsh/cmds/mknewcmd	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/cmds/mknewcmd	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -213,5 +213,5 @@
 	printf " to include your new command.\n"
 	[ -n "$CMDALIAS" ] &&  {
-		printf "\nYou should also modify %ss/%s_aliases.h and " \
+		printf "\nYou should also modify %ss/%s_aliases.c and " \
 			"${CMDTYPE}" "${CMDTYPE}"
 		printf "add %s as an alias for %s\n" \
Index: uspace/app/bdsh/cmds/modules/ls/ls.c
===================================================================
--- uspace/app/bdsh/cmds/modules/ls/ls.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/cmds/modules/ls/ls.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -267,5 +267,5 @@
 
 	/* Populate the directory list. */
-	if (ls.recursive) {
+	if (ls.recursive && nbdirs > 0) {
 		tmp = (struct dir_elem_t *) realloc(*dir_list_ptr,
 		    nbdirs * sizeof(struct dir_elem_t));
Index: uspace/app/bdsh/cmds/modules/module_aliases.c
===================================================================
--- uspace/app/bdsh/cmds/modules/module_aliases.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/bdsh/cmds/modules/module_aliases.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2008 Tim Post
+ * 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 <stdlib.h>
+#include "module_aliases.h"
+
+/*
+ * Modules that declare multiple names for themselves but use the
+ * same entry functions are aliases. This array helps to determine if
+ * a module is an alias, as such it can be invoked differently.
+ * format is alias , real_name
+ */
+
+/*
+ * So far, this is only used in the help display but could be used to
+ * handle a module differently even prior to reaching its entry code.
+ * For instance, 'exit' could behave differently than 'quit', prior to
+ * the entry point being reached.
+ */
+
+const char *mod_aliases[] = {
+	"ren", "mv",
+	"umount", "unmount",
+	NULL, NULL
+};
Index: uspace/app/bdsh/cmds/modules/module_aliases.h
===================================================================
--- uspace/app/bdsh/cmds/modules/module_aliases.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/cmds/modules/module_aliases.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,23 +30,5 @@
 #define MODULE_ALIASES_H
 
-/*
- * Modules that declare multiple names for themselves but use the
- * same entry functions are aliases. This array helps to determine if
- * a module is an alias, as such it can be invoked differently.
- * format is alias , real_name
- */
-
-/*
- * So far, this is only used in the help display but could be used to
- * handle a module differently even prior to reaching its entry code.
- * For instance, 'exit' could behave differently than 'quit', prior to
- * the entry point being reached.
- */
-
-const char *mod_aliases[] = {
-	"ren", "mv",
-	"umount", "unmount",
-	NULL, NULL
-};
+extern const char *mod_aliases[];
 
 #endif
Index: uspace/app/bdsh/cmds/modules/modules.c
===================================================================
--- uspace/app/bdsh/cmds/modules/modules.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/bdsh/cmds/modules/modules.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2008 Tim Post
+ * 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.
+ */
+
+/*
+ * Each built in function has two files, one being an entry.h file which
+ * prototypes the run/help entry functions, the other being a .def file
+ * which fills the modules[] array according to the cmd_t structure
+ * defined in cmds.h.
+ *
+ * To add or remove a module, just make a new directory in cmds/modules
+ * for it and copy the 'show' example for basics, then include it here.
+ * (or reverse the process to remove one)
+ *
+ * NOTE: See module_ aliases.h as well, this is where aliases (commands that
+ * share an entry point with others) are indexed
+ */
+
+#include "config.h"
+#include "modules.h"
+
+/* Prototypes for each module's entry (help/exec) points */
+
+#include "help/entry.h"
+#include "mkdir/entry.h"
+#include "mkfile/entry.h"
+#include "rm/entry.h"
+#include "cat/entry.h"
+#include "touch/entry.h"
+#include "ls/entry.h"
+#include "pwd/entry.h"
+#include "sleep/entry.h"
+#include "cp/entry.h"
+#include "mv/entry.h"
+#include "mount/entry.h"
+#include "unmount/entry.h"
+#include "kcon/entry.h"
+#include "printf/entry.h"
+#include "echo/entry.h"
+#include "cmp/entry.h"
+
+/*
+ * Each .def function fills the module_t struct with the individual name, entry
+ * point, help entry point, etc. You can use config.h to control what modules
+ * are loaded based on what libraries exist on the system.
+ */
+
+module_t modules[] = {
+#include "help/help_def.inc"
+#include "mkdir/mkdir_def.inc"
+#include "mkfile/mkfile_def.inc"
+#include "rm/rm_def.inc"
+#include "cat/cat_def.inc"
+#include "touch/touch_def.inc"
+#include "ls/ls_def.inc"
+#include "pwd/pwd_def.inc"
+#include "sleep/sleep_def.inc"
+#include "cp/cp_def.inc"
+#include "mv/mv_def.inc"
+#include "mount/mount_def.inc"
+#include "unmount/unmount_def.inc"
+#include "kcon/kcon_def.inc"
+#include "printf/printf_def.inc"
+#include "echo/echo_def.inc"
+#include "cmp/cmp_def.inc"
+
+	{ NULL, NULL, NULL, NULL }
+};
Index: uspace/app/bdsh/cmds/modules/modules.h
===================================================================
--- uspace/app/bdsh/cmds/modules/modules.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/cmds/modules/modules.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,67 +30,8 @@
 #define MODULES_H
 
-/*
- * Each built in function has two files, one being an entry.h file which
- * prototypes the run/help entry functions, the other being a .def file
- * which fills the modules[] array according to the cmd_t structure
- * defined in cmds.h.
- *
- * To add or remove a module, just make a new directory in cmds/modules
- * for it and copy the 'show' example for basics, then include it here.
- * (or reverse the process to remove one)
- *
- * NOTE: See module_ aliases.h as well, this is where aliases (commands that
- * share an entry point with others) are indexed
- */
+#include "../cmds.h"
+#include "modules.h"
 
-#include "config.h"
-
-/* Prototypes for each module's entry (help/exec) points */
-
-#include "help/entry.h"
-#include "mkdir/entry.h"
-#include "mkfile/entry.h"
-#include "rm/entry.h"
-#include "cat/entry.h"
-#include "touch/entry.h"
-#include "ls/entry.h"
-#include "pwd/entry.h"
-#include "sleep/entry.h"
-#include "cp/entry.h"
-#include "mv/entry.h"
-#include "mount/entry.h"
-#include "unmount/entry.h"
-#include "kcon/entry.h"
-#include "printf/entry.h"
-#include "echo/entry.h"
-#include "cmp/entry.h"
-
-/*
- * Each .def function fills the module_t struct with the individual name, entry
- * point, help entry point, etc. You can use config.h to control what modules
- * are loaded based on what libraries exist on the system.
- */
-
-module_t modules[] = {
-#include "help/help_def.inc"
-#include "mkdir/mkdir_def.inc"
-#include "mkfile/mkfile_def.inc"
-#include "rm/rm_def.inc"
-#include "cat/cat_def.inc"
-#include "touch/touch_def.inc"
-#include "ls/ls_def.inc"
-#include "pwd/pwd_def.inc"
-#include "sleep/sleep_def.inc"
-#include "cp/cp_def.inc"
-#include "mv/mv_def.inc"
-#include "mount/mount_def.inc"
-#include "unmount/unmount_def.inc"
-#include "kcon/kcon_def.inc"
-#include "printf/printf_def.inc"
-#include "echo/echo_def.inc"
-#include "cmp/cmp_def.inc"
-
-	{ NULL, NULL, NULL, NULL }
-};
+extern module_t modules[];
 
 #endif
Index: uspace/app/bdsh/cmds/modules/sleep/sleep.c
===================================================================
--- uspace/app/bdsh/cmds/modules/sleep/sleep.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/cmds/modules/sleep/sleep.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,6 +27,6 @@
  */
 
-#include <async.h>
 #include <errno.h>
+#include <fibril.h>
 #include <stdio.h>
 #include <stdlib.h>
Index: uspace/app/bdsh/compl.c
===================================================================
--- uspace/app/bdsh/compl.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/compl.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -40,4 +40,5 @@
 #include "exec.h"
 #include "tok.h"
+#include "util.h"
 
 static errno_t compl_init(wchar_t *text, size_t pos, size_t *cstart, void **state);
@@ -209,6 +210,4 @@
 		}
 		*cstart += rpath_sep + 1 - prefix;
-		free(prefix);
-		prefix = NULL;
 
 		cs->path_list = malloc(sizeof(char *) * 2);
@@ -217,5 +216,22 @@
 			goto error;
 		}
-		cs->path_list[0] = dirname;
+
+		if (!is_path(prefix) && cs->is_command) {
+			cs->path_list[0] = malloc(sizeof(char) * PATH_MAX);
+			if (cs->path_list[0] == NULL) {
+				retval = ENOMEM;
+				goto error;
+			}
+
+			int ret = snprintf(cs->path_list[0], PATH_MAX, "%s/%s", search_dir[0], dirname);
+			if (ret < 0 || ret >= PATH_MAX) {
+				retval = ENOMEM;
+				goto error;
+			}
+		} else {
+			cs->path_list[0] = dirname;
+		}
+
+		free(prefix);
 		cs->path_list[1] = NULL;
 		/*
Index: uspace/app/bdsh/exec.c
===================================================================
--- uspace/app/bdsh/exec.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/exec.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -47,8 +47,5 @@
 #include "errors.h"
 
-/* FIXME: Just have find_command() return an allocated string */
-static char *found;
-
-static char *find_command(char *);
+static errno_t find_command(char *, char **);
 static int try_access(const char *);
 
@@ -68,30 +65,48 @@
 }
 
-/** Returns the full path of "cmd" if cmd is found
+/** Returns EOK if no internal failure or else ENOMEM
  *
- * else just hand back cmd as it was presented
+ * When the parameter `cmd` can be found then the absolute path will be set in `found`.
+ * Or else `found` will be NULL.
+ * `found` will be newly allocated and must be freed by the caller
  */
-static char *find_command(char *cmd)
+static errno_t find_command(char *cmd, char **found)
 {
-	size_t i;
+	/* The user has specified a full or relative path, just give it back. */
+	if (is_path(cmd)) {
+		if (-1 != try_access(cmd)) {
+			*found = str_dup(cmd);
+			return EOK;
+		}
 
-	found = (char *)malloc(PATH_MAX);
+		*found = NULL;
+		return EOK;
+	}
 
-	/* The user has specified a full or relative path, just give it back. */
-	if (-1 != try_access(cmd)) {
-		return (char *) cmd;
+	*found = (char *)malloc(PATH_MAX);
+	if (*found == NULL) {
+		return ENOMEM;
 	}
 
 	/* We now have n places to look for the command */
+	size_t i;
+	size_t cmd_length = str_length(cmd);
 	for (i = 0; search_dir[i] != NULL; i++) {
-		memset(found, 0, PATH_MAX);
-		snprintf(found, PATH_MAX, "%s/%s", search_dir[i], cmd);
-		if (-1 != try_access(found)) {
-			return (char *) found;
+		if (str_length(search_dir[i]) + cmd_length + 2 > PATH_MAX) {
+			free(*found);
+			return ENOMEM;
+		}
+
+		memset(*found, 0, PATH_MAX);
+		snprintf(*found, PATH_MAX, "%s/%s", search_dir[i], cmd);
+		if (-1 != try_access(*found)) {
+			return EOK;
 		}
 	}
+	free(*found);
+	*found = NULL;
 
-	/* We didn't find it, just give it back as-is. */
-	return (char *) cmd;
+	/* We didn't find it, return NULL */
+	return EOK;
 }
 
@@ -107,6 +122,14 @@
 	FILE *files[3];
 
-	tmp = str_dup(find_command(cmd));
-	free(found);
+	rc = find_command(cmd, &tmp);
+	if (rc != EOK) {
+		cli_error(CL_ENOMEM, "%s: failure executing find_command()", progname);
+		return 1;
+	}
+
+	if (tmp == NULL) {
+		cli_error(CL_EEXEC, "%s: Command not found '%s'", progname, cmd);
+		return 1;
+	}
 
 	files[0] = io->stdin;
Index: uspace/app/bdsh/util.c
===================================================================
--- uspace/app/bdsh/util.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/util.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -74,2 +74,15 @@
 	return 0;
 }
+
+/*
+ * Returns true if the string is a relative or an absolute path
+ */
+bool is_path(const char *cmd)
+{
+
+	bool ret = str_lcmp(cmd, "/", 1) == 0;
+	ret = ret || str_lcmp(cmd, "./", 2) == 0;
+	ret = ret || str_lcmp(cmd, "../", 3) == 0;
+
+	return ret;
+}
Index: uspace/app/bdsh/util.h
===================================================================
--- uspace/app/bdsh/util.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/util.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,8 +31,10 @@
 
 #include "scli.h"
+#include <stdbool.h>
 
 /* Utility functions */
 extern unsigned int cli_count_args(char **);
 extern unsigned int cli_set_prompt(cliuser_t *usr);
+extern bool is_path(const char *cmd);
 
 #endif
Index: pace/app/bnchmark/Makefile
===================================================================
--- uspace/app/bnchmark/Makefile	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,35 +1,0 @@
-#
-# Copyright (c) 2011 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.
-#
-
-USPACE_PREFIX = ../..
-BINARY = bnchmark
-
-SOURCES = \
-	bnchmark.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: pace/app/bnchmark/bnchmark.c
===================================================================
--- uspace/app/bnchmark/bnchmark.c	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,213 +1,0 @@
-/*
- * Copyright (c) 2011 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 bnchmark
- * @{
- */
-
-/**
- * @file	bnchmark.c
- * This program measures time for various actions and writes the results
- * to a file.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <str_error.h>
-#include <mem.h>
-#include <loc.h>
-#include <byteorder.h>
-#include <inttypes.h>
-#include <errno.h>
-#include <time.h>
-#include <dirent.h>
-#include <str.h>
-
-#define NAME	"bnchmark"
-#define BUFSIZE 8096
-#define MBYTE (1024*1024)
-
-typedef errno_t (*measure_func_t)(void *);
-
-static void syntax_print(void);
-
-static errno_t measure(measure_func_t fn, void *data, msec_t *result)
-{
-	struct timespec start_time;
-	getuptime(&start_time);
-
-	errno_t rc = fn(data);
-	if (rc != EOK) {
-		fprintf(stderr, "measured function failed\n");
-		return rc;
-	}
-
-	struct timespec final_time;
-	getuptime(&final_time);
-
-	/* Calculate time difference in milliseconds */
-	*result = NSEC2USEC(ts_sub_diff(&final_time, &start_time));
-	return EOK;
-}
-
-static errno_t sequential_read_file(void *data)
-{
-	char *path = (char *) data;
-	char *buf = malloc(BUFSIZE);
-
-	if (buf == NULL)
-		return ENOMEM;
-
-	FILE *file = fopen(path, "r");
-	if (file == NULL) {
-		fprintf(stderr, "Failed opening file: %s\n", path);
-		free(buf);
-		return EIO;
-	}
-
-	while (!feof(file)) {
-		fread(buf, 1, BUFSIZE, file);
-		if (ferror(file)) {
-			fprintf(stderr, "Failed reading file\n");
-			fclose(file);
-			free(buf);
-			return EIO;
-		}
-	}
-
-	fclose(file);
-	free(buf);
-	return EOK;
-}
-
-static errno_t sequential_read_dir(void *data)
-{
-	char *path = (char *) data;
-
-	DIR *dir = opendir(path);
-	if (dir == NULL) {
-		fprintf(stderr, "Failed opening directory: %s\n", path);
-		return EIO;
-	}
-
-	struct dirent *dp;
-
-	while ((dp = readdir(dir))) {
-		/* Do nothing */
-	}
-
-	closedir(dir);
-	return EOK;
-}
-
-int main(int argc, char **argv)
-{
-	errno_t rc;
-	msec_t milliseconds_taken = 0;
-	char *path = NULL;
-	measure_func_t fn = NULL;
-	int iteration;
-	int iterations;
-	char *log_str = NULL;
-	char *test_type = NULL;
-	char *endptr;
-
-	if (argc < 5) {
-		fprintf(stderr, NAME ": Error, argument missing.\n");
-		syntax_print();
-		return 1;
-	}
-
-	if (argc > 5) {
-		fprintf(stderr, NAME ": Error, too many arguments.\n");
-		syntax_print();
-		return 1;
-	}
-
-	// Skip program name
-	--argc;
-	++argv;
-
-	iterations = strtol(*argv, &endptr, 10);
-	if (*endptr != '\0') {
-		printf(NAME ": Error, invalid argument (iterations).\n");
-		syntax_print();
-		return 1;
-	}
-
-	--argc;
-	++argv;
-	test_type = *argv;
-
-	--argc;
-	++argv;
-	log_str = *argv;
-
-	--argc;
-	++argv;
-	path = *argv;
-
-	if (str_cmp(test_type, "sequential-file-read") == 0) {
-		fn = sequential_read_file;
-	} else if (str_cmp(test_type, "sequential-dir-read") == 0) {
-		fn = sequential_read_dir;
-	} else {
-		fprintf(stderr, "Error, unknown test type\n");
-		syntax_print();
-		return 1;
-	}
-
-	for (iteration = 0; iteration < iterations; iteration++) {
-		rc = measure(fn, path, &milliseconds_taken);
-		if (rc != EOK) {
-			fprintf(stderr, "Error: %s\n", str_error(rc));
-			return 1;
-		}
-
-		printf("%s;%s;%s;%lld;ms\n", test_type, path, log_str, milliseconds_taken);
-	}
-
-	return 0;
-}
-
-static void syntax_print(void)
-{
-	fprintf(stderr, "syntax: " NAME " <iterations> <test type> <log-str> <path>\n");
-	fprintf(stderr, "  <iterations>    number of times to run a given test\n");
-	fprintf(stderr, "  <test-type>     one of:\n");
-	fprintf(stderr, "                    sequential-file-read\n");
-	fprintf(stderr, "                    sequential-dir-read\n");
-	fprintf(stderr, "  <log-str>       a string to attach to results\n");
-	fprintf(stderr, "  <path>          file/directory to use for testing\n");
-}
-
-/**
- * @}
- */
Index: pace/app/bnchmark/doc/doxygroups.h
===================================================================
--- uspace/app/bnchmark/doc/doxygroups.h	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,4 +1,0 @@
-/** @addtogroup bnchmark bnchmark
- * @brief Benchmarking application
- * @ingroup apps
- */
Index: uspace/app/contacts/contacts.c
===================================================================
--- uspace/app/contacts/contacts.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/contacts/contacts.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -526,5 +526,5 @@
 {
 	errno_t rc;
-	contacts_t *contacts;
+	contacts_t *contacts = NULL;
 
 	rc = contacts_open("contacts.sif", &contacts);
Index: uspace/app/df/df.c
===================================================================
--- uspace/app/df/df.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/df/df.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -70,5 +70,5 @@
 
 	/* Parse command-line options */
-	while ((optres = getopt(argc, argv, ":ubh")) != -1) {
+	while ((optres = getopt(argc, argv, "ubh")) != -1) {
 		switch (optres) {
 		case 'h':
@@ -78,10 +78,4 @@
 		case 'b':
 			display_blocks = true;
-			break;
-
-		case ':':
-			fprintf(stderr, "Option -%c requires an operand\n",
-			    optopt);
-			errflg++;
 			break;
 
Index: uspace/app/dltest/dltest.c
===================================================================
--- uspace/app/dltest/dltest.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/dltest/dltest.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -91,4 +91,30 @@
 }
 
+/** Test calling function that calls a function that returns a constant */
+static bool test_dlfcn_dl_get_constant_via_call(void)
+{
+	int (*p_dl_get_constant)(void);
+	int val;
+
+	printf("Call dlsym/dl_get_constant_via_call...\n");
+
+	p_dl_get_constant = dlsym(handle, "dl_get_constant_via_call");
+	if (p_dl_get_constant == NULL) {
+		printf("FAILED\n");
+		return false;
+	}
+
+	val = p_dl_get_constant();
+
+	printf("Got %d, expected %d... ", val, dl_constant);
+	if (val != dl_constant) {
+		printf("FAILED\n");
+		return false;
+	}
+
+	printf("Passed\n");
+	return true;
+}
+
 /** Test calling a function that returns contents of a private initialized
  * variable.
@@ -564,4 +590,23 @@
 }
 
+/** Test directly calling function that calls a function that returns a constant */
+static bool test_lnk_dl_get_constant_via_call(void)
+{
+	int val;
+
+	printf("Call linked dl_get_constant_via_call...\n");
+
+	val = dl_get_constant_via_call();
+
+	printf("Got %d, expected %d... ", val, dl_constant);
+	if (val != dl_constant) {
+		printf("FAILED\n");
+		return false;
+	}
+
+	printf("Passed\n");
+	return true;
+}
+
 /** Test dircetly calling a function that returns contents of a private
  * initialized variable.
@@ -853,4 +898,7 @@
 		return 1;
 
+	if (!test_dlfcn_dl_get_constant_via_call())
+		return 1;
+
 	if (!test_dlfcn_dl_get_private_var())
 		return 1;
@@ -905,4 +953,7 @@
 {
 	if (!test_lnk_dl_get_constant())
+		return 1;
+
+	if (!test_lnk_dl_get_constant_via_call())
 		return 1;
 
Index: uspace/app/hbench/Makefile
===================================================================
--- uspace/app/hbench/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2018 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.
+#
+
+USPACE_PREFIX = ../..
+
+LIBS = math
+
+BINARY = hbench
+
+SOURCES = \
+	benchlist.c \
+	csv.c \
+	env.c \
+	main.c \
+	utils.c \
+	fs/dirread.c \
+	fs/fileread.c \
+	ipc/ns_ping.c \
+	ipc/ping_pong.c \
+	malloc/malloc1.c \
+	malloc/malloc2.c \
+	synch/fibril_mutex.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/hbench/benchlist.c
===================================================================
--- uspace/app/hbench/benchlist.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/benchlist.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2018 Jiri Svoboda
+ * Copyright (c) 2018 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 hbench
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdlib.h>
+#include "hbench.h"
+
+benchmark_t *benchmarks[] = {
+	&benchmark_dir_read,
+	&benchmark_fibril_mutex,
+	&benchmark_file_read,
+	&benchmark_malloc1,
+	&benchmark_malloc2,
+	&benchmark_ns_ping,
+	&benchmark_ping_pong
+};
+
+size_t benchmark_count = sizeof(benchmarks) / sizeof(benchmarks[0]);
+
+/** @}
+ */
Index: uspace/app/hbench/csv.c
===================================================================
--- uspace/app/hbench/csv.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/csv.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2019 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 hbench
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "hbench.h"
+
+static FILE *csv_output = NULL;
+
+/** Open CSV benchmark report.
+ *
+ * @param filename Filename where to store the CSV.
+ * @return Whether it was possible to open the file.
+ */
+errno_t csv_report_open(const char *filename)
+{
+	csv_output = fopen(filename, "w");
+	if (csv_output == NULL) {
+		return errno;
+	}
+
+	fprintf(csv_output, "benchmark,run,size,duration_nanos\n");
+
+	return EOK;
+}
+
+/** Add one entry to the report.
+ *
+ * When csv_report_open() was not called or failed, the function does
+ * nothing.
+ *
+ * @param run Performance data of the entry.
+ * @param run_index Run index, use negative values for warm-up.
+ * @param bench Benchmark information.
+ * @param workload_size Workload size.
+ */
+void csv_report_add_entry(bench_run_t *run, int run_index,
+    benchmark_t *bench, uint64_t workload_size)
+{
+	if (csv_output == NULL) {
+		return;
+	}
+
+	fprintf(csv_output, "%s,%d,%" PRIu64 ",%lld\n",
+	    bench->name, run_index, workload_size,
+	    (long long) stopwatch_get_nanos(&run->stopwatch));
+}
+
+/** Close CSV report.
+ *
+ * When csv_report_open() was not called or failed, the function does
+ * nothing.
+ */
+void csv_report_close(void)
+{
+	if (csv_output != NULL) {
+		fclose(csv_output);
+	}
+}
+
+/** @}
+ */
Index: uspace/app/hbench/doc/doxygroups.h
===================================================================
--- uspace/app/hbench/doc/doxygroups.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/doc/doxygroups.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,44 @@
+/** @addtogroup hbench hbench
+ * @brief User space benchmarks
+ * @ingroup apps
+ *
+ * @details
+ *
+ * To add a new benchmark, you need to implement the actual benchmarking
+ * code and register it.
+ *
+ * Registration is done by adding
+ * <code>extern benchmark_t bench_YOUR_NAME</code> reference to benchlist.h
+ * and by adding it to the array in benchlist.c.
+ *
+ * The actual benchmark should reside in a separate file (see malloc/malloc1.c
+ * for example) and has to (at least) declare one function (the actual
+ * benchmark) and fill-in the benchmark_t structure.
+ *
+ * Fill-in the name of the benchmark, its description and a reference to the
+ * benchmark function to the benchmark_t.
+ *
+ * The benchmarking function has to accept trhee arguments:
+ *  @li bench_env_t: benchmark environment configuration
+ *  @li bench_run_t: call bench_run_start and bench_run_stop around the
+ *      actual benchmarking code
+ *  @li uint64_t: size of the workload - typically number of inner loops in
+ *      your benchmark (used to self-calibrate benchmark size)
+ *
+ * Typically, the structure of the function is following:
+ * @code{c}
+ * static bool runnerconst bench_env_t const *envbench_run_t *run, uint64_t size)
+ * {
+ * 	bench_run_start(run);
+ * 	for (uint64_t i = 0; i < size; i++) {
+ * 		// measured action
+ * 		if (something_fails) {
+ * 		    return bench_run_fail(run, "oops: %s (%d)", str_error(rc), rc);
+ * 		}
+ * 	}
+ * 	bench_run_stop(run);
+ *
+ * 	return true;
+ * }
+ * @endcode
+ */
Index: uspace/app/hbench/env.c
===================================================================
--- uspace/app/hbench/env.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/env.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2019 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 hbench
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <str.h>
+#include "hbench.h"
+
+typedef struct {
+	ht_link_t link;
+
+	char *key;
+	char *value;
+} param_t;
+
+static size_t param_hash(const ht_link_t *item)
+{
+	param_t *param = hash_table_get_inst(item, param_t, link);
+	return str_size(param->key);
+}
+
+static size_t param_key_hash(const void *key)
+{
+	const char *key_str = key;
+	return str_size(key_str);
+}
+
+static bool param_key_equal(const void *key, const ht_link_t *item)
+{
+	param_t *param = hash_table_get_inst(item, param_t, link);
+	const char *key_str = key;
+
+	return str_cmp(param->key, key_str) == 0;
+}
+
+static bool param_equal(const ht_link_t *link_a, const ht_link_t *link_b)
+{
+	param_t *a = hash_table_get_inst(link_a, param_t, link);
+	param_t *b = hash_table_get_inst(link_b, param_t, link);
+
+	return str_cmp(a->key, b->key) == 0;
+}
+
+static void param_remove(ht_link_t *item)
+{
+	param_t *param = hash_table_get_inst(item, param_t, link);
+	free(param->key);
+	free(param->value);
+}
+
+static hash_table_ops_t param_hash_table_ops = {
+	.hash = param_hash,
+	.key_hash = param_key_hash,
+	.key_equal = param_key_equal,
+	.equal = param_equal,
+	.remove_callback = param_remove
+};
+
+errno_t bench_env_init(bench_env_t *env)
+{
+	bool ok = hash_table_create(&env->parameters, 0, 0, &param_hash_table_ops);
+	if (!ok) {
+		return ENOMEM;
+	}
+
+	env->run_count = DEFAULT_RUN_COUNT;
+	env->minimal_run_duration_nanos = MSEC2NSEC(DEFAULT_MIN_RUN_DURATION_SEC);
+
+	return EOK;
+}
+
+void bench_env_cleanup(bench_env_t *env)
+{
+	hash_table_destroy(&env->parameters);
+}
+
+errno_t bench_env_param_set(bench_env_t *env, const char *key, const char *value)
+{
+	param_t *param = malloc(sizeof(param_t));
+	if (param == NULL) {
+		return ENOMEM;
+	}
+
+	param->key = str_dup(key);
+	param->value = str_dup(value);
+
+	if ((param->key == NULL) || (param->value == NULL)) {
+		free(param->key);
+		free(param->value);
+		free(param);
+
+		return ENOMEM;
+	}
+
+	hash_table_insert(&env->parameters, &param->link);
+
+	return EOK;
+}
+
+const char *bench_env_param_get(bench_env_t *env, const char *key, const char *default_value)
+{
+	ht_link_t *item = hash_table_find(&env->parameters, (char *) key);
+
+	if (item == NULL) {
+		return default_value;
+	}
+
+	param_t *param = hash_table_get_inst(item, param_t, link);
+	return param->value;
+}
+
+/** @}
+ */
Index: uspace/app/hbench/fs/dirread.c
===================================================================
--- uspace/app/hbench/fs/dirread.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/fs/dirread.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2011 Martin Sucha
+ * Copyright (c) 2019 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 hbench
+ * @{
+ */
+
+#include <dirent.h>
+#include <str_error.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "../hbench.h"
+
+/** Execute directory listing benchmark.
+ *
+ * Note that while this benchmark tries to measure speed of direct
+ * read, it rather measures speed of FS cache as it is highly probable
+ * that the corresponding blocks would be cached after first run.
+ */
+static bool runner(bench_env_t *env, bench_run_t *run, uint64_t size)
+{
+	const char *path = bench_env_param_get(env, "dirname", "/");
+
+	bench_run_start(run);
+	for (uint64_t i = 0; i < size; i++) {
+		DIR *dir = opendir(path);
+		if (dir == NULL) {
+			return bench_run_fail(run, "failed to open %s for reading: %s",
+			    path, str_error(errno));
+		}
+
+		struct dirent *dp;
+		while ((dp = readdir(dir))) {
+			/* Do nothing */
+		}
+
+		closedir(dir);
+	}
+	bench_run_stop(run);
+
+	return true;
+}
+
+benchmark_t benchmark_dir_read = {
+	.name = "dir_read",
+	.desc = "Read contents of a directory (use 'dirname' param to alter the default).",
+	.entry = &runner,
+	.setup = NULL,
+	.teardown = NULL
+};
+
+/**
+ * @}
+ */
Index: uspace/app/hbench/fs/fileread.c
===================================================================
--- uspace/app/hbench/fs/fileread.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/fs/fileread.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2011 Martin Sucha
+ * Copyright (c) 2019 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 hbench
+ * @{
+ */
+
+#include <str_error.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "../hbench.h"
+
+#define BUFFER_SIZE 4096
+
+/** Execute file reading benchmark.
+ *
+ * Note that while this benchmark tries to measure speed of file reading,
+ * it rather measures speed of FS cache as it is highly probable that the
+ * corresponding blocks would be cached after first run.
+ */
+static bool runner(bench_env_t *env, bench_run_t *run, uint64_t size)
+{
+	const char *path = bench_env_param_get(env, "filename", "/data/web/helenos.png");
+
+	char *buf = malloc(BUFFER_SIZE);
+	if (buf == NULL) {
+		return bench_run_fail(run, "failed to allocate %dB buffer", BUFFER_SIZE);
+	}
+
+	bool ret = true;
+
+	FILE *file = fopen(path, "r");
+	if (file == NULL) {
+		bench_run_fail(run, "failed to open %s for reading: %s",
+		    path, str_error(errno));
+		ret = false;
+		goto leave_free_buf;
+	}
+
+	bench_run_start(run);
+	for (uint64_t i = 0; i < size; i++) {
+		int rc = fseek(file, 0, SEEK_SET);
+		if (rc != 0) {
+			bench_run_fail(run, "failed to rewind %s: %s",
+			    path, str_error(errno));
+			ret = false;
+			goto leave_close;
+		}
+		while (!feof(file)) {
+			fread(buf, 1, BUFFER_SIZE, file);
+			if (ferror(file)) {
+				bench_run_fail(run, "failed to read from %s: %s",
+				    path, str_error(errno));
+				ret = false;
+				goto leave_close;
+			}
+		}
+	}
+	bench_run_stop(run);
+
+leave_close:
+	fclose(file);
+
+leave_free_buf:
+	free(buf);
+
+	return ret;
+}
+
+benchmark_t benchmark_file_read = {
+	.name = "file_read",
+	.desc = "Sequentially read contents of a file (use 'filename' param to alter the default).",
+	.entry = &runner,
+	.setup = NULL,
+	.teardown = NULL
+};
+
+/**
+ * @}
+ */
Index: uspace/app/hbench/hbench.h
===================================================================
--- uspace/app/hbench/hbench.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/hbench.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2018 Jiri Svoboda
+ * Copyright (c) 2019 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 hbench
+ * @{
+ */
+/** @file
+ */
+
+#ifndef HBENCH_H_
+#define HBENCH_H_
+
+#include <adt/hash_table.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <perf.h>
+
+#define DEFAULT_RUN_COUNT 10
+#define DEFAULT_MIN_RUN_DURATION_SEC 10
+
+/** Single run information.
+ *
+ * Used to store both performance information (now, only wall-clock
+ * time) as well as information about error.
+ *
+ * Use proper access functions when modifying data inside this structure.
+ *
+ * Eventually, we could collection of hardware counters etc. without
+ * modifying signatures of any existing benchmark.
+ */
+typedef struct {
+	stopwatch_t stopwatch;
+	char *error_message;
+	size_t error_message_buffer_size;
+} bench_run_t;
+
+/** Benchmark environment configuration.
+ *
+ * Benchmarking code (runners) should use access functions to read
+ * data from this structure (now only bench_env_param_get).
+ *
+ * Harness can access it directly.
+ */
+typedef struct {
+	hash_table_t parameters;
+	size_t run_count;
+	nsec_t minimal_run_duration_nanos;
+} bench_env_t;
+
+/** Actual benchmark runner.
+ *
+ * The first argument describes the environment, second is used to store
+ * information about the run (performance data or error message) and
+ * third describes workload size (number of iterations).
+ */
+typedef bool (*benchmark_entry_t)(bench_env_t *, bench_run_t *, uint64_t);
+
+/** Setup and teardown callback type.
+ *
+ * Unlike in benchmark_entry_t, we do not need to pass in number of
+ * iterations to execute (note that we use bench_run_t only to simplify
+ * creation of error messages).
+ */
+typedef bool (*benchmark_helper_t)(bench_env_t *, bench_run_t *);
+
+typedef struct {
+	const char *name;
+	const char *desc;
+	benchmark_entry_t entry;
+	benchmark_helper_t setup;
+	benchmark_helper_t teardown;
+} benchmark_t;
+
+extern void bench_run_init(bench_run_t *, char *, size_t);
+extern bool bench_run_fail(bench_run_t *, const char *, ...);
+
+/*
+ * We keep the following two functions inline to ensure that we start
+ * measurement as close to the surrounding code as possible. Note that
+ * this inlining is done at least on the level of individual wrappers
+ * (this one and the one provided by stopwatch_t) to pass the control
+ * as fast as possible to the actual timer used.
+ */
+
+static inline void bench_run_start(bench_run_t *run)
+{
+	stopwatch_start(&run->stopwatch);
+}
+
+static inline void bench_run_stop(bench_run_t *run)
+{
+	stopwatch_stop(&run->stopwatch);
+}
+
+extern errno_t csv_report_open(const char *);
+extern void csv_report_add_entry(bench_run_t *, int, benchmark_t *, uint64_t);
+extern void csv_report_close(void);
+
+extern errno_t bench_env_init(bench_env_t *);
+extern errno_t bench_env_param_set(bench_env_t *, const char *, const char *);
+extern const char *bench_env_param_get(bench_env_t *, const char *, const char *);
+extern void bench_env_cleanup(bench_env_t *);
+
+extern benchmark_t *benchmarks[];
+extern size_t benchmark_count;
+
+/* Put your benchmark descriptors here (and also to benchlist.c). */
+extern benchmark_t benchmark_dir_read;
+extern benchmark_t benchmark_fibril_mutex;
+extern benchmark_t benchmark_file_read;
+extern benchmark_t benchmark_malloc1;
+extern benchmark_t benchmark_malloc2;
+extern benchmark_t benchmark_ns_ping;
+extern benchmark_t benchmark_ping_pong;
+
+#endif
+
+/** @}
+ */
Index: uspace/app/hbench/ipc/ns_ping.c
===================================================================
--- uspace/app/hbench/ipc/ns_ping.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/ipc/ns_ping.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2018 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 hbench
+ * @{
+ */
+
+#include <stdio.h>
+#include <ns.h>
+#include <async.h>
+#include <errno.h>
+#include <str_error.h>
+#include "../hbench.h"
+
+static bool runner(bench_env_t *env, bench_run_t *run, uint64_t niter)
+{
+	bench_run_start(run);
+
+	for (uint64_t count = 0; count < niter; count++) {
+		errno_t rc = ns_ping();
+
+		if (rc != EOK) {
+			return bench_run_fail(run, "failed sending ping message: %s (%d)",
+			    str_error(rc), rc);
+		}
+	}
+
+	bench_run_stop(run);
+
+	return true;
+}
+
+benchmark_t benchmark_ns_ping = {
+	.name = "ns_ping",
+	.desc = "Name service IPC ping-pong benchmark",
+	.entry = &runner,
+	.setup = NULL,
+	.teardown = NULL
+};
+
+/** @}
+ */
Index: uspace/app/hbench/ipc/ping_pong.c
===================================================================
--- uspace/app/hbench/ipc/ping_pong.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/ipc/ping_pong.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2009 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 hbench
+ * @{
+ */
+
+#include <stdio.h>
+#include <ipc_test.h>
+#include <async.h>
+#include <errno.h>
+#include <str_error.h>
+#include "../hbench.h"
+
+static ipc_test_t *test = NULL;
+
+static bool setup(bench_env_t *env, bench_run_t *run)
+{
+	errno_t rc = ipc_test_create(&test);
+	if (rc != EOK) {
+		return bench_run_fail(run,
+		    "failed contacting IPC test server (have you run /srv/test/ipc-test?): %s (%d)",
+		    str_error(rc), rc);
+	}
+
+	return true;
+}
+
+static bool teardown(bench_env_t *env, bench_run_t *run)
+{
+	ipc_test_destroy(test);
+	return true;
+}
+
+static bool runner(bench_env_t *env, bench_run_t *run, uint64_t niter)
+{
+	bench_run_start(run);
+
+	for (uint64_t count = 0; count < niter; count++) {
+		errno_t rc = ipc_test_ping(test);
+
+		if (rc != EOK) {
+			return bench_run_fail(run, "failed sending ping message: %s (%d)",
+			    str_error(rc), rc);
+		}
+	}
+
+	bench_run_stop(run);
+
+	return true;
+}
+
+benchmark_t benchmark_ping_pong = {
+	.name = "ping_pong",
+	.desc = "IPC ping-pong benchmark",
+	.entry = &runner,
+	.setup = &setup,
+	.teardown = &teardown
+};
+
+/** @}
+ */
Index: uspace/app/hbench/main.c
===================================================================
--- uspace/app/hbench/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2018 Jiri Svoboda
+ * Copyright (c) 2018 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 hbench
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <assert.h>
+#include <getopt.h>
+#include <math.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <str.h>
+#include <time.h>
+#include <errno.h>
+#include <str_error.h>
+#include <perf.h>
+#include <types/casting.h>
+#include "hbench.h"
+
+#define MAX_ERROR_STR_LENGTH 1024
+
+static void short_report(bench_run_t *info, int run_index,
+    benchmark_t *bench, uint64_t workload_size)
+{
+	csv_report_add_entry(info, run_index, bench, workload_size);
+
+	usec_t duration_usec = NSEC2USEC(stopwatch_get_nanos(&info->stopwatch));
+
+	printf("Completed %" PRIu64 " operations in %llu us",
+	    workload_size, duration_usec);
+	if (duration_usec > 0) {
+		double nanos = stopwatch_get_nanos(&info->stopwatch);
+		double thruput = (double) workload_size / (nanos / 1000000000.0l);
+		printf(", %.0f ops/s.\n", thruput);
+	} else {
+		printf(".\n");
+	}
+}
+
+/** Estimate square root value.
+ *
+ * @param value The value to compute square root of.
+ * @param precision Required precision (e.g. 0.00001).
+ *
+ * @details
+ *
+ * This is a temporary solution until we have proper sqrt() implementation
+ * in libmath.
+ *
+ * The algorithm uses Babylonian method [1].
+ *
+ * [1] https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method
+ */
+static double estimate_square_root(double value, double precision)
+{
+	double estimate = 1.;
+	double prev_estimate = estimate + 10 * precision;
+
+	while (fabs(estimate - prev_estimate) > precision) {
+		prev_estimate = estimate;
+		estimate = (prev_estimate + value / prev_estimate) / 2.;
+	}
+
+	return estimate;
+}
+
+/** Compute available statistics from given stopwatches.
+ *
+ * We compute normal mean for average duration of the workload and geometric
+ * mean for average thruput. Note that geometric mean is necessary to compute
+ * average throughput correctly - consider the following example:
+ *  - we run always 60 operations,
+ *  - first run executes in 30 s (i.e. 2 ops/s)
+ *  - and second one in 10 s (6 ops/s).
+ * Then, naively, average throughput would be (2+6)/2 = 4 [ops/s]. However, we
+ * actually executed 60 + 60 ops in 30 + 10 seconds. So the actual average
+ * throughput is 3 ops/s (which is exactly what geometric mean means).
+ *
+ */
+static void compute_stats(bench_run_t *runs, size_t run_count,
+    uint64_t workload_size, double precision, double *out_duration_avg,
+    double *out_duration_sigma, double *out_thruput_avg)
+{
+	double inv_thruput_sum = 0.0;
+	double nanos_sum = 0.0;
+	double nanos_sum2 = 0.0;
+
+	for (size_t i = 0; i < run_count; i++) {
+		double nanos = stopwatch_get_nanos(&runs[i].stopwatch);
+		double thruput = (double) workload_size / nanos;
+
+		inv_thruput_sum += 1.0 / thruput;
+		nanos_sum += nanos;
+		nanos_sum2 += nanos * nanos;
+	}
+	*out_duration_avg = nanos_sum / run_count;
+	double sigma2 = (nanos_sum2 - nanos_sum * (*out_duration_avg)) /
+	    ((double) run_count - 1);
+	// FIXME: implement sqrt properly
+	if (run_count > 1) {
+		*out_duration_sigma = estimate_square_root(sigma2, precision);
+	} else {
+		*out_duration_sigma = NAN;
+	}
+	*out_thruput_avg = 1.0 / (inv_thruput_sum / run_count);
+}
+
+static void summary_stats(bench_run_t *runs, size_t run_count,
+    benchmark_t *bench, uint64_t workload_size)
+{
+	double duration_avg, duration_sigma, thruput_avg;
+	compute_stats(runs, run_count, workload_size, 0.001,
+	    &duration_avg, &duration_sigma, &thruput_avg);
+
+	printf("Average: %" PRIu64 " ops in %.0f us (sd %.0f us); "
+	    "%.0f ops/s; Samples: %zu\n",
+	    workload_size, duration_avg / 1000.0, duration_sigma / 1000.0,
+	    thruput_avg * 1000000000.0, run_count);
+}
+
+static bool run_benchmark(bench_env_t *env, benchmark_t *bench)
+{
+	printf("Warm up and determine workload size...\n");
+
+	/*
+	 * We share this buffer across all runs as we know that it is
+	 * used only on failure (and we abort after first error).
+	 */
+	char *error_msg = malloc(MAX_ERROR_STR_LENGTH + 1);
+	if (error_msg == NULL) {
+		printf("Out of memory!\n");
+		return false;
+	}
+	str_cpy(error_msg, MAX_ERROR_STR_LENGTH, "");
+
+	bench_run_t helper_run;
+	bench_run_init(&helper_run, error_msg, MAX_ERROR_STR_LENGTH);
+
+	bool ret = true;
+
+	if (bench->setup != NULL) {
+		ret = bench->setup(env, &helper_run);
+		if (!ret) {
+			goto leave_error;
+		}
+	}
+
+	/*
+	 * Find workload size that is big enough to last few seconds.
+	 * We also check that uint64_t is big enough.
+	 */
+	uint64_t workload_size = 0;
+	for (size_t bits = 0; bits <= 64; bits++) {
+		if (bits == 64) {
+			str_cpy(error_msg, MAX_ERROR_STR_LENGTH, "Workload too small even for 1 << 63");
+			goto leave_error;
+		}
+		workload_size = ((uint64_t) 1) << bits;
+
+		bench_run_t run;
+		bench_run_init(&run, error_msg, MAX_ERROR_STR_LENGTH);
+
+		bool ok = bench->entry(env, &run, workload_size);
+		if (!ok) {
+			goto leave_error;
+		}
+		short_report(&run, -1, bench, workload_size);
+
+		nsec_t duration = stopwatch_get_nanos(&run.stopwatch);
+		if (duration > env->minimal_run_duration_nanos) {
+			break;
+		}
+	}
+
+	printf("Workload size set to %" PRIu64 ", measuring %zu samples.\n",
+	    workload_size, env->run_count);
+
+	bench_run_t *runs = calloc(env->run_count, sizeof(bench_run_t));
+	if (runs == NULL) {
+		snprintf(error_msg, MAX_ERROR_STR_LENGTH, "failed allocating memory");
+		goto leave_error;
+	}
+	for (size_t i = 0; i < env->run_count; i++) {
+		bench_run_init(&runs[i], error_msg, MAX_ERROR_STR_LENGTH);
+
+		bool ok = bench->entry(env, &runs[i], workload_size);
+		if (!ok) {
+			free(runs);
+			goto leave_error;
+		}
+		short_report(&runs[i], i, bench, workload_size);
+	}
+
+	summary_stats(runs, env->run_count, bench, workload_size);
+	printf("\nBenchmark completed\n");
+
+	free(runs);
+
+	goto leave;
+
+leave_error:
+	printf("Error: %s\n", error_msg);
+	ret = false;
+
+leave:
+	if (bench->teardown != NULL) {
+		bool ok = bench->teardown(env, &helper_run);
+		if (!ok) {
+			printf("Error: %s\n", error_msg);
+			ret = false;
+		}
+	}
+
+	free(error_msg);
+
+	return ret;
+}
+
+static int run_benchmarks(bench_env_t *env)
+{
+	unsigned int count_ok = 0;
+	unsigned int count_fail = 0;
+
+	char *failed_names = NULL;
+
+	printf("\n*** Running all benchmarks ***\n\n");
+
+	for (size_t it = 0; it < benchmark_count; it++) {
+		printf("%s (%s)\n", benchmarks[it]->name, benchmarks[it]->desc);
+		if (run_benchmark(env, benchmarks[it])) {
+			count_ok++;
+			continue;
+		}
+
+		if (!failed_names) {
+			failed_names = str_dup(benchmarks[it]->name);
+		} else {
+			char *f = NULL;
+			asprintf(&f, "%s, %s", failed_names, benchmarks[it]->name);
+			if (!f) {
+				printf("Out of memory.\n");
+				abort();
+			}
+			free(failed_names);
+			failed_names = f;
+		}
+		count_fail++;
+	}
+
+	printf("\nCompleted, %u benchmarks run, %u succeeded.\n",
+	    count_ok + count_fail, count_ok);
+	if (failed_names)
+		printf("Failed benchmarks: %s\n", failed_names);
+
+	return count_fail;
+}
+
+static void list_benchmarks(void)
+{
+	size_t len = 0;
+	for (size_t i = 0; i < benchmark_count; i++) {
+		size_t len_now = str_length(benchmarks[i]->name);
+		if (len_now > len)
+			len = len_now;
+	}
+
+	assert(can_cast_size_t_to_int(len) && "benchmark name length overflow");
+
+	for (size_t i = 0; i < benchmark_count; i++)
+		printf("  %-*s %s\n", (int) len, benchmarks[i]->name, benchmarks[i]->desc);
+
+	printf("  %-*s Run all benchmarks\n", (int) len, "*");
+}
+
+static void print_usage(const char *progname)
+{
+	printf("Usage: %s [options] <benchmark>\n", progname);
+	printf("-h, --help                 "
+	    "Print this help and exit\n");
+	printf("-d, --duration MILLIS      "
+	    "Set minimal run duration (milliseconds)\n");
+	printf("-n, --count N              "
+	    "Set number of measured runs\n");
+	printf("-o, --output filename.csv  "
+	    "Store machine-readable data in filename.csv\n");
+	printf("-p, --param KEY=VALUE      "
+	    "Additional parameters for the benchmark\n");
+	printf("<benchmark> is one of the following:\n");
+	list_benchmarks();
+}
+
+static void handle_param_arg(bench_env_t *env, char *arg)
+{
+	char *value = NULL;
+	char *key = str_tok(arg, "=", &value);
+	bench_env_param_set(env, key, value);
+}
+
+int main(int argc, char *argv[])
+{
+	bench_env_t bench_env;
+	errno_t rc = bench_env_init(&bench_env);
+	if (rc != EOK) {
+		fprintf(stderr, "Failed to initialize internal params structure: %s\n",
+		    str_error(rc));
+		return -5;
+	}
+
+	const char *short_options = "ho:p:n:d:";
+	struct option long_options[] = {
+		{ "duration", required_argument, NULL, 'd' },
+		{ "help", optional_argument, NULL, 'h' },
+		{ "count", required_argument, NULL, 'n' },
+		{ "output", required_argument, NULL, 'o' },
+		{ "param", required_argument, NULL, 'p' },
+		{ 0, 0, NULL, 0 }
+	};
+
+	char *csv_output_filename = NULL;
+
+	int opt = 0;
+	while ((opt = getopt_long(argc, argv, short_options, long_options, NULL)) > 0) {
+		switch (opt) {
+		case 'd':
+			errno = EOK;
+			bench_env.minimal_run_duration_nanos = MSEC2NSEC(atoll(optarg));
+			if ((errno != EOK) || (bench_env.minimal_run_duration_nanos <= 0)) {
+				fprintf(stderr, "Invalid -d argument.\n");
+				return -3;
+			}
+			break;
+		case 'h':
+			print_usage(*argv);
+			return 0;
+		case 'n':
+			errno = EOK;
+			bench_env.run_count = (nsec_t) atoll(optarg);
+			if ((errno != EOK) || (bench_env.run_count <= 0)) {
+				fprintf(stderr, "Invalid -n argument.\n");
+				return -3;
+			}
+			break;
+		case 'o':
+			csv_output_filename = optarg;
+			break;
+		case 'p':
+			handle_param_arg(&bench_env, optarg);
+			break;
+		case -1:
+		default:
+			break;
+		}
+	}
+
+	if (optind + 1 != argc) {
+		print_usage(*argv);
+		fprintf(stderr, "Error: specify one benchmark to run or * for all.\n");
+		return -3;
+	}
+
+	const char *benchmark = argv[optind];
+
+	if (csv_output_filename != NULL) {
+		errno_t rc = csv_report_open(csv_output_filename);
+		if (rc != EOK) {
+			fprintf(stderr, "Failed to open CSV report '%s': %s\n",
+			    csv_output_filename, str_error(rc));
+			return -4;
+		}
+	}
+
+	int exit_code = 0;
+
+	if (str_cmp(benchmark, "*") == 0) {
+		exit_code = run_benchmarks(&bench_env);
+	} else {
+		bool benchmark_exists = false;
+		for (size_t i = 0; i < benchmark_count; i++) {
+			if (str_cmp(benchmark, benchmarks[i]->name) == 0) {
+				benchmark_exists = true;
+				exit_code = run_benchmark(&bench_env, benchmarks[i]) ? 0 : -1;
+				break;
+			}
+		}
+		if (!benchmark_exists) {
+			printf("Unknown benchmark \"%s\"\n", benchmark);
+			exit_code = -2;
+		}
+	}
+
+	csv_report_close();
+	bench_env_cleanup(&bench_env);
+
+	return exit_code;
+}
+
+/** @}
+ */
Index: uspace/app/hbench/malloc/malloc1.c
===================================================================
--- uspace/app/hbench/malloc/malloc1.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/malloc/malloc1.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2018 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 hbench
+ * @{
+ */
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "../hbench.h"
+
+static bool runner(bench_env_t *env, bench_run_t *run, uint64_t size)
+{
+	bench_run_start(run);
+	for (uint64_t i = 0; i < size; i++) {
+		void *p = malloc(1);
+		if (p == NULL) {
+			return bench_run_fail(run,
+			    "failed to allocate 1B in run %" PRIu64 " (out of %" PRIu64 ")",
+			    i, size);
+		}
+		free(p);
+	}
+	bench_run_stop(run);
+
+	return true;
+}
+
+benchmark_t benchmark_malloc1 = {
+	.name = "malloc1",
+	.desc = "User-space memory allocator benchmark, repeatedly allocate one block",
+	.entry = &runner,
+	.setup = NULL,
+	.teardown = NULL
+};
+
+/** @}
+ */
Index: uspace/app/hbench/malloc/malloc2.c
===================================================================
--- uspace/app/hbench/malloc/malloc2.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/malloc/malloc2.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2018 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 hbench
+ * @{
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "../hbench.h"
+
+static bool runner(bench_env_t *env, bench_run_t *run, uint64_t niter)
+{
+	bench_run_start(run);
+
+	void **p = malloc(niter * sizeof(void *));
+	if (p == NULL) {
+		return bench_run_fail(run, "failed to allocate backend array (%" PRIu64 "B)",
+		    niter * sizeof(void *));
+	}
+
+	for (uint64_t count = 0; count < niter; count++) {
+		p[count] = malloc(1);
+		if (p[count] == NULL) {
+			for (uint64_t j = 0; j < count; j++) {
+				free(p[j]);
+			}
+			free(p);
+			return bench_run_fail(run,
+			    "failed to allocate 1B in run %" PRIu64 " (out of %" PRIu64 ")",
+			    count, niter);
+		}
+	}
+
+	for (uint64_t count = 0; count < niter; count++)
+		free(p[count]);
+
+	free(p);
+
+	bench_run_stop(run);
+
+	return true;
+}
+
+benchmark_t benchmark_malloc2 = {
+	.name = "malloc2",
+	.desc = "User-space memory allocator benchmark, allocate many small blocks",
+	.entry = &runner,
+	.setup = NULL,
+	.teardown = NULL
+};
+
+/** @}
+ */
Index: uspace/app/hbench/synch/fibril_mutex.c
===================================================================
--- uspace/app/hbench/synch/fibril_mutex.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/synch/fibril_mutex.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2019 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 hbench
+ * @{
+ */
+
+#include <fibril_synch.h>
+#include <stdatomic.h>
+#include "../hbench.h"
+
+/*
+ * Simple benchmark for fibril mutexes. There are two fibrils that compete
+ * over the same mutex as that is the simplest scenario.
+ */
+
+typedef struct {
+	fibril_mutex_t mutex;
+	uint64_t counter;
+	atomic_bool done;
+} shared_t;
+
+static errno_t competitor(void *arg)
+{
+	shared_t *shared = arg;
+	fibril_detach(fibril_get_id());
+
+	while (true) {
+		fibril_mutex_lock(&shared->mutex);
+		uint64_t local = shared->counter;
+		fibril_mutex_unlock(&shared->mutex);
+		if (local == 0) {
+			break;
+		}
+	}
+
+	atomic_store(&shared->done, true);
+
+	return EOK;
+}
+
+static bool runner(bench_env_t *env, bench_run_t *run, uint64_t size)
+{
+	shared_t shared;
+	fibril_mutex_initialize(&shared.mutex);
+	shared.counter = size;
+	atomic_store(&shared.done, false);
+
+	fid_t other = fibril_create(competitor, &shared);
+	fibril_add_ready(other);
+
+	bench_run_start(run);
+	for (uint64_t i = 0; i < size; i++) {
+		fibril_mutex_lock(&shared.mutex);
+		shared.counter--;
+		fibril_mutex_unlock(&shared.mutex);
+	}
+	bench_run_stop(run);
+
+	while (!atomic_load(&shared.done)) {
+		fibril_yield();
+	}
+
+	return true;
+}
+
+benchmark_t benchmark_fibril_mutex = {
+	.name = "fibril_mutex",
+	.desc = "Speed of mutex lock/unlock operations",
+	.entry = &runner,
+	.setup = NULL,
+	.teardown = NULL
+};
+
+/** @}
+ */
Index: uspace/app/hbench/utils.c
===================================================================
--- uspace/app/hbench/utils.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/utils.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2019 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 hbench
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "hbench.h"
+
+/** Initialize bench run structure.
+ *
+ * @param run Structure to intialize.
+ * @param error_buffer Pre-allocated memory to use for error messages.
+ * @param error_buffer_size Size of error_buffer.
+ */
+void bench_run_init(bench_run_t *run, char *error_buffer, size_t error_buffer_size)
+{
+	stopwatch_init(&run->stopwatch);
+	run->error_message = error_buffer;
+	run->error_message_buffer_size = error_buffer_size;
+}
+
+/** Format error message on benchmark failure.
+ *
+ * This function always returns false so it can be easily used in benchmark
+ * runners as
+ *
+ * @code
+ * if (error) {
+ *     return bench_run_fail(run, "we failed");
+ * }
+ * @endcode
+ *
+ * @param run Current benchmark run.
+ * @param fmt printf-style message followed by extra arguments.
+ * @retval false Always.
+ */
+bool bench_run_fail(bench_run_t *run, const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+	vsnprintf(run->error_message, run->error_message_buffer_size, fmt, args);
+	va_end(args);
+
+	return false;
+}
+
+/** @}
+ */
Index: uspace/app/init/untar.c
===================================================================
--- uspace/app/init/untar.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/init/untar.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -45,5 +45,5 @@
 typedef struct {
 	const char *dev;
-	
+
 	service_id_t sid;
 	aoff64_t offset;
Index: uspace/app/kio/kio.c
===================================================================
--- uspace/app/kio/kio.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/kio/kio.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -164,7 +164,7 @@
 	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 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;
Index: uspace/app/lprint/Makefile
===================================================================
--- uspace/app/lprint/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/lprint/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2018 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.
+#
+
+USPACE_PREFIX = ../..
+BINARY = lprint
+
+SOURCES = \
+	lprint.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/lprint/doc/doxygroups.h
===================================================================
--- uspace/app/lprint/doc/doxygroups.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/lprint/doc/doxygroups.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,4 @@
+/** @addtogroup lprint lprint
+ * @brief Print on a printer
+ * @ingroup apps
+ */
Index: uspace/app/lprint/lprint.c
===================================================================
--- uspace/app/lprint/lprint.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/lprint/lprint.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2018 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 lprint
+ * @{
+ */
+
+/**
+ * @file
+ * @brief Print on a printer
+ *
+ */
+
+#include <errno.h>
+#include <io/chardev.h>
+#include <loc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <str.h>
+
+#define NAME	"lprint"
+
+#define BUF_SIZE 1024
+
+static void syntax_print(void);
+
+/** Get default printer port.
+ *
+ * @param sid Place to store service ID of the printer port
+ * @return EOK on success or error code
+ */
+static errno_t lprint_get_def_printer_port(service_id_t *sid)
+{
+	category_id_t cid;
+	service_id_t *sids;
+	size_t nsids;
+	errno_t rc;
+
+	rc = loc_category_get_id("printer-port", &cid, 0);
+	if (rc != EOK)
+		return EIO;
+
+	rc = loc_category_get_svcs(cid, &sids, &nsids);
+	if (rc != EOK)
+		return EIO;
+
+	if (nsids < 1) {
+		free(sids);
+		return EIO;
+	}
+
+	*sid = sids[0];
+	free(sids);
+	return EOK;
+}
+
+/** Print a message.
+ *
+ * @param chardev Character device
+ * @param argc Number of arguments
+ * @param argv Arguments - strings to print
+ *
+ * @return EOK on success or error code
+ */
+static errno_t lprint_msg(chardev_t *chardev, int argc, char *argv[])
+{
+	const char *msg;
+	size_t nbytes;
+	const char *sep;
+	errno_t rc;
+
+	while (argc > 0) {
+		msg = *argv;
+		--argc;
+		++argv;
+
+		rc = chardev_write(chardev, msg, str_size(msg), &nbytes);
+		if (rc != EOK) {
+			printf(NAME ": Failed sending data.\n");
+			return EIO;
+		}
+
+		sep = argc > 0 ? " " : "\n";
+
+		rc = chardev_write(chardev, sep, str_size(sep), &nbytes);
+		if (rc != EOK) {
+			printf(NAME ": Failed sending data.\n");
+			return EIO;
+		}
+	}
+
+	return EOK;
+}
+
+/** Print a file.
+ *
+ * @param chardev Character device
+ * @param fname File name
+ *
+ * @return EOK on success or error code
+ */
+static errno_t lprint_file(chardev_t *chardev, const char *fname)
+{
+	void *buf;
+	size_t nread, nwritten;
+	FILE *f = NULL;
+	errno_t rc;
+
+	buf = malloc(BUF_SIZE);
+	if (buf == NULL) {
+		printf(NAME ": Out of memory.\n");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	f = fopen(fname, "rb");
+	if (f == NULL) {
+		printf(NAME ": Cannot open '%s'.\n", fname);
+		rc = EIO;
+		goto error;
+	}
+
+	while (true) {
+		nread = fread(buf, 1, BUF_SIZE, f);
+		if (ferror(f)) {
+			printf(NAME ": Error reading file.\n");
+			rc = EIO;
+			goto error;
+		}
+
+		if (nread == 0)
+			break;
+
+		rc = chardev_write(chardev, buf, nread, &nwritten);
+		if (rc != EOK) {
+			printf(NAME ": Failed sending data.\n");
+			rc = EIO;
+			goto error;
+		}
+
+	}
+
+	fclose(f);
+	return EOK;
+error:
+	if (buf != NULL)
+		free(buf);
+	if (f != NULL)
+		fclose(f);
+	return rc;
+}
+
+int main(int argc, char **argv)
+{
+	chardev_t *chardev;
+	errno_t rc;
+	async_sess_t *sess;
+	service_id_t sid;
+	const char *svc_name = NULL;
+	bool msg_mode = false;
+
+	if (argc < 2) {
+		printf(NAME ": Error, argument missing.\n");
+		syntax_print();
+		return 1;
+	}
+
+	--argc;
+	++argv;
+
+	while (*argv != NULL && *argv[0] == '-') {
+		if (str_cmp(*argv, "-d") == 0) {
+			--argc;
+			++argv;
+
+			if (*argv == NULL) {
+				printf(NAME ": Error, argument missing.\n");
+				syntax_print();
+				return 1;
+			}
+
+			svc_name = *argv;
+			--argc;
+			++argv;
+			continue;
+		}
+
+		if (str_cmp(*argv, "-m") == 0) {
+			msg_mode = true;
+			--argc;
+			++argv;
+			continue;
+		}
+
+		if (str_cmp(*argv, "--help") == 0) {
+			--argc;
+			++argv;
+
+			if (*argv != NULL) {
+				printf(NAME ": Error, unexpected argument.\n");
+				syntax_print();
+				return 1;
+			}
+
+			syntax_print();
+			return 0;
+		}
+
+		printf(NAME ": Error, invalid argument.\n");
+		syntax_print();
+		return 1;
+	}
+
+	if (argc < 1) {
+		printf(NAME ": Error, argument missing.\n");
+		syntax_print();
+		return 1;
+	}
+
+	if (!msg_mode && argc > 1) {
+		printf(NAME ": Error, too many arguments.\n");
+		syntax_print();
+		return 1;
+	}
+
+	if (svc_name != NULL) {
+		rc = loc_service_get_id(svc_name, &sid, 0);
+		if (rc != EOK) {
+			printf(NAME ": Failed resolving printer port service "
+			    "'%s'.\n", svc_name);
+			return 1;
+		}
+	} else {
+		rc = lprint_get_def_printer_port(&sid);
+		if (rc != EOK) {
+			printf(NAME ": No printer found.\n");
+			return 1;
+		}
+	}
+
+	sess = loc_service_connect(sid, INTERFACE_DDF, 0);
+	if (sess == NULL) {
+		printf(NAME ": Failed connecting printer port service.\n");
+		return 1;
+	}
+
+	rc = chardev_open(sess, &chardev);
+	if (rc != EOK) {
+		async_hangup(sess);
+		printf(NAME ": Failed opening printer port device.\n");
+		return 1;
+	}
+
+	if (msg_mode) {
+		rc = lprint_msg(chardev, argc, argv);
+		if (rc != EOK) {
+			chardev_close(chardev);
+			return 1;
+		}
+	} else {
+		rc = lprint_file(chardev, argv[0]);
+		if (rc != EOK) {
+			chardev_close(chardev);
+			return 1;
+		}
+	}
+
+	chardev_close(chardev);
+	return 0;
+}
+
+/** Print syntax help. */
+static void syntax_print(void)
+{
+	printf("syntax:\n"
+	    "\tlprint [<options>] <file>\n"
+	    "\tlprint [<options>] -m <message...>\n"
+	    "options:\n"
+	    "\t-d <device>Print to the specified device\n");
+}
+
+/**
+ * @}
+ */
Index: uspace/app/mkbd/main.c
===================================================================
--- uspace/app/mkbd/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/mkbd/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,4 +39,5 @@
 #include <stdlib.h>
 #include <errno.h>
+#include <fibril.h>
 #include <str_error.h>
 #include <stdbool.h>
Index: uspace/app/mkext4/mkext4.c
===================================================================
--- uspace/app/mkext4/mkext4.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/mkext4/mkext4.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -56,4 +56,5 @@
 	aoff64_t nblocks;
 	const char *label = "";
+	unsigned int bsize = 4096;
 
 	cfg.version = ext4_def_fs_version;
@@ -68,5 +69,5 @@
 	++argv;
 
-	while (*argv[0] == '-') {
+	while (*argv && *argv[0] == '-') {
 		if (str_cmp(*argv, "--size") == 0) {
 			--argc;
@@ -87,4 +88,26 @@
 			--argc;
 			++argv;
+			continue;
+		}
+
+		if (str_cmp(*argv, "--bsize") == 0) {
+			--argc;
+			++argv;
+			if (*argv == NULL) {
+				printf(NAME ": Error, argument missing.\n");
+				syntax_print();
+				return 1;
+			}
+
+			bsize = strtol(*argv, &endptr, 10);
+			if (*endptr != '\0') {
+				printf(NAME ": Error, invalid argument.\n");
+				syntax_print();
+				return 1;
+			}
+
+			--argc;
+			++argv;
+			continue;
 		}
 
@@ -107,4 +130,5 @@
 			--argc;
 			++argv;
+			continue;
 		}
 
@@ -122,4 +146,10 @@
 			--argc;
 			++argv;
+			continue;
+		}
+
+		if (str_cmp(*argv, "--help") == 0) {
+			syntax_print();
+			return 0;
 		}
 
@@ -128,4 +158,8 @@
 			++argv;
 			break;
+		} else {
+			printf(NAME ": Invalid argument: %s\n", *argv);
+			syntax_print();
+			return 1;
 		}
 	}
@@ -147,4 +181,5 @@
 
 	cfg.volume_name = label;
+	cfg.bsize = bsize;
 	(void) nblocks;
 
@@ -166,5 +201,6 @@
 	    "\t--size <sectors> Filesystem size, overrides device size\n"
 	    "\t--label <label>  Volume label\n"
-	    "\t--type <fstype>  Filesystem type (ext2, ext2old)\n");
+	    "\t--type <fstype>  Filesystem type (ext2, ext2old)\n"
+	    "\t--bsize <bytes>  Filesystem block size in bytes (default = 4096)\n");
 }
 
Index: uspace/app/modplay/modplay.c
===================================================================
--- uspace/app/modplay/modplay.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/modplay/modplay.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,4 +39,5 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <str.h>
 #include <str_error.h>
 #include <trackmod.h>
@@ -67,4 +68,11 @@
 }
 
+static void print_syntax(void)
+{
+	printf("syntax: modplay [<options>] <filename.mod>\n");
+	printf("options:\n");
+	printf("\t-t <target>\tOutput to specified audio target.\n");
+}
+
 int main(int argc, char *argv[])
 {
@@ -78,8 +86,33 @@
 	void *buffer;
 	size_t buffer_size;
+	const char *target = HOUND_DEFAULT_TARGET;
 	errno_t rc;
 
-	if (argc != 2) {
-		printf("syntax: modplay <filename.mod>\n");
+	++argv;
+	--argc;
+
+	while (argc > 0 && (*argv)[0] == '-') {
+		if (str_cmp(*argv, "-t") == 0) {
+			++argv;
+			--argc;
+
+			if (argc < 1) {
+				printf("Option '-t' requires an argument.\n");
+				print_syntax();
+				return 1;
+			}
+
+			target = *argv++;
+			--argc;
+			continue;
+		}
+
+		printf("Invalid option '%s'\n", *argv);
+		print_syntax();
+		return 1;
+	}
+
+	if (argc != 1) {
+		print_syntax();
 		return 1;
 	}
@@ -87,7 +120,7 @@
 	con = console_init(stdin, stdout);
 
-	rc = trackmod_module_load(argv[1], &mod);
+	rc = trackmod_module_load(argv[0], &mod);
 	if (rc != EOK) {
-		printf("Error loading %s.\n", argv[1]);
+		printf("Error loading %s.\n", argv[0]);
 		return 1;
 	}
@@ -114,7 +147,18 @@
 	}
 
-	rc = hound_context_connect_target(hound, HOUND_DEFAULT_TARGET);
+	rc = hound_context_connect_target(hound, target);
 	if (rc != EOK) {
-		printf("Error connecting default audio target: %s.\n", str_error(rc));
+		printf("Error connecting audio target '%s': %s.\n",
+		    target, str_error(rc));
+
+		char **names = NULL;
+		size_t count = 0;
+		rc = hound_context_get_available_targets(hound, &names, &count);
+		if (rc == EOK) {
+			printf("Available targets:\n");
+			for (size_t i = 0; i < count; i++)
+				printf(" - %s\n", names[i]);
+		}
+
 		return 1;
 	}
Index: uspace/app/pci/Makefile
===================================================================
--- uspace/app/pci/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/pci/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2019 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.
+#
+
+USPACE_PREFIX = ../..
+BINARY = pci
+
+SOURCES = \
+	pci.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/pci/doc/doxygroups.h
===================================================================
--- uspace/app/pci/doc/doxygroups.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/pci/doc/doxygroups.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,4 @@
+/** @addtogroup pci pci
+ * @brief Tool for listing PCI devices
+ * @ingroup apps
+ */
Index: uspace/app/pci/pci.c
===================================================================
--- uspace/app/pci/pci.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/pci/pci.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2019 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 pci
+ * @{
+ */
+
+/**
+ * @file
+ * @brief Tool for listing PCI devices.
+ */
+
+#include <devman.h>
+#include <errno.h>
+#include <io/table.h>
+#include <loc.h>
+#include <pci.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <str.h>
+
+#define NAME	"mkext4"
+
+#define MAX_NAME_LENGTH 1024
+
+static void syntax_print(void);
+static errno_t pci_list(void);
+static errno_t pci_list_bridge(const char *);
+static errno_t pci_list_bridge_id(service_id_t);
+
+int main(int argc, char **argv)
+{
+	errno_t rc;
+	const char *bridge = NULL;
+
+	--argc;
+	++argv;
+
+	while (argc > 0 && argv[0][0] == '-') {
+		if (str_cmp(argv[0], "--bridge") == 0) {
+			--argc;
+			++argv;
+			if (argc < 1) {
+				printf("Option argument missing.\n");
+				return 1;
+			}
+
+			bridge = argv[0];
+			--argc;
+			++argv;
+		} else {
+			syntax_print();
+			return 1;
+		}
+	}
+
+	if (argc != 0) {
+		syntax_print();
+		return 1;
+	}
+
+	if (bridge != NULL)
+		rc = pci_list_bridge(bridge);
+	else
+		rc = pci_list();
+
+	if (rc != EOK)
+		return 1;
+
+	return 0;
+}
+
+static void syntax_print(void)
+{
+	printf("syntax: pci [<options>]\n");
+	printf("options:\n"
+	    "\t--bridge <svc-name> Only devices under host bridge <svc-name>\n");
+}
+
+/** List PCI devices. */
+static errno_t pci_list(void)
+{
+	errno_t rc;
+	category_id_t pci_cat_id;
+	service_id_t *svc_ids = NULL;
+	size_t svc_cnt;
+	size_t i;
+
+	rc = loc_category_get_id("pci", &pci_cat_id, 0);
+	if (rc != EOK) {
+		printf("Error getting 'pci' category ID.\n");
+		goto error;
+	}
+
+	rc = loc_category_get_svcs(pci_cat_id, &svc_ids, &svc_cnt);
+	if (rc != EOK) {
+		printf("Error getting list of PCI services.\n");
+		goto error;
+	}
+
+	for (i = 0; i < svc_cnt; i++) {
+		if (i > 0)
+			putchar('\n');
+
+		rc = pci_list_bridge_id(svc_ids[i]);
+		if (rc != EOK)
+			goto error;
+	}
+
+	free(svc_ids);
+	return EOK;
+error:
+	if (svc_ids != NULL)
+		free(svc_ids);
+	return rc;
+}
+
+/** List PCI devices under a host bridge specified by name.
+ *
+ * @param svc_name PCI service name
+ * @return EOK on success or an error code
+ */
+static errno_t pci_list_bridge(const char *svc_name)
+{
+	errno_t rc;
+	service_id_t svc_id;
+
+	rc = loc_service_get_id(svc_name, &svc_id, 0);
+	if (rc != EOK) {
+		printf("Error looking up host bridge '%s'.\n", svc_name);
+		return rc;
+	}
+
+	return pci_list_bridge_id(svc_id);
+}
+
+/** List PCI devices under a host bridge specified by ID.
+ *
+ * @param svc_id PCI service ID
+ * @return EOK on success or an error code
+ */
+static errno_t pci_list_bridge_id(service_id_t svc_id)
+{
+	errno_t rc;
+	devman_handle_t *dev_ids = NULL;
+	size_t dev_cnt;
+	pci_dev_info_t dev_info;
+	size_t i;
+	pci_t *pci = NULL;
+	char *svc_name = NULL;
+	char *drv_name = NULL;
+	table_t *table = NULL;
+
+	drv_name = malloc(MAX_NAME_LENGTH);
+	if (drv_name == NULL) {
+		printf("Out of memory.\n");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	rc = table_create(&table);
+	if (rc != EOK) {
+		printf("Out of memory.\n");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	table_header_row(table);
+	table_printf(table, "Address\t" "Type\t" "Driver\n");
+
+	rc = loc_service_get_name(svc_id, &svc_name);
+	if (rc != EOK) {
+		printf("Error getting service name.\n");
+		goto error;
+	}
+
+	rc = pci_open(svc_id, &pci);
+	if (rc != EOK) {
+		printf("Error opening PCI service '%s'.\n", svc_name);
+		goto error;
+	}
+
+	rc = pci_get_devices(pci, &dev_ids, &dev_cnt);
+	if (rc != EOK) {
+		printf("Error getting PCI device list.\n");
+		goto error;
+	}
+
+	for (i = 0; i < dev_cnt; i++) {
+		rc = pci_dev_get_info(pci, dev_ids[i], &dev_info);
+		if (rc != EOK) {
+			printf("Error getting PCI device info.\n");
+			goto error;
+		}
+
+		rc = devman_fun_get_driver_name(dev_info.dev_handle,
+		    drv_name, MAX_NAME_LENGTH);
+		if (rc != EOK && rc != EINVAL) {
+			printf("Error getting driver name.\n");
+			goto error;
+		}
+
+		if (rc == EINVAL)
+			drv_name[0] = '\0';
+
+		table_printf(table, "%02x.%02x.%x\t" "%04x:%04x\t"
+		    "%s\n", dev_info.bus_num, dev_info.dev_num,
+		    dev_info.fn_num, dev_info.vendor_id,
+		    dev_info.device_id, drv_name);
+	}
+
+	printf("Device listing for host bridge %s:\n\n", svc_name);
+	rc = table_print_out(table, stdout);
+	if (rc != EOK) {
+		printf("Error printing table.\n");
+		goto error;
+	}
+
+	table_destroy(table);
+	table = NULL;
+	free(dev_ids);
+	dev_ids = NULL;
+	pci_close(pci);
+	pci = NULL;
+	free(svc_name);
+	svc_name = NULL;
+
+	free(drv_name);
+	return EOK;
+error:
+	if (drv_name != NULL)
+		free(drv_name);
+	if (table != NULL)
+		table_destroy(table);
+	if (pci != NULL)
+		pci_close(pci);
+	if (svc_name != NULL)
+		free(svc_name);
+	if (dev_ids != NULL)
+		free(dev_ids);
+	return rc;
+}
+
+/**
+ * @}
+ */
Index: pace/app/perf/Makefile
===================================================================
--- uspace/app/perf/Makefile	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,42 +1,0 @@
-#
-# Copyright (c) 2018 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.
-#
-
-USPACE_PREFIX = ../..
-
-LIBS = math
-
-BINARY = perf
-
-SOURCES = \
-	perf.c \
-	ipc/ns_ping.c \
-	ipc/ping_pong.c \
-	malloc/malloc1.c \
-	malloc/malloc2.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: pace/app/perf/doc/doxygroups.h
===================================================================
--- uspace/app/perf/doc/doxygroups.h	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,4 +1,0 @@
-/** @addtogroup perf perf
- * @brief User space performance measuring tool
- * @ingroup apps
- */
Index: pace/app/perf/ipc/ns_ping.c
===================================================================
--- uspace/app/perf/ipc/ns_ping.c	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,134 +1,0 @@
-/*
- * Copyright (c) 2018 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.
- */
-
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <ns.h>
-#include <async.h>
-#include <errno.h>
-#include "../perf.h"
-
-#define MIN_DURATION_SECS  10
-#define NUM_SAMPLES 10
-
-static errno_t ping_pong_measure(uint64_t niter, uint64_t *rduration)
-{
-	struct timespec start;
-	uint64_t count;
-
-	getuptime(&start);
-
-	for (count = 0; count < niter; count++) {
-		errno_t retval = ns_ping();
-
-		if (retval != EOK) {
-			printf("Error sending ping message.\n");
-			return EIO;
-		}
-	}
-
-	struct timespec now;
-	getuptime(&now);
-
-	*rduration = ts_sub_diff(&now, &start) / 1000;
-	return EOK;
-}
-
-static void ping_pong_report(uint64_t niter, uint64_t duration)
-{
-	printf("Completed %" PRIu64 " round trips in %" PRIu64 " us",
-	    niter, duration);
-
-	if (duration > 0) {
-		printf(", %" PRIu64 " rt/s.\n", niter * 1000 * 1000 / duration);
-	} else {
-		printf(".\n");
-	}
-}
-
-const char *bench_ns_ping(void)
-{
-	errno_t rc;
-	uint64_t duration;
-	uint64_t dsmp[NUM_SAMPLES];
-
-	printf("Warm up and determine work size...\n");
-
-	struct timespec start;
-	getuptime(&start);
-
-	uint64_t niter = 1;
-
-	while (true) {
-		rc = ping_pong_measure(niter, &duration);
-		if (rc != EOK)
-			return "Failed.";
-
-		ping_pong_report(niter, duration);
-
-		if (duration >= MIN_DURATION_SECS * 1000000)
-			break;
-
-		niter *= 2;
-	}
-
-	printf("Measure %d samples...\n", NUM_SAMPLES);
-
-	int i;
-
-	for (i = 0; i < NUM_SAMPLES; i++) {
-		rc = ping_pong_measure(niter, &dsmp[i]);
-		if (rc != EOK)
-			return "Failed.";
-
-		ping_pong_report(niter, dsmp[i]);
-	}
-
-	double sum = 0.0;
-
-	for (i = 0; i < NUM_SAMPLES; i++)
-		sum += (double)niter / ((double)dsmp[i] / 1000000.0l);
-
-	double avg = sum / NUM_SAMPLES;
-
-	double qd = 0.0;
-	double d;
-	for (i = 0; i < NUM_SAMPLES; i++) {
-		d = (double)niter / ((double)dsmp[i] / 1000000.0l) - avg;
-		qd += d * d;
-	}
-
-	double stddev = qd / (NUM_SAMPLES - 1); // XXX sqrt
-
-	printf("Average: %.0f rt/s Std.dev^2: %.0f rt/s Samples: %d\n",
-	    avg, stddev, NUM_SAMPLES);
-
-	return NULL;
-}
Index: pace/app/perf/ipc/ns_ping.def
===================================================================
--- uspace/app/perf/ipc/ns_ping.def	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,5 +1,0 @@
-{
-	"ns_ping",
-	"Name service IPC ping-pong benchmark",
-	&bench_ns_ping
-},
Index: pace/app/perf/ipc/ping_pong.c
===================================================================
--- uspace/app/perf/ipc/ping_pong.c	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,149 +1,0 @@
-/*
- * Copyright (c) 2009 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.
- */
-
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <ipc_test.h>
-#include <async.h>
-#include <errno.h>
-#include "../perf.h"
-
-#define MIN_DURATION_SECS  10
-#define NUM_SAMPLES 10
-
-static errno_t ping_pong_measure(ipc_test_t *test, uint64_t niter,
-    uint64_t *rduration)
-{
-	struct timespec start;
-	uint64_t count;
-
-	getuptime(&start);
-
-	for (count = 0; count < niter; count++) {
-		errno_t retval = ipc_test_ping(test);
-
-		if (retval != EOK) {
-			printf("Error sending ping message.\n");
-			return EIO;
-		}
-	}
-
-	struct timespec now;
-	getuptime(&now);
-
-	*rduration = ts_sub_diff(&now, &start) / 1000;
-	return EOK;
-}
-
-static void ping_pong_report(uint64_t niter, uint64_t duration)
-{
-	printf("Completed %" PRIu64 " round trips in %" PRIu64 " us",
-	    niter, duration);
-
-	if (duration > 0) {
-		printf(", %" PRIu64 " rt/s.\n", niter * 1000 * 1000 / duration);
-	} else {
-		printf(".\n");
-	}
-}
-
-const char *bench_ping_pong(void)
-{
-	errno_t rc;
-	uint64_t duration;
-	uint64_t dsmp[NUM_SAMPLES];
-	ipc_test_t *test;
-	const char *msg;
-
-	rc = ipc_test_create(&test);
-	if (rc != EOK)
-		return "Failed contacting IPC test server.";
-
-	printf("Warm up and determine work size...\n");
-
-	struct timespec start;
-	getuptime(&start);
-
-	uint64_t niter = 1;
-
-	while (true) {
-		rc = ping_pong_measure(test, niter, &duration);
-		if (rc != EOK) {
-			msg = "Failed.";
-			goto error;
-		}
-
-		ping_pong_report(niter, duration);
-
-		if (duration >= MIN_DURATION_SECS * 1000000)
-			break;
-
-		niter *= 2;
-	}
-
-	printf("Measure %d samples...\n", NUM_SAMPLES);
-
-	int i;
-
-	for (i = 0; i < NUM_SAMPLES; i++) {
-		rc = ping_pong_measure(test, niter, &dsmp[i]);
-		if (rc != EOK) {
-			msg = "Failed.";
-			goto error;
-		}
-
-		ping_pong_report(niter, dsmp[i]);
-	}
-
-	double sum = 0.0;
-
-	for (i = 0; i < NUM_SAMPLES; i++)
-		sum += (double)niter / ((double)dsmp[i] / 1000000.0l);
-
-	double avg = sum / NUM_SAMPLES;
-
-	double qd = 0.0;
-	double d;
-	for (i = 0; i < NUM_SAMPLES; i++) {
-		d = (double)niter / ((double)dsmp[i] / 1000000.0l) - avg;
-		qd += d * d;
-	}
-
-	double stddev = qd / (NUM_SAMPLES - 1); // XXX sqrt
-
-	printf("Average: %.0f rt/s Std.dev^2: %.0f rt/s Samples: %d\n",
-	    avg, stddev, NUM_SAMPLES);
-
-	ipc_test_destroy(test);
-	return NULL;
-error:
-	ipc_test_destroy(test);
-	return msg;
-}
Index: pace/app/perf/ipc/ping_pong.def
===================================================================
--- uspace/app/perf/ipc/ping_pong.def	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,5 +1,0 @@
-{
-	"ping_pong",
-	"IPC ping-pong benchmark",
-	&bench_ping_pong
-},
Index: pace/app/perf/malloc/malloc1.c
===================================================================
--- uspace/app/perf/malloc/malloc1.c	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,138 +1,0 @@
-/*
- * Copyright (c) 2018 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.
- */
-
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <errno.h>
-#include "../perf.h"
-
-#define MIN_DURATION_SECS  10
-#define NUM_SAMPLES 10
-
-static errno_t malloc1_measure(uint64_t niter, uint64_t *rduration)
-{
-	struct timespec start;
-	uint64_t count;
-	void *p;
-
-	getuptime(&start);
-
-	for (count = 0; count < niter; count++) {
-		p = malloc(1);
-		if (p == NULL)
-			return ENOMEM;
-		free(p);
-	}
-
-	struct timespec now;
-	getuptime(&now);
-
-	*rduration = ts_sub_diff(&now, &start) / 1000;
-	return EOK;
-}
-
-static void malloc1_report(uint64_t niter, uint64_t duration)
-{
-	printf("Completed %" PRIu64 " allocations and deallocations in %" PRIu64 " us",
-	    niter, duration);
-
-	if (duration > 0) {
-		printf(", %" PRIu64 " cycles/s.\n", niter * 1000 * 1000 / duration);
-	} else {
-		printf(".\n");
-	}
-}
-
-const char *bench_malloc1(void)
-{
-	errno_t rc;
-	uint64_t duration;
-	uint64_t dsmp[NUM_SAMPLES];
-	const char *msg;
-
-	printf("Warm up and determine work size...\n");
-
-	struct timespec start;
-	getuptime(&start);
-
-	uint64_t niter = 1;
-
-	while (true) {
-		rc = malloc1_measure(niter, &duration);
-		if (rc != EOK) {
-			msg = "Failed.";
-			goto error;
-		}
-
-		malloc1_report(niter, duration);
-
-		if (duration >= MIN_DURATION_SECS * 1000000)
-			break;
-
-		niter *= 2;
-	}
-
-	printf("Measure %d samples...\n", NUM_SAMPLES);
-
-	int i;
-
-	for (i = 0; i < NUM_SAMPLES; i++) {
-		rc = malloc1_measure(niter, &dsmp[i]);
-		if (rc != EOK) {
-			msg = "Failed.";
-			goto error;
-		}
-
-		malloc1_report(niter, dsmp[i]);
-	}
-
-	double sum = 0.0;
-
-	for (i = 0; i < NUM_SAMPLES; i++)
-		sum += (double)niter / ((double)dsmp[i] / 1000000.0l);
-
-	double avg = sum / NUM_SAMPLES;
-
-	double qd = 0.0;
-	double d;
-	for (i = 0; i < NUM_SAMPLES; i++) {
-		d = (double)niter / ((double)dsmp[i] / 1000000.0l) - avg;
-		qd += d * d;
-	}
-
-	double stddev = qd / (NUM_SAMPLES - 1); // XXX sqrt
-
-	printf("Average: %.0f cycles/s Std.dev^2: %.0f cycles/s Samples: %d\n",
-	    avg, stddev, NUM_SAMPLES);
-
-	return NULL;
-error:
-	return msg;
-}
Index: pace/app/perf/malloc/malloc1.def
===================================================================
--- uspace/app/perf/malloc/malloc1.def	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,5 +1,0 @@
-{
-	"malloc1",
-	"User-space memory allocator benchmark, repeatedly allocate one block",
-	&bench_malloc1
-},
Index: pace/app/perf/malloc/malloc2.c
===================================================================
--- uspace/app/perf/malloc/malloc2.c	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,146 +1,0 @@
-/*
- * Copyright (c) 2018 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.
- */
-
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <errno.h>
-#include "../perf.h"
-
-#define MIN_DURATION_SECS  10
-#define NUM_SAMPLES 10
-
-static errno_t malloc2_measure(uint64_t niter, uint64_t *rduration)
-{
-	struct timespec start;
-	uint64_t count;
-	void **p;
-
-	getuptime(&start);
-
-	p = malloc(niter * sizeof(void *));
-	if (p == NULL)
-		return ENOMEM;
-
-	for (count = 0; count < niter; count++) {
-		p[count] = malloc(1);
-		if (p[count] == NULL)
-			return ENOMEM;
-	}
-
-	for (count = 0; count < niter; count++)
-		free(p[count]);
-
-	free(p);
-
-	struct timespec now;
-	getuptime(&now);
-
-	*rduration = ts_sub_diff(&now, &start) / 1000;
-	return EOK;
-}
-
-static void malloc2_report(uint64_t niter, uint64_t duration)
-{
-	printf("Completed %" PRIu64 " allocations and deallocations in %" PRIu64 " us",
-	    niter, duration);
-
-	if (duration > 0) {
-		printf(", %" PRIu64 " cycles/s.\n", niter * 1000 * 1000 / duration);
-	} else {
-		printf(".\n");
-	}
-}
-
-const char *bench_malloc2(void)
-{
-	errno_t rc;
-	uint64_t duration;
-	uint64_t dsmp[NUM_SAMPLES];
-	const char *msg;
-
-	printf("Warm up and determine work size...\n");
-
-	struct timespec start;
-	getuptime(&start);
-
-	uint64_t niter = 1;
-
-	while (true) {
-		rc = malloc2_measure(niter, &duration);
-		if (rc != EOK) {
-			msg = "Failed.";
-			goto error;
-		}
-
-		malloc2_report(niter, duration);
-
-		if (duration >= MIN_DURATION_SECS * 1000000)
-			break;
-
-		niter *= 2;
-	}
-
-	printf("Measure %d samples...\n", NUM_SAMPLES);
-
-	int i;
-
-	for (i = 0; i < NUM_SAMPLES; i++) {
-		rc = malloc2_measure(niter, &dsmp[i]);
-		if (rc != EOK) {
-			msg = "Failed.";
-			goto error;
-		}
-
-		malloc2_report(niter, dsmp[i]);
-	}
-
-	double sum = 0.0;
-
-	for (i = 0; i < NUM_SAMPLES; i++)
-		sum += (double)niter / ((double)dsmp[i] / 1000000.0l);
-
-	double avg = sum / NUM_SAMPLES;
-
-	double qd = 0.0;
-	double d;
-	for (i = 0; i < NUM_SAMPLES; i++) {
-		d = (double)niter / ((double)dsmp[i] / 1000000.0l) - avg;
-		qd += d * d;
-	}
-
-	double stddev = qd / (NUM_SAMPLES - 1); // XXX sqrt
-
-	printf("Average: %.0f cycles/s Std.dev^2: %.0f cycles/s Samples: %d\n",
-	    avg, stddev, NUM_SAMPLES);
-
-	return NULL;
-error:
-	return msg;
-}
Index: pace/app/perf/malloc/malloc2.def
===================================================================
--- uspace/app/perf/malloc/malloc2.def	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,5 +1,0 @@
-{
-	"malloc2",
-	"User-space memory allocator benchmark, allocate many small blocks",
-	&bench_malloc2
-},
Index: pace/app/perf/perf.c
===================================================================
--- uspace/app/perf/perf.c	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,149 +1,0 @@
-/*
- * Copyright (c) 2018 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 perf
- * @{
- */
-/**
- * @file
- */
-
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <str.h>
-#include "perf.h"
-
-benchmark_t benchmarks[] = {
-#include "ipc/ns_ping.def"
-#include "ipc/ping_pong.def"
-#include "malloc/malloc1.def"
-#include "malloc/malloc2.def"
-	{ NULL, NULL, NULL }
-};
-
-static bool run_benchmark(benchmark_t *bench)
-{
-	/* Execute the benchmarl */
-	const char *ret = bench->entry();
-
-	if (ret == NULL) {
-		printf("\nBenchmark completed\n");
-		return true;
-	}
-
-	printf("\n%s\n", ret);
-	return false;
-}
-
-static int run_benchmarks(void)
-{
-	benchmark_t *bench;
-	unsigned int i = 0;
-	unsigned int n = 0;
-
-	char *failed_names = NULL;
-
-	printf("\n*** Running all benchmarks ***\n\n");
-
-	for (bench = benchmarks; bench->name != NULL; bench++) {
-		printf("%s (%s)\n", bench->name, bench->desc);
-		if (run_benchmark(bench)) {
-			i++;
-			continue;
-		}
-
-		if (!failed_names) {
-			failed_names = str_dup(bench->name);
-		} else {
-			char *f = NULL;
-			asprintf(&f, "%s, %s", failed_names, bench->name);
-			if (!f) {
-				printf("Out of memory.\n");
-				abort();
-			}
-			free(failed_names);
-			failed_names = f;
-		}
-		n++;
-	}
-
-	printf("\nCompleted, %u benchmarks run, %u succeeded.\n", i + n, i);
-	if (failed_names)
-		printf("Failed benchmarks: %s\n", failed_names);
-
-	return n;
-}
-
-static void list_benchmarks(void)
-{
-	size_t len = 0;
-	benchmark_t *bench;
-	for (bench = benchmarks; bench->name != NULL; bench++) {
-		if (str_length(bench->name) > len)
-			len = str_length(bench->name);
-	}
-
-	unsigned int _len = (unsigned int) len;
-	if ((_len != len) || (((int) _len) < 0)) {
-		printf("Command length overflow\n");
-		return;
-	}
-
-	for (bench = benchmarks; bench->name != NULL; bench++)
-		printf("%-*s %s\n", _len, bench->name, bench->desc);
-
-	printf("%-*s Run all benchmarks\n", _len, "*");
-}
-
-int main(int argc, char *argv[])
-{
-	if (argc < 2) {
-		printf("Usage:\n\n");
-		printf("%s <benchmark>\n\n", argv[0]);
-		list_benchmarks();
-		return 0;
-	}
-
-	if (str_cmp(argv[1], "*") == 0) {
-		return run_benchmarks();
-	}
-
-	benchmark_t *bench;
-	for (bench = benchmarks; bench->name != NULL; bench++) {
-		if (str_cmp(argv[1], bench->name) == 0) {
-			return (run_benchmark(bench) ? 0 : -1);
-		}
-	}
-
-	printf("Unknown benchmark \"%s\"\n", argv[1]);
-	return -2;
-}
-
-/** @}
- */
Index: pace/app/perf/perf.h
===================================================================
--- uspace/app/perf/perf.h	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,58 +1,0 @@
-/*
- * Copyright (c) 2018 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 perf
- * @{
- */
-/** @file
- */
-
-#ifndef PERF_H_
-#define PERF_H_
-
-#include <stdbool.h>
-
-typedef const char *(*benchmark_entry_t)(void);
-
-typedef struct {
-	const char *name;
-	const char *desc;
-	benchmark_entry_t entry;
-} benchmark_t;
-
-extern const char *bench_malloc1(void);
-extern const char *bench_malloc2(void);
-extern const char *bench_ns_ping(void);
-extern const char *bench_ping_pong(void);
-
-extern benchmark_t benchmarks[];
-
-#endif
-
-/** @}
- */
Index: uspace/app/sbi/src/bigint.c
===================================================================
--- uspace/app/sbi/src/bigint.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/sbi/src/bigint.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -379,5 +379,5 @@
 	printf("Convert bigint to string.\n");
 #endif
-	static_assert(BIGINT_BASE >= 10);
+	static_assert(BIGINT_BASE >= 10, "");
 
 	/* Compute number of characters. */
Index: uspace/app/sportdmp/sportdmp.c
===================================================================
--- uspace/app/sportdmp/sportdmp.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/sportdmp/sportdmp.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -146,5 +146,6 @@
 
 	while (true) {
-		rc = chardev_read(chardev, buf, BUF_SIZE, &nread);
+		rc = chardev_read(chardev, buf, BUF_SIZE, &nread,
+		    chardev_f_none);
 		for (size_t i = 0; i < nread; i++) {
 			printf("%02hhx ", buf[i]);
Index: uspace/app/sysinst/rdimg.c
===================================================================
--- uspace/app/sysinst/rdimg.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/sysinst/rdimg.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,4 +34,5 @@
 
 #include <errno.h>
+#include <fibril.h>
 #include <stdio.h>
 #include <stdlib.h>
Index: uspace/app/sysinst/sysinst.c
===================================================================
--- uspace/app/sysinst/sysinst.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/sysinst/sysinst.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -62,5 +62,5 @@
  * in Grub notation).
  */
-#define DEFAULT_DEV "devices/\\hw\\pci0\\00:01.0\\ata-c1\\d0"
+#define DEFAULT_DEV "devices/\\hw\\sys\\00:01.0\\ata-c1\\d0"
 //#define DEFAULT_DEV "devices/\\hw\\pci0\\00:01.2\\uhci_rh\\usb01_a1\\mass-storage0\\l0"
 /** Volume label for the new file system */
Index: uspace/app/taskdump/symtab.c
===================================================================
--- uspace/app/taskdump/symtab.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/taskdump/symtab.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -215,5 +215,5 @@
 			continue;
 
-		stype = ELF_ST_TYPE(st->sym[i].st_info);
+		stype = elf_st_type(st->sym[i].st_info);
 		if (stype != STT_OBJECT && stype != STT_FUNC)
 			continue;
@@ -257,5 +257,5 @@
 			continue;
 
-		stype = ELF_ST_TYPE(st->sym[i].st_info);
+		stype = elf_st_type(st->sym[i].st_info);
 		if (stype != STT_OBJECT && stype != STT_FUNC &&
 		    stype != STT_NOTYPE) {
Index: uspace/app/tester/chardev/chardev1.c
===================================================================
--- uspace/app/tester/chardev/chardev1.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/tester/chardev/chardev1.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jiri Svoboda
+ * Copyright (c) 2019 Jiri Svoboda
  * All rights reserved.
  *
@@ -76,5 +76,6 @@
 	TPRINTF("Sent %zu bytes\n", nbytes);
 
-	rc = chardev_read(chardev, small_buffer, SMALL_BUFFER_SIZE, &nbytes);
+	rc = chardev_read(chardev, small_buffer, SMALL_BUFFER_SIZE, &nbytes,
+	    chardev_f_none);
 	if (rc != EOK) {
 		chardev_close(chardev);
@@ -128,5 +129,6 @@
 	TPRINTF("Sent %zu bytes\n", nbytes);
 
-	rc = chardev_read(chardev, large_buffer, LARGE_BUFFER_SIZE, &nbytes);
+	rc = chardev_read(chardev, large_buffer, LARGE_BUFFER_SIZE, &nbytes,
+	    chardev_f_none);
 	if (rc != EOK) {
 		chardev_close(chardev);
@@ -181,5 +183,6 @@
 	    str_error_name(rc));
 
-	rc = chardev_read(chardev, small_buffer, SMALL_BUFFER_SIZE, &nbytes);
+	rc = chardev_read(chardev, small_buffer, SMALL_BUFFER_SIZE, &nbytes,
+	    chardev_f_none);
 	if (rc != EIO || nbytes != 1) {
 		chardev_close(chardev);
Index: uspace/app/tester/hw/serial/serial1.c
===================================================================
--- uspace/app/tester/hw/serial/serial1.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/tester/hw/serial/serial1.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -136,5 +136,6 @@
 	while (total < cnt) {
 
-		rc = chardev_read(chardev, buf, cnt - total, &nread);
+		rc = chardev_read(chardev, buf, cnt - total, &nread,
+		    chardev_f_none);
 		if (rc != EOK) {
 			(void) serial_set_comm_props(serial, old_baud,
Index: uspace/app/tester/stdio/logger2.c
===================================================================
--- uspace/app/tester/stdio/logger2.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/tester/stdio/logger2.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,6 +30,6 @@
 #include <stdlib.h>
 #include <errno.h>
+#include <fibril.h>
 #include <io/log.h>
-#include <async.h>
 #include "../tester.h"
 
Index: uspace/app/tester/tester.c
===================================================================
--- uspace/app/tester/tester.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/tester/tester.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,4 +35,5 @@
  */
 
+#include <assert.h>
 #include <stdio.h>
 #include <stddef.h>
@@ -40,4 +41,5 @@
 #include <str.h>
 #include <io/log.h>
+#include <types/casting.h>
 #include "tester.h"
 
@@ -144,15 +146,11 @@
 	}
 
-	unsigned int _len = (unsigned int) len;
-	if ((_len != len) || (((int) _len) < 0)) {
-		printf("Command length overflow\n");
-		return;
-	}
+	assert(can_cast_size_t_to_int(len) && "test name length overflow");
 
 	for (test = tests; test->name != NULL; test++)
-		printf("%-*s %s%s\n", _len, test->name, test->desc,
+		printf("%-*s %s%s\n", (int) len, test->name, test->desc,
 		    (test->safe ? "" : " (unsafe)"));
 
-	printf("%-*s Run all safe tests\n", _len, "*");
+	printf("%-*s Run all safe tests\n", (int) len, "*");
 }
 
Index: uspace/app/trace/ipcp.c
===================================================================
--- uspace/app/trace/ipcp.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/trace/ipcp.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -72,8 +72,8 @@
 proto_t	*proto_unknown;		/**< Protocol with no known methods. */
 
-static size_t pending_call_key_hash(void *key)
-{
-	cap_call_handle_t *chandle = (cap_call_handle_t *) key;
-	return CAP_HANDLE_RAW(*chandle);
+static size_t pending_call_key_hash(const void *key)
+{
+	const cap_call_handle_t *chandle = key;
+	return cap_handle_raw(*chandle);
 }
 
@@ -81,10 +81,10 @@
 {
 	pending_call_t *hs = hash_table_get_inst(item, pending_call_t, link);
-	return CAP_HANDLE_RAW(hs->call_handle);
-}
-
-static bool pending_call_key_equal(void *key, const ht_link_t *item)
-{
-	cap_call_handle_t *chandle = (cap_call_handle_t *) key;
+	return cap_handle_raw(hs->call_handle);
+}
+
+static bool pending_call_key_equal(const void *key, const ht_link_t *item)
+{
+	const cap_call_handle_t *chandle = key;
 	pending_call_t *hs = hash_table_get_inst(item, pending_call_t, link);
 
@@ -104,16 +104,16 @@
 	// XXX: there is no longer a limit on the number of phones as phones are
 	// now handled using capabilities
-	if (CAP_HANDLE_RAW(phone) < 0 || CAP_HANDLE_RAW(phone) >= MAX_PHONE)
+	if (cap_handle_raw(phone) < 0 || cap_handle_raw(phone) >= MAX_PHONE)
 		return;
-	connections[CAP_HANDLE_RAW(phone)].server = server;
-	connections[CAP_HANDLE_RAW(phone)].proto = proto;
-	have_conn[CAP_HANDLE_RAW(phone)] = 1;
+	connections[cap_handle_raw(phone)].server = server;
+	connections[cap_handle_raw(phone)].proto = proto;
+	have_conn[cap_handle_raw(phone)] = 1;
 }
 
 void ipcp_connection_clear(cap_phone_handle_t phone)
 {
-	have_conn[CAP_HANDLE_RAW(phone)] = 0;
-	connections[CAP_HANDLE_RAW(phone)].server = 0;
-	connections[CAP_HANDLE_RAW(phone)].proto = NULL;
+	have_conn[cap_handle_raw(phone)] = 0;
+	connections[cap_handle_raw(phone)].server = 0;
+	connections[cap_handle_raw(phone)].proto = NULL;
 }
 
@@ -184,6 +184,6 @@
 	int i;
 
-	if (have_conn[CAP_HANDLE_RAW(phandle)])
-		proto = connections[CAP_HANDLE_RAW(phandle)].proto;
+	if (have_conn[cap_handle_raw(phandle)])
+		proto = connections[cap_handle_raw(phandle)].proto;
 	else
 		proto = NULL;
@@ -194,5 +194,5 @@
 		printf("Call handle: %p, phone: %p, proto: %s, method: ",
 		    chandle, phandle, (proto ? proto->name : "n/a"));
-		ipc_m_print(proto, IPC_GET_IMETHOD(*call));
+		ipc_m_print(proto, ipc_get_imethod(call));
 		printf(" args: (%" PRIun ", %" PRIun ", %" PRIun ", "
 		    "%" PRIun ", %" PRIun ")\n",
@@ -203,5 +203,5 @@
 
 		if (proto != NULL) {
-			oper = proto_get_oper(proto, IPC_GET_IMETHOD(*call));
+			oper = proto_get_oper(proto, ipc_get_imethod(call));
 		} else {
 			oper = NULL;
@@ -262,6 +262,6 @@
 
 	phone = pcall->phone_handle;
-	method = IPC_GET_IMETHOD(pcall->question);
-	retval = IPC_GET_RETVAL(*answer);
+	method = ipc_get_imethod(&pcall->question);
+	retval = ipc_get_retval(answer);
 
 	resp = answer->args;
@@ -270,7 +270,7 @@
 		printf("Response to %p: retval=%s, args = (%" PRIun ", "
 		    "%" PRIun ", %" PRIun ", %" PRIun ", %" PRIun ")\n",
-		    call_handle, str_error_name(retval), IPC_GET_ARG1(*answer),
-		    IPC_GET_ARG2(*answer), IPC_GET_ARG3(*answer),
-		    IPC_GET_ARG4(*answer), IPC_GET_ARG5(*answer));
+		    call_handle, str_error_name(retval), ipc_get_arg1(answer),
+		    ipc_get_arg2(answer), ipc_get_arg3(answer),
+		    ipc_get_arg4(answer), ipc_get_arg5(answer));
 	}
 
@@ -305,10 +305,10 @@
 	    (retval == 0)) {
 		/* Connected to a service (through NS) */
-		service = IPC_GET_ARG2(pcall->question);
+		service = ipc_get_arg2(&pcall->question);
 		proto = proto_get_by_srv(service);
 		if (proto == NULL)
 			proto = proto_unknown;
 
-		cphone = (cap_phone_handle_t) IPC_GET_ARG5(*answer);
+		cphone = (cap_phone_handle_t) ipc_get_arg5(answer);
 		if ((display_mask & DM_SYSTEM) != 0) {
 			printf("Registering connection (phone %p, protocol: %s)\n", cphone,
Index: uspace/app/trace/proto.c
===================================================================
--- uspace/app/trace/proto.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/trace/proto.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -57,7 +57,8 @@
 /* Hash table operations. */
 
-static size_t srv_proto_key_hash(void *key)
-{
-	return *(int *)key;
+static size_t srv_proto_key_hash(const void *key)
+{
+	const int *n = key;
+	return *n;
 }
 
@@ -68,8 +69,9 @@
 }
 
-static bool srv_proto_key_equal(void *key, const ht_link_t *item)
-{
+static bool srv_proto_key_equal(const void *key, const ht_link_t *item)
+{
+	const int *n = key;
 	srv_proto_t *sp = hash_table_get_inst(item, srv_proto_t, link);
-	return sp->srv == *(int *)key;
+	return sp->srv == *n;
 }
 
@@ -82,7 +84,8 @@
 };
 
-static size_t method_oper_key_hash(void *key)
-{
-	return *(int *)key;
+static size_t method_oper_key_hash(const void *key)
+{
+	const int *n = key;
+	return *n;
 }
 
@@ -93,8 +96,9 @@
 }
 
-static bool method_oper_key_equal(void *key, const ht_link_t *item)
-{
+static bool method_oper_key_equal(const void *key, const ht_link_t *item)
+{
+	const int *n = key;
 	method_oper_t *mo = hash_table_get_inst(item, method_oper_t, link);
-	return mo->method == *(int *)key;
+	return mo->method == *n;
 }
 
Index: uspace/app/trace/trace.c
===================================================================
--- uspace/app/trace/trace.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/trace/trace.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -302,10 +302,10 @@
 	phandle = (cap_phone_handle_t) sc_args[0];
 
-	IPC_SET_IMETHOD(call, sc_args[1]);
-	IPC_SET_ARG1(call, sc_args[2]);
-	IPC_SET_ARG2(call, sc_args[3]);
-	IPC_SET_ARG3(call, sc_args[4]);
-	IPC_SET_ARG4(call, sc_args[5]);
-	IPC_SET_ARG5(call, 0);
+	ipc_set_imethod(&call, sc_args[1]);
+	ipc_set_arg1(&call, sc_args[2]);
+	ipc_set_arg2(&call, sc_args[3]);
+	ipc_set_arg3(&call, sc_args[4]);
+	ipc_set_arg4(&call, sc_args[5]);
+	ipc_set_arg5(&call, 0);
 
 	ipcp_call_out(phandle, &call, 0);
Index: uspace/app/wavplay/dplay.c
===================================================================
--- uspace/app/wavplay/dplay.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/wavplay/dplay.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -103,8 +103,8 @@
 		async_get_call(&call);
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case PCM_EVENT_PLAYBACK_STARTED:
 		case PCM_EVENT_FRAMES_PLAYED:
-			printf("%" PRIun " frames: ", IPC_GET_ARG1(call));
+			printf("%" PRIun " frames: ", ipc_get_arg1(&call));
 			async_answer_0(&call, EOK);
 			break;
@@ -118,5 +118,5 @@
 			return;
 		default:
-			printf("Unknown event %" PRIun ".\n", IPC_GET_IMETHOD(call));
+			printf("Unknown event %" PRIun ".\n", ipc_get_imethod(&call));
 			async_answer_0(&call, ENOTSUP);
 			continue;
Index: uspace/app/wavplay/drec.c
===================================================================
--- uspace/app/wavplay/drec.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/wavplay/drec.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -36,4 +36,5 @@
 #include <assert.h>
 #include <errno.h>
+#include <fibril.h>
 #include <str_error.h>
 #include <audio_pcm_iface.h>
@@ -88,6 +89,6 @@
  * Writes recorded data.
  *
- * @param icall Poitner to IPC call structure.
- * @param arg   Argument. Poitner to recording helper structure.
+ * @param icall Pointer to IPC call structure.
+ * @param arg   Argument. Pointer to recording helper structure.
  *
  */
@@ -102,5 +103,5 @@
 		async_get_call(&call);
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case PCM_EVENT_CAPTURE_TERMINATED:
 			printf("Recording terminated\n");
@@ -108,8 +109,8 @@
 			break;
 		case PCM_EVENT_FRAMES_CAPTURED:
-			printf("%" PRIun " frames\n", IPC_GET_ARG1(call));
+			printf("%" PRIun " frames\n", ipc_get_arg1(&call));
 			break;
 		default:
-			printf("Unknown event %" PRIun ".\n", IPC_GET_IMETHOD(call));
+			printf("Unknown event %" PRIun ".\n", ipc_get_imethod(&call));
 			async_answer_0(&call, ENOTSUP);
 			continue;
Index: uspace/app/wavplay/main.c
===================================================================
--- uspace/app/wavplay/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/wavplay/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -119,5 +119,5 @@
  * @return Error code
  */
-static errno_t hplay(const char *filename)
+static errno_t hplay(const char *filename, const char *target)
 {
 	printf("Hound playback: %s\n", filename);
@@ -158,8 +158,18 @@
 	}
 
-	ret = hound_context_connect_target(hound, HOUND_DEFAULT_TARGET);
+	ret = hound_context_connect_target(hound, target);
 	if (ret != EOK) {
-		printf("Failed to connect to default target: %s\n",
+		printf("Failed to connect to target '%s': %s\n", target,
 		    str_error(ret));
+
+		char **names = NULL;
+		size_t count = 0;
+		ret = hound_context_get_available_targets(hound, &names, &count);
+		if (ret == EOK) {
+			printf("Available targets:\n");
+			for (size_t i = 0; i < count; i++)
+				printf(" - %s\n", names[i]);
+		}
+
 		hound_context_destroy(hound);
 		fclose(source);
@@ -215,4 +225,5 @@
 	{ "parallel", no_argument, 0, 'p' },
 	{ "record", no_argument, 0, 'r' },
+	{ "target", required_argument, 0, 't' },
 	{ "help", no_argument, 0, 'h' },
 	{ 0, 0, 0, 0 }
@@ -230,6 +241,7 @@
 	printf("\t -r, --record\t Start recording instead of playback. "
 	    "(Not implemented)\n");
-	printf("\t -d, --device\t Use specified device instead of the sound "
-	    "service. Use location path or a special device `default'\n");
+	printf("\t -d, --device\t Direct output to specified device instead of "
+	    "the sound service. Use location path or a special device `default'\n");
+	printf("\t -t, --target\t Output to the specified audio target.\n");
 	printf("\t -p, --parallel\t Play given files in parallel instead of "
 	    "sequentially (does not work with -d).\n");
@@ -239,4 +251,5 @@
 {
 	const char *device = "default";
+	const char *target = HOUND_DEFAULT_TARGET;
 	int idx = 0;
 	bool direct = false, record = false, parallel = false;
@@ -246,5 +259,5 @@
 	/* Parse command line options */
 	while (ret != -1) {
-		ret = getopt_long(argc, argv, "d:prh", opts, &idx);
+		ret = getopt_long(argc, argv, "d:prt:h", opts, &idx);
 		switch (ret) {
 		case 'd':
@@ -257,4 +270,7 @@
 		case 'p':
 			parallel = true;
+			break;
+		case 't':
+			target = optarg;
 			break;
 		case 'h':
@@ -334,5 +350,5 @@
 				fibril_add_ready(fid);
 			} else {
-				hplay(file);
+				hplay(file, target);
 			}
 		}
Index: pace/doc/main_page.h
===================================================================
--- uspace/doc/main_page.h	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,12 +1,0 @@
-/**
- * @mainpage HelenOS Operating System Source Code Reference
- *
- * HelenOS is a portable microkernel-based multiserver operating system designed and implemented from scratch. It decomposes key operating system functionality such as file systems, networking, device drivers and graphical user interface into a collection of fine-grained user space components that interact with each other via message passing. A failure or crash of one component does not directly harm others. HelenOS is therefore flexible, modular, extensible, fault tolerant and easy to understand.
- *
- * HelenOS does not aim to be a clone of any existing operating system and trades compatibility with legacy APIs for cleaner design. Most of HelenOS components have been made to order specifically for HelenOS so that its essential parts can stay free of adaptation layers, glue code, franken-components and the maintenance burden incurred by them.
- *
- * HelenOS runs on seven different processor architectures and machines ranging from embedded ARM devices and single-board computers through multicore 32-bit and 64-bit desktop PCs to 64-bit Itanium and SPARC rack-mount servers.
- *
- * HelenOS is open source, free software. Its source code is available under the BSD license. Some third-party components are licensed under GPL.
- *
- */
Index: uspace/drv/audio/hdaudio/hdaudio.c
===================================================================
--- uspace/drv/audio/hdaudio/hdaudio.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/audio/hdaudio/hdaudio.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -151,4 +151,5 @@
 {
 	ddf_fun_t *fun_pcm = NULL;
+	bool bound = false;
 	hda_t *hda = NULL;
 	hw_res_list_parsed_t res;
@@ -299,9 +300,17 @@
 	}
 
-	ddf_fun_add_to_category(fun_pcm, "audio-pcm");
+	bound = true;
+
+	rc = ddf_fun_add_to_category(fun_pcm, "audio-pcm");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed adding function to audio-pcm category.");
+		goto error;
+	}
 
 	hw_res_list_parsed_clean(&res);
 	return EOK;
 error:
+	if (bound)
+		ddf_fun_unbind(fun_pcm);
 	if (fun_pcm != NULL)
 		ddf_fun_destroy(fun_pcm);
@@ -376,5 +385,5 @@
 	hda_ctl_interrupt(hda->ctl);
 
-	if (IPC_GET_ARG3(*icall) != 0) {
+	if (ipc_get_arg3(icall) != 0) {
 		/* Buffer completed */
 		hda_lock(hda);
Index: uspace/drv/audio/hdaudio/hdaudio.ma
===================================================================
--- uspace/drv/audio/hdaudio/hdaudio.ma	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/audio/hdaudio/hdaudio.ma	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,3 +1,4 @@
 10 pci/ven=1002&dev=4383
+10 pci/ven=8086&dev=160c
 10 pci/ven=8086&dev=1e20
 10 pci/ven=8086&dev=2668
@@ -5,2 +6,3 @@
 10 pci/ven=8086&dev=1c20
 10 pci/ven=8086&dev=293e
+10 pci/ven=8086&dev=9ca0
Index: uspace/drv/block/ahci/ahci.c
===================================================================
--- uspace/drv/block/ahci/ahci.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/block/ahci/ahci.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -816,5 +816,5 @@
  *
  * @param sata     SATA device structure.
- * @param phys     Physical addres of buffer with sector data.
+ * @param phys     Physical address of buffer with sector data.
  * @param blocknum Block number to write.
  *
@@ -897,6 +897,6 @@
 {
 	ahci_dev_t *ahci = dev_ahci_dev(dev);
-	unsigned int port = IPC_GET_ARG1(*icall);
-	ahci_port_is_t pxis = IPC_GET_ARG2(*icall);
+	unsigned int port = ipc_get_arg1(icall);
+	ahci_port_is_t pxis = ipc_get_arg2(icall);
 
 	if (port >= AHCI_MAX_PORTS)
Index: uspace/drv/block/ata_bd/main.c
===================================================================
--- uspace/drv/block/ata_bd/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/block/ata_bd/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -162,4 +162,5 @@
 	ddf_fun_t *fun = NULL;
 	ata_fun_t *afun = NULL;
+	bool bound = false;
 
 	fun_name = ata_fun_name(disk);
@@ -202,5 +203,12 @@
 	}
 
-	ddf_fun_add_to_category(fun, "disk");
+	bound = true;
+
+	rc = ddf_fun_add_to_category(fun, "disk");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed adding function %s to "
+		    "category 'disk': %s", fun_name, str_error(rc));
+		goto error;
+	}
 
 	free(fun_name);
@@ -208,4 +216,6 @@
 	return EOK;
 error:
+	if (bound)
+		ddf_fun_unbind(fun);
 	if (fun != NULL)
 		ddf_fun_destroy(fun);
Index: uspace/drv/block/ddisk/ddisk.c
===================================================================
--- uspace/drv/block/ddisk/ddisk.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/block/ddisk/ddisk.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -179,5 +179,5 @@
 {
 	ddf_msg(LVL_DEBUG, "ddisk_irq_handler(), status=%" PRIx32,
-	    (uint32_t) IPC_GET_ARG1(*icall));
+	    (uint32_t) ipc_get_arg1(icall));
 
 	ddisk_t *ddisk = (ddisk_t *) ddf_dev_data_get(dev);
@@ -319,4 +319,5 @@
 	errno_t rc;
 	ddf_fun_t *fun = NULL;
+	bool bound = false;
 
 	fun = ddf_fun_create(ddisk->dev, fun_exposed, DDISK_FUN_NAME);
@@ -337,9 +338,18 @@
 	}
 
-	ddf_fun_add_to_category(fun, "disk");
+	bound = true;
+
+	rc = ddf_fun_add_to_category(fun, "disk");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed adding function %s to category "
+		    "'disk': %s.\n", DDISK_FUN_NAME, str_error(rc));
+		goto error;
+	}
 	ddisk->fun = fun;
 
 	return EOK;
 error:
+	if (bound)
+		ddf_fun_unbind(fun);
 	if (fun != NULL)
 		ddf_fun_destroy(fun);
Index: uspace/drv/block/usbmast/main.c
===================================================================
--- uspace/drv/block/usbmast/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/block/usbmast/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -223,4 +223,5 @@
 	ddf_fun_t *fun = NULL;
 	usbmast_fun_t *mfun = NULL;
+	bool bound = false;
 
 	if (asprintf(&fun_name, "l%u", lun) < 0) {
@@ -299,5 +300,12 @@
 	}
 
-	ddf_fun_add_to_category(fun, "disk");
+	bound = true;
+
+	rc = ddf_fun_add_to_category(fun, "disk");
+	if (rc != EOK) {
+		usb_log_error("Failed to add function %s to category 'disk': %s.",
+		    fun_name, str_error(rc));
+		goto error;
+	}
 
 	free(fun_name);
@@ -308,4 +316,6 @@
 	/* Error cleanup */
 error:
+	if (bound)
+		ddf_fun_unbind(fun);
 	if (fun != NULL)
 		ddf_fun_destroy(fun);
Index: uspace/drv/block/virtio-blk/Makefile
===================================================================
--- uspace/drv/block/virtio-blk/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/block/virtio-blk/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2019 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 = drv scsi virtio
+BINARY = virtio-blk
+
+SOURCES = \
+	virtio-blk.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/block/virtio-blk/virtio-blk.c
===================================================================
--- uspace/drv/block/virtio-blk/virtio-blk.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/block/virtio-blk/virtio-blk.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,494 @@
+/*
+ * Copyright (c) 2019 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 "virtio-blk.h"
+
+#include <stdio.h>
+#include <stdint.h>
+
+#include <as.h>
+#include <ddf/driver.h>
+#include <ddf/interrupt.h>
+#include <ddf/log.h>
+#include <pci_dev_iface.h>
+#include <fibril_synch.h>
+
+#include <bd_srv.h>
+
+#include <virtio-pci.h>
+
+#define NAME	"virtio-blk"
+
+#define VIRTIO_BLK_NUM_QUEUES	1
+
+#define RQ_QUEUE	0
+
+/*
+ * VIRTIO_BLK requests need at least two descriptors so that device-read-only
+ * buffers are separated from device-writable buffers. For convenience, we
+ * always use three descriptors for the request header, buffer and footer.
+ * We therefore organize the virtque so that first RQ_BUFFERS descriptors are
+ * used for request headers, the following RQ_BUFFERS descriptors are used
+ * for in/out buffers and the last RQ_BUFFERS descriptors are used for request
+ * footers.
+ */
+#define REQ_HEADER_DESC(descno)	(0 * RQ_BUFFERS + (descno))
+#define REQ_BUFFER_DESC(descno)	(1 * RQ_BUFFERS + (descno))
+#define REQ_FOOTER_DESC(descno)	(2 * RQ_BUFFERS + (descno))
+
+static errno_t virtio_blk_dev_add(ddf_dev_t *dev);
+
+static driver_ops_t virtio_blk_driver_ops = {
+	.dev_add = virtio_blk_dev_add
+};
+
+static driver_t virtio_blk_driver = {
+	.name = NAME,
+	.driver_ops = &virtio_blk_driver_ops
+};
+
+static void virtio_blk_irq_handler(ipc_call_t *icall, ddf_dev_t *dev)
+{
+	virtio_blk_t *virtio_blk = (virtio_blk_t *) ddf_dev_data_get(dev);
+	virtio_dev_t *vdev = &virtio_blk->virtio_dev;
+
+	uint16_t descno;
+	uint32_t len;
+
+	while (virtio_virtq_consume_used(vdev, RQ_QUEUE, &descno, &len)) {
+		assert(descno < RQ_BUFFERS);
+		fibril_mutex_lock(&virtio_blk->completion_lock[descno]);
+		fibril_condvar_signal(&virtio_blk->completion_cv[descno]);
+		fibril_mutex_unlock(&virtio_blk->completion_lock[descno]);
+	}
+}
+
+static errno_t virtio_blk_register_interrupt(ddf_dev_t *dev)
+{
+	virtio_blk_t *virtio_blk = (virtio_blk_t *) ddf_dev_data_get(dev);
+	virtio_dev_t *vdev = &virtio_blk->virtio_dev;
+
+	async_sess_t *parent_sess = ddf_dev_parent_sess_get(dev);
+	if (parent_sess == NULL)
+		return ENOMEM;
+
+	hw_res_list_parsed_t res;
+	hw_res_list_parsed_init(&res);
+
+	hw_res_list_parsed_init(&res);
+	errno_t rc = hw_res_get_list_parsed(parent_sess, &res, 0);
+	if (rc != EOK)
+		return rc;
+
+	if (res.irqs.count < 1) {
+		hw_res_list_parsed_clean(&res);
+		return EINVAL;
+	}
+
+	virtio_blk->irq = res.irqs.irqs[0];
+	hw_res_list_parsed_clean(&res);
+
+	irq_pio_range_t pio_ranges[] = {
+		{
+			.base = vdev->isr_phys,
+			.size = sizeof(vdev->isr_phys),
+		}
+	};
+
+	irq_cmd_t irq_commands[] = {
+		{
+			.cmd = CMD_PIO_READ_8,
+			.addr = (void *) vdev->isr_phys,
+			.dstarg = 2
+		},
+		{
+			.cmd = CMD_PREDICATE,
+			.value = 1,
+			.srcarg = 2
+		},
+		{
+			.cmd = CMD_ACCEPT
+		}
+	};
+
+	irq_code_t irq_code = {
+		.rangecount = sizeof(pio_ranges) / sizeof(irq_pio_range_t),
+		.ranges = pio_ranges,
+		.cmdcount = sizeof(irq_commands) / sizeof(irq_cmd_t),
+		.cmds = irq_commands
+	};
+
+	return register_interrupt_handler(dev, virtio_blk->irq,
+	    virtio_blk_irq_handler, &irq_code, &virtio_blk->irq_handle);
+}
+
+static errno_t virtio_blk_bd_open(bd_srvs_t *bds, bd_srv_t *bd)
+{
+	return EOK;
+}
+
+static errno_t virtio_blk_bd_close(bd_srv_t *bd)
+{
+	return EOK;
+}
+
+static errno_t virtio_blk_rw_block(virtio_blk_t *virtio_blk, bool read,
+    aoff64_t ba, void *buf)
+{
+	virtio_dev_t *vdev = &virtio_blk->virtio_dev;
+
+	/*
+	 * Allocate a descriptor.
+	 *
+	 * The allocated descno will determine the header descriptor
+	 * (REQ_HEADER_DESC), the buffer descriptor (REQ_BUFFER_DESC) and the
+	 * footer (REQ_FOOTER_DESC) descriptor.
+	 */
+	fibril_mutex_lock(&virtio_blk->free_lock);
+	uint16_t descno = virtio_alloc_desc(vdev, RQ_QUEUE,
+	    &virtio_blk->rq_free_head);
+	while (descno == (uint16_t) -1U) {
+		fibril_condvar_wait(&virtio_blk->free_cv,
+		    &virtio_blk->free_lock);
+		descno = virtio_alloc_desc(vdev, RQ_QUEUE,
+		    &virtio_blk->rq_free_head);
+	}
+	fibril_mutex_unlock(&virtio_blk->free_lock);
+
+	assert(descno < RQ_BUFFERS);
+
+	/* Setup the request header */
+	virtio_blk_req_header_t *req_header =
+	    (virtio_blk_req_header_t *) virtio_blk->rq_header[descno];
+	memset(req_header, 0, sizeof(virtio_blk_req_header_t));
+	pio_write_le32(&req_header->type,
+	    read ? VIRTIO_BLK_T_IN : VIRTIO_BLK_T_OUT);
+	pio_write_le64(&req_header->sector, ba);
+
+	/* Copy write data to the request. */
+	if (!read)
+		memcpy(virtio_blk->rq_buf[descno], buf, VIRTIO_BLK_BLOCK_SIZE);
+
+	fibril_mutex_lock(&virtio_blk->completion_lock[descno]);
+
+	/*
+	 * Set the descriptors, chain them in the virtqueue and notify the
+	 * device.
+	 */
+	virtio_virtq_desc_set(vdev, RQ_QUEUE, REQ_HEADER_DESC(descno),
+	    virtio_blk->rq_header_p[descno], sizeof(virtio_blk_req_header_t),
+	    VIRTQ_DESC_F_NEXT, REQ_BUFFER_DESC(descno));
+	virtio_virtq_desc_set(vdev, RQ_QUEUE, REQ_BUFFER_DESC(descno),
+	    virtio_blk->rq_buf_p[descno], VIRTIO_BLK_BLOCK_SIZE,
+	    VIRTQ_DESC_F_NEXT | (read ? VIRTQ_DESC_F_WRITE : 0),
+	    REQ_FOOTER_DESC(descno));
+	virtio_virtq_desc_set(vdev, RQ_QUEUE, REQ_FOOTER_DESC(descno),
+	    virtio_blk->rq_footer_p[descno], sizeof(virtio_blk_req_footer_t),
+	    VIRTQ_DESC_F_WRITE, 0);
+	virtio_virtq_produce_available(vdev, RQ_QUEUE, descno);
+
+	/*
+	 * Wait for the completion of the request.
+	 */
+	fibril_condvar_wait(&virtio_blk->completion_cv[descno],
+	    &virtio_blk->completion_lock[descno]);
+	fibril_mutex_unlock(&virtio_blk->completion_lock[descno]);
+
+	errno_t rc;
+	virtio_blk_req_footer_t *footer =
+	    (virtio_blk_req_footer_t *) virtio_blk->rq_footer[descno];
+	switch (footer->status) {
+	case VIRTIO_BLK_S_OK:
+		rc = EOK;
+		break;
+	case VIRTIO_BLK_S_IOERR:
+		rc = EIO;
+		break;
+	case VIRTIO_BLK_S_UNSUPP:
+		rc = ENOTSUP;
+		break;
+	default:
+		ddf_msg(LVL_DEBUG, "device returned unknown status=%d\n",
+		    (int) footer->status);
+		rc = EIO;
+		break;
+	}
+
+	/* Copy read data from the request */
+	if (rc == EOK && read)
+		memcpy(buf, virtio_blk->rq_buf[descno], VIRTIO_BLK_BLOCK_SIZE);
+
+	/* Free the descriptor and buffer */
+	fibril_mutex_lock(&virtio_blk->free_lock);
+	virtio_free_desc(vdev, RQ_QUEUE, &virtio_blk->rq_free_head, descno);
+	fibril_condvar_signal(&virtio_blk->free_cv);
+	fibril_mutex_unlock(&virtio_blk->free_lock);
+
+	return rc;
+}
+
+static errno_t virtio_blk_bd_rw_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt,
+    void *buf, size_t size, bool read)
+{
+	virtio_blk_t *virtio_blk = (virtio_blk_t *) bd->srvs->sarg;
+	aoff64_t i;
+	errno_t rc;
+
+	if (size != cnt * VIRTIO_BLK_BLOCK_SIZE)
+		return EINVAL;
+
+	for (i = 0; i < cnt; i++) {
+		rc = virtio_blk_rw_block(virtio_blk, read, ba + i,
+		    buf + i * VIRTIO_BLK_BLOCK_SIZE);
+		if (rc != EOK)
+			return rc;
+	}
+
+	return EOK;
+}
+
+static errno_t virtio_blk_bd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt,
+    void *buf, size_t size)
+{
+	return virtio_blk_bd_rw_blocks(bd, ba, cnt, buf, size, true);
+}
+
+static errno_t virtio_blk_bd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt,
+    const void *buf, size_t size)
+{
+	return virtio_blk_bd_rw_blocks(bd, ba, cnt, (void *) buf, size, false);
+}
+
+static errno_t virtio_blk_bd_get_block_size(bd_srv_t *bd, size_t *size)
+{
+	*size = VIRTIO_BLK_BLOCK_SIZE;
+	return EOK;
+}
+
+static errno_t virtio_blk_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *nb)
+{
+	virtio_blk_t *virtio_blk = (virtio_blk_t *) bd->srvs->sarg;
+	virtio_blk_cfg_t *blkcfg = virtio_blk->virtio_dev.device_cfg;
+	*nb = pio_read_le64(&blkcfg->capacity);
+	return EOK;
+}
+
+bd_ops_t virtio_blk_bd_ops = {
+	.open = virtio_blk_bd_open,
+	.close = virtio_blk_bd_close,
+	.read_blocks = virtio_blk_bd_read_blocks,
+	.write_blocks = virtio_blk_bd_write_blocks,
+	.get_block_size = virtio_blk_bd_get_block_size,
+	.get_num_blocks = virtio_blk_bd_get_num_blocks,
+};
+
+static errno_t virtio_blk_initialize(ddf_dev_t *dev)
+{
+	virtio_blk_t *virtio_blk = ddf_dev_data_alloc(dev,
+	    sizeof(virtio_blk_t));
+	if (!virtio_blk)
+		return ENOMEM;
+
+	fibril_mutex_initialize(&virtio_blk->free_lock);
+	fibril_condvar_initialize(&virtio_blk->free_cv);
+
+	for (unsigned i = 0; i < RQ_BUFFERS; i++) {
+		fibril_mutex_initialize(&virtio_blk->completion_lock[i]);
+		fibril_condvar_initialize(&virtio_blk->completion_cv[i]);
+	}
+
+	bd_srvs_init(&virtio_blk->bds);
+	virtio_blk->bds.ops = &virtio_blk_bd_ops;
+	virtio_blk->bds.sarg = virtio_blk;
+
+	errno_t rc = virtio_pci_dev_initialize(dev, &virtio_blk->virtio_dev);
+	if (rc != EOK)
+		return rc;
+
+	virtio_dev_t *vdev = &virtio_blk->virtio_dev;
+	virtio_pci_common_cfg_t *cfg = virtio_blk->virtio_dev.common_cfg;
+
+	/*
+	 * Register IRQ
+	 */
+	rc = virtio_blk_register_interrupt(dev);
+	if (rc != EOK)
+		goto fail;
+
+	/* Reset the device and negotiate the feature bits */
+	rc = virtio_device_setup_start(vdev, 0);
+	if (rc != EOK)
+		goto fail;
+
+	/* Perform device-specific setup */
+
+	/*
+	 * Discover and configure the virtqueue
+	 */
+	uint16_t num_queues = pio_read_le16(&cfg->num_queues);
+	if (num_queues != VIRTIO_BLK_NUM_QUEUES) {
+		ddf_msg(LVL_NOTE, "Unsupported number of virtqueues: %u",
+		    num_queues);
+		rc = ELIMIT;
+		goto fail;
+	}
+
+	vdev->queues = calloc(sizeof(virtq_t), num_queues);
+	if (!vdev->queues) {
+		rc = ENOMEM;
+		goto fail;
+	}
+
+	/* For each in/out request we need 3 descriptors */
+	rc = virtio_virtq_setup(vdev, RQ_QUEUE, 3 * RQ_BUFFERS);
+	if (rc != EOK)
+		goto fail;
+
+	/*
+	 * Setup DMA buffers
+	 */
+	rc = virtio_setup_dma_bufs(RQ_BUFFERS, sizeof(virtio_blk_req_header_t),
+	    true, virtio_blk->rq_header, virtio_blk->rq_header_p);
+	if (rc != EOK)
+		goto fail;
+	rc = virtio_setup_dma_bufs(RQ_BUFFERS, VIRTIO_BLK_BLOCK_SIZE,
+	    true, virtio_blk->rq_buf, virtio_blk->rq_buf_p);
+	if (rc != EOK)
+		goto fail;
+	rc = virtio_setup_dma_bufs(RQ_BUFFERS, sizeof(virtio_blk_req_footer_t),
+	    false, virtio_blk->rq_footer, virtio_blk->rq_footer_p);
+	if (rc != EOK)
+		goto fail;
+
+	/*
+	 * Put all request descriptors on a free list. Because of the
+	 * correspondence between the request, buffer and footer descriptors,
+	 * we only need to manage allocations for one set: the request header
+	 * descriptors.
+	 */
+	virtio_create_desc_free_list(vdev, RQ_QUEUE, RQ_BUFFERS,
+	    &virtio_blk->rq_free_head);
+
+	/*
+	 * Enable IRQ
+	 */
+	rc = hw_res_enable_interrupt(ddf_dev_parent_sess_get(dev),
+	    virtio_blk->irq);
+	if (rc != EOK) {
+		ddf_msg(LVL_NOTE, "Failed to enable interrupt");
+		goto fail;
+	}
+
+	ddf_msg(LVL_NOTE, "Registered IRQ %d", virtio_blk->irq);
+
+	/* Go live */
+	virtio_device_setup_finalize(vdev);
+
+	return EOK;
+
+fail:
+	virtio_teardown_dma_bufs(virtio_blk->rq_header);
+	virtio_teardown_dma_bufs(virtio_blk->rq_buf);
+	virtio_teardown_dma_bufs(virtio_blk->rq_footer);
+
+	virtio_device_setup_fail(vdev);
+	virtio_pci_dev_cleanup(vdev);
+	return rc;
+}
+
+static void virtio_blk_uninitialize(ddf_dev_t *dev)
+{
+	virtio_blk_t *virtio_blk = (virtio_blk_t *) ddf_dev_data_get(dev);
+
+	virtio_teardown_dma_bufs(virtio_blk->rq_header);
+	virtio_teardown_dma_bufs(virtio_blk->rq_buf);
+	virtio_teardown_dma_bufs(virtio_blk->rq_footer);
+
+	virtio_device_setup_fail(&virtio_blk->virtio_dev);
+	virtio_pci_dev_cleanup(&virtio_blk->virtio_dev);
+}
+
+static void virtio_blk_bd_connection(ipc_call_t *icall, void *arg)
+{
+	virtio_blk_t *virtio_blk;
+	ddf_fun_t *fun = (ddf_fun_t *) arg;
+
+	virtio_blk = (virtio_blk_t *) ddf_dev_data_get(ddf_fun_get_dev(fun));
+	bd_conn(icall, &virtio_blk->bds);
+}
+
+static errno_t virtio_blk_dev_add(ddf_dev_t *dev)
+{
+	ddf_msg(LVL_NOTE, "%s %s (handle = %zu)", __func__,
+	    ddf_dev_get_name(dev), ddf_dev_get_handle(dev));
+
+	errno_t rc = virtio_blk_initialize(dev);
+	if (rc != EOK)
+		return rc;
+
+	ddf_fun_t *fun = ddf_fun_create(dev, fun_exposed, "port0");
+	if (fun == NULL) {
+		rc = ENOMEM;
+		goto uninitialize;
+	}
+
+	ddf_fun_set_conn_handler(fun, virtio_blk_bd_connection);
+
+	rc = ddf_fun_bind(fun);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed binding device function");
+		goto destroy;
+	}
+
+	rc = ddf_fun_add_to_category(fun, "disk");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed adding function to category");
+		goto unbind;
+	}
+
+	ddf_msg(LVL_NOTE, "The %s device has been successfully initialized.",
+	    ddf_dev_get_name(dev));
+
+	return EOK;
+
+unbind:
+	ddf_fun_unbind(fun);
+destroy:
+	ddf_fun_destroy(fun);
+uninitialize:
+	virtio_blk_uninitialize(dev);
+	return rc;
+}
+
+int main(void)
+{
+	printf("%s: HelenOS virtio-blk driver\n", NAME);
+
+	(void) ddf_log_init(NAME);
+	return ddf_driver_main(&virtio_blk_driver);
+}
Index: uspace/drv/block/virtio-blk/virtio-blk.h
===================================================================
--- uspace/drv/block/virtio-blk/virtio-blk.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/block/virtio-blk/virtio-blk.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#ifndef _VIRTIO_BLK_H_
+#define _VIRTIO_BLK_H_
+
+#include <virtio-pci.h>
+#include <bd_srv.h>
+#include <abi/cap.h>
+
+#include <fibril_synch.h>
+
+#define VIRTIO_BLK_BLOCK_SIZE	512
+
+/* Operation types. */
+#define VIRTIO_BLK_T_IN		0
+#define VIRTIO_BLK_T_OUT	1
+
+/* Status codes returned by the device. */
+#define VIRTIO_BLK_S_OK		0
+#define VIRTIO_BLK_S_IOERR	1
+#define VIRTIO_BLK_S_UNSUPP	2
+
+#define RQ_BUFFERS	32
+
+/** Device is read-only. */
+#define VIRTIO_BLK_F_RO		(1U << 5)
+
+typedef struct {
+	uint32_t type;
+	uint32_t reserved;
+	uint64_t sector;
+} virtio_blk_req_header_t;
+
+typedef struct {
+	uint8_t status;
+} virtio_blk_req_footer_t;
+
+typedef struct {
+	uint64_t capacity;
+} virtio_blk_cfg_t;
+
+typedef struct {
+	virtio_dev_t virtio_dev;
+
+	void *rq_header[RQ_BUFFERS];
+	uintptr_t rq_header_p[RQ_BUFFERS];
+
+	void *rq_buf[RQ_BUFFERS];
+	uintptr_t rq_buf_p[RQ_BUFFERS];
+
+	void *rq_footer[RQ_BUFFERS];
+	uintptr_t rq_footer_p[RQ_BUFFERS];
+
+	uint16_t rq_free_head;
+
+	int irq;
+	cap_irq_handle_t irq_handle;
+
+	bd_srvs_t bds;
+
+	fibril_mutex_t free_lock;
+	fibril_condvar_t free_cv;
+
+	fibril_mutex_t completion_lock[RQ_BUFFERS];
+	fibril_condvar_t completion_cv[RQ_BUFFERS];
+} virtio_blk_t;
+
+#endif
Index: uspace/drv/block/virtio-blk/virtio-blk.ma
===================================================================
--- uspace/drv/block/virtio-blk/virtio-blk.ma	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/block/virtio-blk/virtio-blk.ma	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,2 @@
+10 pci/ven=1af4&dev=1001
+10 pci/ven=1af4&dev=1042
Index: uspace/drv/bus/adb/cuda_adb/cuda_adb.c
===================================================================
--- uspace/drv/bus/adb/cuda_adb/cuda_adb.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/adb/cuda_adb/cuda_adb.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -208,5 +208,5 @@
 	while (true) {
 		async_get_call(&call);
-		method = IPC_GET_IMETHOD(call);
+		method = ipc_get_imethod(&call);
 
 		if (!method) {
@@ -273,4 +273,7 @@
 
 	fibril_mutex_lock(&cuda->dev_lock);
+
+	/* Lower IFR.SR_INT so that CUDA can generate next int by raising it. */
+	pio_write_8(&cuda->regs->ifr, SR_INT);
 
 	switch (cuda->xstate) {
@@ -293,7 +296,4 @@
 	}
 
-	/* Lower IFR.SR_INT so that CUDA can generate next int by raising it. */
-	pio_write_8(&cuda->regs->ifr, SR_INT);
-
 	fibril_mutex_unlock(&cuda->dev_lock);
 
Index: uspace/drv/bus/adb/cuda_adb/cuda_hw.h
===================================================================
--- uspace/drv/bus/adb/cuda_adb/cuda_hw.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/adb/cuda_adb/cuda_hw.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,53 +37,55 @@
 #define CUDA_HW_H_
 
+#include <ddi.h>
+
 #include <stdint.h>
 
 typedef struct cuda_regs {
-	uint8_t b;
+	ioport8_t b;
 	uint8_t pad0[0x1ff];
 
-	uint8_t a;
+	ioport8_t a;
 	uint8_t pad1[0x1ff];
 
-	uint8_t dirb;
+	ioport8_t dirb;
 	uint8_t pad2[0x1ff];
 
-	uint8_t dira;
+	ioport8_t dira;
 	uint8_t pad3[0x1ff];
 
-	uint8_t t1cl;
+	ioport8_t t1cl;
 	uint8_t pad4[0x1ff];
 
-	uint8_t t1ch;
+	ioport8_t t1ch;
 	uint8_t pad5[0x1ff];
 
-	uint8_t t1ll;
+	ioport8_t t1ll;
 	uint8_t pad6[0x1ff];
 
-	uint8_t t1lh;
+	ioport8_t t1lh;
 	uint8_t pad7[0x1ff];
 
-	uint8_t t2cl;
+	ioport8_t t2cl;
 	uint8_t pad8[0x1ff];
 
-	uint8_t t2ch;
+	ioport8_t t2ch;
 	uint8_t pad9[0x1ff];
 
-	uint8_t sr;
+	ioport8_t sr;
 	uint8_t pad10[0x1ff];
 
-	uint8_t acr;
+	ioport8_t acr;
 	uint8_t pad11[0x1ff];
 
-	uint8_t pcr;
+	ioport8_t pcr;
 	uint8_t pad12[0x1ff];
 
-	uint8_t ifr;
+	ioport8_t ifr;
 	uint8_t pad13[0x1ff];
 
-	uint8_t ier;
+	ioport8_t ier;
 	uint8_t pad14[0x1ff];
 
-	uint8_t anh;
+	ioport8_t anh;
 	uint8_t pad15[0x1ff];
 } cuda_regs_t;
Index: uspace/drv/bus/isa/i8237.c
===================================================================
--- uspace/drv/bus/isa/i8237.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/isa/i8237.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -188,5 +188,5 @@
 } dma_controller_t;
 
-static fibril_mutex_t guard = FIBRIL_MUTEX_INITIALIZER(guard);
+static FIBRIL_MUTEX_INITIALIZE(guard);
 
 /** Standard i8237 DMA controller.
Index: uspace/drv/bus/isa/isa.c
===================================================================
--- uspace/drv/bus/isa/isa.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/isa/isa.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -465,5 +465,5 @@
 		resources[count].res.mem_range.address += isa->pio_win.mem.base;
 		resources[count].res.mem_range.size = len;
-		resources[count].res.mem_range.relative = true;
+		resources[count].res.mem_range.relative = false;
 		resources[count].res.mem_range.endianness = LITTLE_ENDIAN;
 
Index: uspace/drv/bus/isa/isa.dev
===================================================================
--- uspace/drv/bus/isa/isa.dev	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/isa/isa.dev	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -17,4 +17,14 @@
 	irq 3
 	io_range 2f8 8
+
+lpt1:
+	match 100 isa/lpt
+	io_range 378 8
+	irq 7
+
+lpt2:
+	match 100 isa/lpt
+	io_range 278 8
+	irq 5
 
 i8042:
Index: uspace/drv/bus/pci/pciintel/Makefile
===================================================================
--- uspace/drv/bus/pci/pciintel/Makefile	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/pci/pciintel/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -32,4 +32,5 @@
 
 SOURCES = \
+	ctl.c \
 	pci.c
 
Index: uspace/drv/bus/pci/pciintel/ctl.c
===================================================================
--- uspace/drv/bus/pci/pciintel/ctl.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/bus/pci/pciintel/ctl.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2019 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 pciintel
+ * @{
+ */
+
+/** @file
+ */
+
+#include <async.h>
+#include <ddf/log.h>
+#include <ipc/pci.h>
+#include <macros.h>
+#include <types/pci.h>
+#include "ctl.h"
+#include "pci.h"
+
+static void pci_ctl_get_devices_srv(pci_bus_t *, ipc_call_t *);
+static void pci_ctl_dev_get_info_srv(pci_bus_t *, ipc_call_t *);
+static errno_t pci_ctl_get_devices(pci_bus_t *, devman_handle_t *, size_t,
+    size_t *);
+static errno_t pci_ctl_dev_get_info(pci_fun_t *, pci_dev_info_t *);
+
+/** Handle control service connection */
+void pci_ctl_connection(ipc_call_t *icall, void *arg)
+{
+	ipc_call_t call;
+	pci_bus_t *bus;
+
+	/*
+	 * Answer the first IPC_M_CONNECT_ME_TO call.
+	 */
+	async_accept_0(icall);
+
+	bus = pci_bus(ddf_fun_get_dev((ddf_fun_t *) arg));
+
+	while (true) {
+		async_get_call(&call);
+
+		if (!ipc_get_imethod(&call))
+			break;
+
+		switch (ipc_get_imethod(&call)) {
+		case PCI_GET_DEVICES:
+			pci_ctl_get_devices_srv(bus, &call);
+			break;
+		case PCI_DEV_GET_INFO:
+			pci_ctl_dev_get_info_srv(bus, &call);
+			break;
+		default:
+			async_answer_0(&call, EINVAL);
+			break;
+		}
+	}
+}
+
+/** Handle request to get list of PCI devices.
+ *
+ * @param bus PCI bus
+ * @param call Async request
+ */
+static void pci_ctl_get_devices_srv(pci_bus_t *bus, ipc_call_t *icall)
+{
+	ipc_call_t call;
+	size_t size;
+	size_t act_size;
+	devman_handle_t *buf;
+	errno_t rc;
+
+	if (!async_data_read_receive(&call, &size)) {
+		async_answer_0(&call, EREFUSED);
+		async_answer_0(icall, EREFUSED);
+		return;
+	}
+
+	if ((size % sizeof(devman_handle_t)) != 0) {
+		async_answer_0(&call, EINVAL);
+		async_answer_0(icall, EINVAL);
+		return;
+	}
+
+	buf = malloc(max(1, size));
+	if (buf == NULL) {
+		async_answer_0(&call, ENOMEM);
+		async_answer_0(icall, ENOMEM);
+		return;
+	}
+
+	rc = pci_ctl_get_devices(bus, buf, size, &act_size);
+	if (rc != EOK) {
+		free(buf);
+		async_answer_0(&call, rc);
+		async_answer_0(icall, rc);
+		return;
+	}
+
+	errno_t retval = async_data_read_finalize(&call, buf, size);
+
+	free(buf);
+	async_answer_1(icall, retval, act_size);
+}
+
+/** Handle request to get PCI device information.
+ *
+ * @param bus PCI bus
+ * @param call Async request
+ */
+static void pci_ctl_dev_get_info_srv(pci_bus_t *bus, ipc_call_t *icall)
+{
+	devman_handle_t dev_handle;
+	pci_fun_t *fun;
+	pci_dev_info_t info;
+	errno_t rc;
+
+	dev_handle = ipc_get_arg1(icall);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "pci_dev_get_info_srv(%zu)",
+	    dev_handle);
+	fun = pci_fun_first(bus);
+	while (fun != NULL) {
+		if (ddf_fun_get_handle(fun->fnode) == dev_handle)
+			break;
+
+		fun = pci_fun_next(fun);
+	}
+
+	if (fun == NULL) {
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "pci_dev_get_info_srv: "
+		    "device %zu not found", dev_handle);
+		async_answer_0(icall, ENOENT);
+		return;
+	}
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "pci_dev_get_info_srv: "
+	    "vol_volume_get_info");
+	rc = pci_ctl_dev_get_info(fun, &info);
+	if (rc != EOK) {
+		async_answer_0(icall, EIO);
+		return;
+	}
+
+	ipc_call_t call;
+	size_t size;
+	if (!async_data_read_receive(&call, &size)) {
+		async_answer_0(&call, EREFUSED);
+		async_answer_0(icall, EREFUSED);
+		return;
+	}
+
+	if (size != sizeof(pci_dev_info_t)) {
+		async_answer_0(&call, EINVAL);
+		async_answer_0(icall, EINVAL);
+		return;
+	}
+
+	rc = async_data_read_finalize(&call, &info,
+	    min(size, sizeof(info)));
+	if (rc != EOK) {
+		async_answer_0(&call, rc);
+		async_answer_0(icall, rc);
+		return;
+	}
+
+	async_answer_0(icall, EOK);
+}
+
+/** Get list of PCI devices.
+ *
+ * @param bus PCI bus
+ * @param call Async request
+ */
+static errno_t pci_ctl_get_devices(pci_bus_t *bus, devman_handle_t *id_buf,
+    size_t size, size_t *act_size)
+{
+	pci_fun_t *fun;
+	size_t cnt;
+
+	ddf_msg(LVL_NOTE, "pci_ctl_get_devices(%p, %p, %zu, %p)\n",
+	    bus, id_buf, size, act_size);
+
+	fun = pci_fun_first(bus);
+	cnt = 0;
+	while (fun != NULL) {
+		if (sizeof(devman_handle_t) * cnt < size)
+			id_buf[cnt] = ddf_fun_get_handle(fun->fnode);
+		++cnt;
+		fun = pci_fun_next(fun);
+	}
+
+	*act_size = sizeof(devman_handle_t) * cnt;
+	return EOK;
+}
+
+/** Get PCI device information.
+ *
+ * @param fun PCI function
+ * @param info Place to store information
+ *
+ * @return EOK on success or an error code
+ */
+static errno_t pci_ctl_dev_get_info(pci_fun_t *fun, pci_dev_info_t *info)
+{
+	info->dev_handle = ddf_fun_get_handle(fun->fnode);
+	info->bus_num = fun->bus;
+	info->dev_num = fun->dev;
+	info->fn_num = fun->fn;
+	info->vendor_id = fun->vendor_id;
+	info->device_id = fun->device_id;
+	return EOK;
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/bus/pci/pciintel/ctl.h
===================================================================
--- uspace/drv/bus/pci/pciintel/ctl.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/bus/pci/pciintel/ctl.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019 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 pciintel
+ * @{
+ */
+/** @file
+ */
+
+#ifndef CTL_H_
+#define CTL_H_
+
+#include <async.h>
+
+extern void pci_ctl_connection(ipc_call_t *icall, void *arg);
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/drv/bus/pci/pciintel/pci.c
===================================================================
--- uspace/drv/bus/pci/pciintel/pci.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/pci/pciintel/pci.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,5 +1,5 @@
 /*
+ * Copyright (c) 2019 Jiri Svoboda
  * Copyright (c) 2010 Lenka Trochtova
- * Copyright (c) 2018 Jiri Svoboda
  * All rights reserved.
  *
@@ -58,5 +58,7 @@
 #include <pci_dev_iface.h>
 
+#include "ctl.h"
 #include "pci.h"
+#include "pci_regs.h"
 
 #define NAME "pciintel"
@@ -73,10 +75,8 @@
 
 /** Obtain PCI bus soft-state from DDF device node */
-#if 0
-static pci_bus_t *pci_bus(ddf_dev_t *dnode)
+pci_bus_t *pci_bus(ddf_dev_t *dnode)
 {
 	return ddf_dev_data_get(dnode);
 }
-#endif
 
 /** Obtain PCI bus soft-state from function soft-state */
@@ -448,4 +448,36 @@
 
 	/* TODO add subsys ids, but those exist only in header type 0 */
+}
+
+/** Get first PCI function.
+ *
+ * @param bus PCI bus
+ * @return First PCI function on @a bus or @c NULL if there is none
+ */
+pci_fun_t *pci_fun_first(pci_bus_t *bus)
+{
+	link_t *link;
+
+	link = list_first(&bus->funs);
+	if (link == NULL)
+		return NULL;
+
+	return list_get_instance(link, pci_fun_t, lfuns);
+}
+
+/** Get next PCI function.
+ *
+ * @param cur Current function
+ * @return Next PCI function on the same bus or @c NULL if there is none
+ */
+pci_fun_t *pci_fun_next(pci_fun_t *cur)
+{
+	link_t *link;
+
+	link = list_next(&cur->lfuns, &cur->busptr->funs);
+	if (link == NULL)
+		return NULL;
+
+	return list_get_instance(link, pci_fun_t, lfuns);
 }
 
@@ -691,4 +723,6 @@
 				continue;
 			}
+
+			list_append(&fun->lfuns, &bus->funs);
 		}
 	}
@@ -718,4 +752,6 @@
 		goto fail;
 	}
+
+	list_initialize(&bus->funs);
 	fibril_mutex_initialize(&bus->conf_mutex);
 
@@ -802,4 +838,6 @@
 	}
 
+	ddf_fun_set_conn_handler(ctl, pci_ctl_connection);
+
 	/* Enumerate functions. */
 	ddf_msg(LVL_DEBUG, "Enumerating the bus");
@@ -816,4 +854,11 @@
 	}
 
+	rc = ddf_fun_add_to_category(ctl, "pci");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed adding control function to category "
+		    "'pci'.");
+		goto fail;
+	}
+
 	hw_res_clean_resource_list(&hw_resources);
 
Index: uspace/drv/bus/pci/pciintel/pci.h
===================================================================
--- uspace/drv/bus/pci/pciintel/pci.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/pci/pciintel/pci.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,6 +37,8 @@
 #define PCI_H_
 
+#include <adt/list.h>
+#include <ddi.h>
 #include <ddf/driver.h>
-#include "pci_regs.h"
+#include <fibril_synch.h>
 
 #define PCI_MAX_HW_RES 10
@@ -50,4 +52,6 @@
 	pio_window_t pio_win;
 	fibril_mutex_t conf_mutex;
+	/** List of functions (of pci_fun_t) */
+	list_t funs;
 } pci_bus_t;
 
@@ -55,4 +59,6 @@
 	pci_bus_t *busptr;
 	ddf_fun_t *fnode;
+	/** Link to @c busptr->funs */
+	link_t lfuns;
 
 	int bus;
@@ -71,5 +77,9 @@
 } pci_fun_t;
 
+extern pci_bus_t *pci_bus(ddf_dev_t *);
+
 extern void pci_fun_create_match_ids(pci_fun_t *);
+extern pci_fun_t *pci_fun_first(pci_bus_t *);
+extern pci_fun_t *pci_fun_next(pci_fun_t *);
 
 extern uint8_t pci_conf_read_8(pci_fun_t *, int);
Index: uspace/drv/bus/usb/ehci/hw_struct/iso_transfer_descriptor.h
===================================================================
--- uspace/drv/bus/usb/ehci/hw_struct/iso_transfer_descriptor.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/usb/ehci/hw_struct/iso_transfer_descriptor.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -56,6 +56,6 @@
 #define ITD_TRANSACTION_STATUS_BABBLE_FLAG   (1 << 29)
 #define ITD_TRANSACTION_STATUS_TRANS_ERROR_FLAG  (1 << 28)
-#define ITD_TRANSACTION_LENGHT_MASK    0xfff
-#define ITD_TRANSACTION_LENGHT_SHIFT   16
+#define ITD_TRANSACTION_LENGTH_MASK    0xfff
+#define ITD_TRANSACTION_LENGTH_SHIFT   16
 #define ITD_TRANSACTION_IOC_FLAG       (1 << 15)
 #define ITD_TRANSACTION_PG_MASK        0x3
Index: uspace/drv/bus/usb/ehci/hw_struct/transfer_descriptor.h
===================================================================
--- uspace/drv/bus/usb/ehci/hw_struct/transfer_descriptor.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/usb/ehci/hw_struct/transfer_descriptor.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -88,5 +88,5 @@
 #define TD_BUFFER_POINTER_OFFSET_MASK    0xfff
 
-static_assert(sizeof(td_t) % 32 == 0);
+static_assert(sizeof(td_t) % 32 == 0, "");
 
 static inline bool td_active(const td_t *td)
Index: uspace/drv/bus/usb/ohci/hc.c
===================================================================
--- uspace/drv/bus/usb/ohci/hc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/usb/ohci/hc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -514,5 +514,5 @@
 
 	/* Enable interrupts */
-	if (CAP_HANDLE_VALID(instance->base.irq_handle)) {
+	if (cap_handle_valid(instance->base.irq_handle)) {
 		OHCI_WR(instance->registers->interrupt_enable,
 		    OHCI_USED_INTERRUPTS);
Index: uspace/drv/bus/usb/ohci/hw_struct/hcca.h
===================================================================
--- uspace/drv/bus/usb/ohci/hw_struct/hcca.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/usb/ohci/hw_struct/hcca.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -61,5 +61,5 @@
 } hcca_t;
 
-static_assert(sizeof(hcca_t) == 256);
+static_assert(sizeof(hcca_t) == 256, "");
 
 /** Allocate properly aligned structure.
Index: uspace/drv/bus/usb/ohci/ohci_regs.h
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_regs.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/usb/ohci/ohci_regs.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -153,5 +153,5 @@
  * ohci_regs_t.control
  */
- 
+
 /* Control-bulk service ratio */
 #define C_CBSR_1_1  (0x0)
Index: uspace/drv/bus/usb/uhci/hc.c
===================================================================
--- uspace/drv/bus/usb/uhci/hc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/usb/uhci/hc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -295,5 +295,5 @@
 	pio_write_32(&registers->flbaseadd, pa);
 
-	if (CAP_HANDLE_VALID(instance->base.irq_handle)) {
+	if (cap_handle_valid(instance->base.irq_handle)) {
 		/* Enable all interrupts, but resume interrupt */
 		pio_write_16(&instance->registers->usbintr,
Index: uspace/drv/bus/usb/uhci/uhci_batch.c
===================================================================
--- uspace/drv/bus/usb/uhci/uhci_batch.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/usb/uhci/uhci_batch.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -96,5 +96,5 @@
 int uhci_transfer_batch_prepare(uhci_transfer_batch_t *uhci_batch)
 {
-	static_assert((sizeof(td_t) % 16) == 0);
+	static_assert((sizeof(td_t) % 16) == 0, "");
 
 	usb_transfer_batch_t *usb_batch = &uhci_batch->base;
Index: uspace/drv/bus/usb/vhc/conndev.c
===================================================================
--- uspace/drv/bus/usb/vhc/conndev.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/usb/vhc/conndev.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -83,5 +83,5 @@
 		return;
 
-	size_t len = IPC_GET_ARG2(data_request_call);
+	size_t len = ipc_get_arg2(&data_request_call);
 	plugged_device_name[len] = 0;
 }
Index: uspace/drv/bus/usb/xhci/hc.c
===================================================================
--- uspace/drv/bus/usb/xhci/hc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/usb/xhci/hc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -494,5 +494,5 @@
 	XHCI_REG_WR(intr0, XHCI_INTR_ERSTBA, erstba_phys);
 
-	if (CAP_HANDLE_VALID(hc->base.irq_handle)) {
+	if (cap_handle_valid(hc->base.irq_handle)) {
 		XHCI_REG_SET(intr0, XHCI_INTR_IE, 1);
 		XHCI_REG_SET(hc->op_regs, XHCI_OP_INTE, 1);
Index: uspace/drv/bus/usb/xhci/hw_struct/common.h
===================================================================
--- uspace/drv/bus/usb/xhci/hw_struct/common.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/usb/xhci/hw_struct/common.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -45,4 +45,5 @@
 #include <ddi.h>
 #include <errno.h>
+#include <fibril.h>
 
 #define host2xhci(size, val) host2uint##size##_t_le((val))
Index: uspace/drv/bus/usb/xhci/trb_ring.c
===================================================================
--- uspace/drv/bus/usb/xhci/trb_ring.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/usb/xhci/trb_ring.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -53,5 +53,5 @@
 } __attribute__((aligned(PAGE_SIZE)));
 
-static_assert(sizeof(trb_segment_t) == PAGE_SIZE);
+static_assert(sizeof(trb_segment_t) == PAGE_SIZE, "");
 
 /**
Index: uspace/drv/char/i8042/i8042.c
===================================================================
--- uspace/drv/char/i8042/i8042.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/char/i8042/i8042.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -67,5 +67,6 @@
 
 static void i8042_char_conn(ipc_call_t *, void *);
-static errno_t i8042_read(chardev_srv_t *, void *, size_t, size_t *);
+static errno_t i8042_read(chardev_srv_t *, void *, size_t, size_t *,
+    chardev_flags_t);
 static errno_t i8042_write(chardev_srv_t *, const void *, size_t, size_t *);
 
@@ -131,6 +132,6 @@
 	errno_t rc;
 
-	const uint8_t status = IPC_GET_ARG1(*call);
-	const uint8_t data = IPC_GET_ARG2(*call);
+	const uint8_t status = ipc_get_arg1(call);
+	const uint8_t data = ipc_get_arg2(call);
 
 	i8042_port_t *port = (status & i8042_AUX_DATA) ?
@@ -385,5 +386,5 @@
  */
 static errno_t i8042_read(chardev_srv_t *srv, void *dest, size_t size,
-    size_t *nread)
+    size_t *nread, chardev_flags_t flags)
 {
 	i8042_port_t *port = (i8042_port_t *)srv->srvs->sarg;
@@ -394,5 +395,6 @@
 	fibril_mutex_lock(&port->buf_lock);
 
-	while (circ_buf_nused(&port->cbuf) == 0)
+	while ((flags & chardev_f_nonblock) == 0 &&
+	    circ_buf_nused(&port->cbuf) == 0)
 		fibril_condvar_wait(&port->buf_cv, &port->buf_lock);
 
Index: uspace/drv/char/msim-con/msim-con.c
===================================================================
--- uspace/drv/char/msim-con/msim-con.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/char/msim-con/msim-con.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -43,5 +43,6 @@
 static void msim_con_connection(ipc_call_t *, void *);
 
-static errno_t msim_con_read(chardev_srv_t *, void *, size_t, size_t *);
+static errno_t msim_con_read(chardev_srv_t *, void *, size_t, size_t *,
+    chardev_flags_t);
 static errno_t msim_con_write(chardev_srv_t *, const void *, size_t, size_t *);
 
@@ -70,5 +71,5 @@
 	fibril_mutex_lock(&con->buf_lock);
 
-	c = IPC_GET_ARG2(*call);
+	c = ipc_get_arg2(call);
 	rc = circ_buf_push(&con->cbuf, &c);
 	if (rc != EOK)
@@ -85,4 +86,5 @@
 	irq_cmd_t *msim_cmds = NULL;
 	errno_t rc;
+	bool bound = false;
 
 	circ_buf_init(&con->cbuf, con->buf, msim_con_buf_size, 1);
@@ -143,10 +145,19 @@
 	}
 
-	ddf_fun_add_to_category(fun, "console");
+	bound = true;
+
+	rc = ddf_fun_add_to_category(fun, "console");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error adding function 'a' to category "
+		    "'console'.");
+		goto error;
+	}
 
 	return EOK;
 error:
-	if (CAP_HANDLE_VALID(con->irq_handle))
+	if (cap_handle_valid(con->irq_handle))
 		async_irq_unsubscribe(con->irq_handle);
+	if (bound)
+		ddf_fun_unbind(fun);
 	if (fun != NULL)
 		ddf_fun_destroy(fun);
@@ -175,5 +186,5 @@
 /** Read from msim console device */
 static errno_t msim_con_read(chardev_srv_t *srv, void *buf, size_t size,
-    size_t *nread)
+    size_t *nread, chardev_flags_t flags)
 {
 	msim_con_t *con = (msim_con_t *) srv->srvs->sarg;
@@ -184,5 +195,6 @@
 	fibril_mutex_lock(&con->buf_lock);
 
-	while (circ_buf_nused(&con->cbuf) == 0)
+	while ((flags & chardev_f_nonblock) == 0 &&
+	    circ_buf_nused(&con->cbuf) == 0)
 		fibril_condvar_wait(&con->buf_cv, &con->buf_lock);
 
Index: uspace/drv/char/ns8250/ns8250.c
===================================================================
--- uspace/drv/char/ns8250/ns8250.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/char/ns8250/ns8250.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -246,8 +246,11 @@
  * @param count		The number of bytes to be read.
  * @param nread		Place to store number of bytes actually read
+ * @param flags		@c chardev_f_nonblock not to block waiting for data
+ *			even if no data is available
  *
  * @return		EOK on success or non-zero error code
  */
-static errno_t ns8250_read(chardev_srv_t *srv, void *buf, size_t count, size_t *nread)
+static errno_t ns8250_read(chardev_srv_t *srv, void *buf, size_t count, size_t *nread,
+    chardev_flags_t flags)
 {
 	ns8250_t *ns = srv_ns8250(srv);
@@ -261,5 +264,6 @@
 
 	fibril_mutex_lock(&ns->mutex);
-	while (buf_is_empty(&ns->input_buffer))
+	while ((flags & chardev_f_none) == 0 &&
+	    buf_is_empty(&ns->input_buffer))
 		fibril_condvar_wait(&ns->input_buffer_available, &ns->mutex);
 	while (!buf_is_empty(&ns->input_buffer) && pos < count) {
@@ -829,4 +833,5 @@
 	bool need_cleanup = false;
 	bool need_unreg_intr_handler = false;
+	bool bound = false;
 	errno_t rc;
 
@@ -909,7 +914,12 @@
 	}
 
+	bound = true;
 	ns->fun = fun;
 
-	ddf_fun_add_to_category(fun, "serial");
+	rc = ddf_fun_add_to_category(fun, "serial");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error adding function to category 'serial'.");
+		goto fail;
+	}
 
 	ddf_msg(LVL_NOTE, "Device %s successfully initialized.",
@@ -918,4 +928,6 @@
 	return EOK;
 fail:
+	if (bound)
+		ddf_fun_unbind(fun);
 	if (fun != NULL)
 		ddf_fun_destroy(fun);
@@ -1068,5 +1080,5 @@
 {
 	ns8250_t *ns8250 = srv_ns8250(srv);
-	sysarg_t method = IPC_GET_IMETHOD(*call);
+	sysarg_t method = ipc_get_imethod(call);
 	errno_t ret;
 	unsigned int baud_rate, parity, word_length, stop_bits;
@@ -1081,8 +1093,8 @@
 
 	case SERIAL_SET_COM_PROPS:
-		baud_rate = IPC_GET_ARG1(*call);
-		parity = IPC_GET_ARG2(*call);
-		word_length = IPC_GET_ARG3(*call);
-		stop_bits = IPC_GET_ARG4(*call);
+		baud_rate = ipc_get_arg1(call);
+		parity = ipc_get_arg2(call);
+		word_length = ipc_get_arg3(call);
+		stop_bits = ipc_get_arg4(call);
 		ret = ns8250_set_props(ns8250->dev, baud_rate, parity, word_length,
 		    stop_bits);
Index: uspace/drv/char/pc-lpt/Makefile
===================================================================
--- uspace/drv/char/pc-lpt/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pc-lpt/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2018 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.
+#
+
+USPACE_PREFIX = ../../..
+LIBS = drv
+BINARY = pc-lpt
+
+SOURCES = \
+	main.c \
+	pc-lpt.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/char/pc-lpt/doc/doxygroups.h
===================================================================
--- uspace/drv/char/pc-lpt/doc/doxygroups.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pc-lpt/doc/doxygroups.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,4 @@
+/** @addtogroup uspace_drv_pc_lpt pc-lpt
+ * @brief PC parallel port driver
+ * @ingroup drvs
+ */
Index: uspace/drv/char/pc-lpt/main.c
===================================================================
--- uspace/drv/char/pc-lpt/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pc-lpt/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2018 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 uspace_drv_pc_lpt
+ * @{
+ */
+/** @file PC parallel port driver
+ */
+
+#include <ddf/driver.h>
+#include <ddf/log.h>
+#include <device/hw_res_parsed.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "pc-lpt.h"
+
+#define NAME  "pc-lpt"
+
+static errno_t pc_lpt_dev_add(ddf_dev_t *dev);
+static errno_t pc_lpt_dev_remove(ddf_dev_t *dev);
+static errno_t pc_lpt_dev_gone(ddf_dev_t *dev);
+static errno_t pc_lpt_fun_online(ddf_fun_t *fun);
+static errno_t pc_lpt_fun_offline(ddf_fun_t *fun);
+
+static driver_ops_t driver_ops = {
+	.dev_add = pc_lpt_dev_add,
+	.dev_remove = pc_lpt_dev_remove,
+	.dev_gone = pc_lpt_dev_gone,
+	.fun_online = pc_lpt_fun_online,
+	.fun_offline = pc_lpt_fun_offline
+};
+
+static driver_t pc_lpt_driver = {
+	.name = NAME,
+	.driver_ops = &driver_ops
+};
+
+static errno_t pc_lpt_get_res(ddf_dev_t *dev, pc_lpt_res_t *res)
+{
+	async_sess_t *parent_sess;
+	hw_res_list_parsed_t hw_res;
+	errno_t rc;
+
+	parent_sess = ddf_dev_parent_sess_get(dev);
+	if (parent_sess == NULL)
+		return ENOMEM;
+
+	hw_res_list_parsed_init(&hw_res);
+	rc = hw_res_get_list_parsed(parent_sess, &hw_res, 0);
+	if (rc != EOK)
+		return rc;
+
+	if (hw_res.io_ranges.count != 1) {
+		rc = EINVAL;
+		goto error;
+	}
+
+	res->base = RNGABS(hw_res.io_ranges.ranges[0]);
+
+	if (hw_res.irqs.count != 1) {
+		rc = EINVAL;
+		goto error;
+	}
+
+	res->irq = hw_res.irqs.irqs[0];
+
+	return EOK;
+error:
+	hw_res_list_parsed_clean(&hw_res);
+	return rc;
+}
+
+static errno_t pc_lpt_dev_add(ddf_dev_t *dev)
+{
+	pc_lpt_t *pc_lpt;
+	pc_lpt_res_t res;
+	errno_t rc;
+
+	ddf_msg(LVL_DEBUG, "pc_lpt_dev_add(%p)", dev);
+
+	pc_lpt = ddf_dev_data_alloc(dev, sizeof(pc_lpt_t));
+	if (pc_lpt == NULL) {
+		ddf_msg(LVL_ERROR, "Failed allocating soft state.");
+		return ENOMEM;
+	}
+
+	pc_lpt->dev = dev;
+
+	rc = pc_lpt_get_res(dev, &res);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed getting hardware resource list.");
+		return EIO;
+	}
+
+	return pc_lpt_add(pc_lpt, &res);
+}
+
+static errno_t pc_lpt_dev_remove(ddf_dev_t *dev)
+{
+	pc_lpt_t *pc_lpt = (pc_lpt_t *)ddf_dev_data_get(dev);
+
+	ddf_msg(LVL_DEBUG, "pc_lpt_dev_remove(%p)", dev);
+
+	return pc_lpt_remove(pc_lpt);
+}
+
+static errno_t pc_lpt_dev_gone(ddf_dev_t *dev)
+{
+	pc_lpt_t *pc_lpt = (pc_lpt_t *)ddf_dev_data_get(dev);
+
+	ddf_msg(LVL_DEBUG, "pc_lpt_dev_gone(%p)", dev);
+
+	return pc_lpt_gone(pc_lpt);
+}
+
+static errno_t pc_lpt_fun_online(ddf_fun_t *fun)
+{
+	ddf_msg(LVL_DEBUG, "pc_lpt_fun_online()");
+	return ddf_fun_online(fun);
+}
+
+static errno_t pc_lpt_fun_offline(ddf_fun_t *fun)
+{
+	ddf_msg(LVL_DEBUG, "pc_lpt_fun_offline()");
+	return ddf_fun_offline(fun);
+}
+
+int main(int argc, char *argv[])
+{
+	printf(NAME ": PC parallel port driver\n");
+	ddf_log_init(NAME);
+	return ddf_driver_main(&pc_lpt_driver);
+}
+
+/** @}
+ */
Index: uspace/drv/char/pc-lpt/pc-lpt.c
===================================================================
--- uspace/drv/char/pc-lpt/pc-lpt.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pc-lpt/pc-lpt.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+/** @file
+ * @brief PC parallel port driver.
+ */
+
+#include <async.h>
+#include <bitops.h>
+#include <ddf/driver.h>
+#include <ddf/log.h>
+#include <ddi.h>
+#include <errno.h>
+#include <fibril_synch.h>
+#include <io/chardev_srv.h>
+
+#include "pc-lpt.h"
+#include "pc-lpt_hw.h"
+
+static void pc_lpt_connection(ipc_call_t *, void *);
+
+static errno_t pc_lpt_read(chardev_srv_t *, void *, size_t, size_t *,
+    chardev_flags_t);
+static errno_t pc_lpt_write(chardev_srv_t *, const void *, size_t, size_t *);
+
+static chardev_ops_t pc_lpt_chardev_ops = {
+	.read = pc_lpt_read,
+	.write = pc_lpt_write
+};
+
+static irq_cmd_t pc_lpt_cmds_proto[] = {
+	{
+		.cmd = CMD_DECLINE
+	}
+};
+
+/** PC LPT IRQ handler.
+ *
+ * Note that while the standard PC parallel port supports IRQ, it seems
+ * drivers tend to avoid using them (for a reason?) These IRQs tend
+ * to be used by other HW as well (Sound Blaster) so caution is in order.
+ * Also not sure, if/how the IRQ needs to be cleared.
+ *
+ * Currently we don't enable IRQ and don't handle it in any way.
+ */
+static void pc_lpt_irq_handler(ipc_call_t *call, void *arg)
+{
+	pc_lpt_t *lpt = (pc_lpt_t *) arg;
+
+	(void) lpt;
+}
+
+/** Add pc-lpt device. */
+errno_t pc_lpt_add(pc_lpt_t *lpt, pc_lpt_res_t *res)
+{
+	ddf_fun_t *fun = NULL;
+	bool bound = false;
+	irq_cmd_t *pc_lpt_cmds = NULL;
+	uint8_t control;
+	uint8_t r;
+	errno_t rc;
+
+	lpt->irq_handle = CAP_NIL;
+	fibril_mutex_initialize(&lpt->hw_lock);
+
+	pc_lpt_cmds = malloc(sizeof(pc_lpt_cmds_proto));
+	if (pc_lpt_cmds == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+
+	lpt->res = *res;
+
+	fun = ddf_fun_create(lpt->dev, fun_exposed, "a");
+	if (fun == NULL) {
+		ddf_msg(LVL_ERROR, "Error creating function 'a'.");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	rc = pio_enable((void *)res->base, sizeof(pc_lpt_regs_t),
+	    (void **) &lpt->regs);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error enabling I/O");
+		goto error;
+	}
+
+	ddf_fun_set_conn_handler(fun, pc_lpt_connection);
+
+	lpt->irq_range[0].base = res->base;
+	lpt->irq_range[0].size = 1;
+
+	memcpy(pc_lpt_cmds, pc_lpt_cmds_proto, sizeof(pc_lpt_cmds_proto));
+	pc_lpt_cmds[0].addr = (void *) res->base;
+
+	lpt->irq_code.rangecount = 1;
+	lpt->irq_code.ranges = lpt->irq_range;
+	lpt->irq_code.cmdcount = sizeof(pc_lpt_cmds_proto) / sizeof(irq_cmd_t);
+	lpt->irq_code.cmds = pc_lpt_cmds;
+
+	rc = async_irq_subscribe(res->irq, pc_lpt_irq_handler, lpt,
+	    &lpt->irq_code, &lpt->irq_handle);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error registering IRQ code.");
+		goto error;
+	}
+
+	control = BIT_V(uint8_t, ctl_select) | BIT_V(uint8_t, ctl_ninit);
+	pio_write_8(&lpt->regs->control, control);
+	r = pio_read_8(&lpt->regs->control);
+	if ((r & 0xf) != control) {
+		/* Device not present */
+		rc = EIO;
+		goto error;
+	}
+
+	control |= BIT_V(uint8_t, ctl_autofd);
+	pio_write_8(&lpt->regs->control, control);
+	r = pio_read_8(&lpt->regs->control);
+	if ((r & 0xf) != control) {
+		/* Device not present */
+		rc = EIO;
+		goto error;
+	}
+
+	control &= ~BIT_V(uint8_t, ctl_autofd);
+	pio_write_8(&lpt->regs->control, control);
+
+	chardev_srvs_init(&lpt->cds);
+	lpt->cds.ops = &pc_lpt_chardev_ops;
+	lpt->cds.sarg = lpt;
+
+	rc = ddf_fun_bind(fun);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error binding function 'a'.");
+		goto error;
+	}
+
+	bound = true;
+
+	rc = ddf_fun_add_to_category(fun, "printer-port");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error adding function 'a' to category "
+		    "'printer-port'.");
+		goto error;
+	}
+
+	return EOK;
+error:
+	if (cap_handle_valid(lpt->irq_handle))
+		async_irq_unsubscribe(lpt->irq_handle);
+	if (bound)
+		ddf_fun_unbind(fun);
+	if (fun != NULL)
+		ddf_fun_destroy(fun);
+	free(pc_lpt_cmds);
+
+	return rc;
+}
+
+/** Remove pc-lpt device */
+errno_t pc_lpt_remove(pc_lpt_t *lpt)
+{
+	return ENOTSUP;
+}
+
+/** Pc-lpt device gone */
+errno_t pc_lpt_gone(pc_lpt_t *lpt)
+{
+	return ENOTSUP;
+}
+
+/** Write a single byte to the parallel port.
+ *
+ * @param lpt Parallel port (locked)
+ * @param ch Byte
+ */
+static void pc_lpt_putchar(pc_lpt_t *lpt, uint8_t ch)
+{
+	uint8_t status;
+	uint8_t control;
+
+	assert(fibril_mutex_is_locked(&lpt->hw_lock));
+
+	/* Write data */
+	pio_write_8(&lpt->regs->data, ch);
+
+	/* Wait for S7/nbusy to become 1 */
+	do {
+		status = pio_read_8(&lpt->regs->status);
+		// FIXME Need to time out with an error after a while
+	} while ((status & BIT_V(uint8_t, sts_nbusy)) == 0);
+
+	control = pio_read_8(&lpt->regs->control);
+	pio_write_8(&lpt->regs->control, control | BIT_V(uint8_t, ctl_strobe));
+	fibril_usleep(5);
+	pio_write_8(&lpt->regs->control, control & ~BIT_V(uint8_t, ctl_strobe));
+}
+
+/** Read from pc-lpt device */
+static errno_t pc_lpt_read(chardev_srv_t *srv, void *buf, size_t size,
+    size_t *nread, chardev_flags_t flags)
+{
+	pc_lpt_t *lpt = (pc_lpt_t *) srv->srvs->sarg;
+	(void) lpt;
+	return ENOTSUP;
+}
+
+/** Write to pc-lpt device */
+static errno_t pc_lpt_write(chardev_srv_t *srv, const void *data, size_t size,
+    size_t *nwr)
+{
+	pc_lpt_t *lpt = (pc_lpt_t *) srv->srvs->sarg;
+	size_t i;
+	uint8_t *dp = (uint8_t *) data;
+
+	fibril_mutex_lock(&lpt->hw_lock);
+
+	for (i = 0; i < size; i++)
+		pc_lpt_putchar(lpt, dp[i]);
+
+	fibril_mutex_unlock(&lpt->hw_lock);
+
+	*nwr = size;
+	return EOK;
+}
+
+/** Character device connection handler. */
+static void pc_lpt_connection(ipc_call_t *icall, void *arg)
+{
+	pc_lpt_t *lpt = (pc_lpt_t *) ddf_dev_data_get(
+	    ddf_fun_get_dev((ddf_fun_t *) arg));
+
+	chardev_conn(icall, &lpt->cds);
+}
+
+/** @}
+ */
Index: uspace/drv/char/pc-lpt/pc-lpt.h
===================================================================
--- uspace/drv/char/pc-lpt/pc-lpt.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pc-lpt/pc-lpt.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018 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 uspace_drv_pc_lpt
+ * @{
+ */
+/** @file
+ */
+
+#ifndef PC_LPT_H
+#define PC_LPT_H
+
+#include <async.h>
+#include <ddf/driver.h>
+#include <ddi.h>
+#include <fibril_synch.h>
+#include <io/chardev_srv.h>
+#include <stdint.h>
+
+#include "pc-lpt_hw.h"
+
+/** PC parallel port resources */
+typedef struct {
+	uintptr_t base;
+	int irq;
+} pc_lpt_res_t;
+
+/** PC parallel port */
+typedef struct {
+	/** DDF device */
+	ddf_dev_t *dev;
+	/** Character device service structure */
+	chardev_srvs_t cds;
+	/** Hardware resources */
+	pc_lpt_res_t res;
+	/** PIO range */
+	irq_pio_range_t irq_range[1];
+	/** IRQ code */
+	irq_code_t irq_code;
+	/** Hardware access lock */
+	fibril_mutex_t hw_lock;
+	/** Hardware registers */
+	pc_lpt_regs_t *regs;
+	/** IRQ handle */
+	cap_irq_handle_t irq_handle;
+} pc_lpt_t;
+
+extern errno_t pc_lpt_add(pc_lpt_t *, pc_lpt_res_t *);
+extern errno_t pc_lpt_remove(pc_lpt_t *);
+extern errno_t pc_lpt_gone(pc_lpt_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/drv/char/pc-lpt/pc-lpt.ma
===================================================================
--- uspace/drv/char/pc-lpt/pc-lpt.ma	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pc-lpt/pc-lpt.ma	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+10 isa/lpt
Index: uspace/drv/char/pc-lpt/pc-lpt_hw.h
===================================================================
--- uspace/drv/char/pc-lpt/pc-lpt_hw.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pc-lpt/pc-lpt_hw.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2018 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 uspace_drv_pc_lpt
+ * @{
+ */
+/** @file
+ */
+
+#ifndef PC_LPT_HW_H
+#define PC_LPT_HW_H
+
+#include <ddi.h>
+
+/** PC parallel port registers */
+typedef struct {
+	/** Data out register */
+	ioport8_t data;
+	/** Status register */
+	ioport8_t status;
+	/** Control register */
+	ioport8_t control;
+} pc_lpt_regs_t;
+
+/** Printer control register bits */
+typedef enum {
+	/** Strobe */
+	ctl_strobe = 0,
+	/** Auto linefeed */
+	ctl_autofd = 1,
+	/** -Init */
+	ctl_ninit = 2,
+	/** Select */
+	ctl_select = 3,
+	/** IRQ Enable */
+	ctl_irq_enable = 4
+} pc_lpt_ctl_bits_t;
+
+/** Printer status register bits */
+typedef enum {
+	/** -Error */
+	sts_nerror = 3,
+	/** Select */
+	sts_select = 4,
+	/** Init */
+	sts_paper_end = 5,
+	/** -Ack */
+	sts_nack = 6,
+	/** -Busy */
+	sts_nbusy = 7
+} pc_lpt_sts_bits_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/drv/char/pl011/Makefile
===================================================================
--- uspace/drv/char/pl011/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pl011/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2016 Petr Pavlu
+# 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 = drv
+BINARY = pl011
+
+SOURCES = \
+	main.c \
+	pl011.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/char/pl011/main.c
===================================================================
--- uspace/drv/char/pl011/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pl011/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2018 Petr Pavlu
+ * 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 uspace_drv_pl011
+ * @{
+ */
+/** @file ARM PrimeCell PL011 UART driver.
+ */
+
+#include <ddf/driver.h>
+#include <ddf/log.h>
+#include <device/hw_res_parsed.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "pl011.h"
+
+#define NAME  "pl011"
+
+static errno_t pl011_dev_add(ddf_dev_t *dev);
+static errno_t pl011_dev_remove(ddf_dev_t *dev);
+static errno_t pl011_dev_gone(ddf_dev_t *dev);
+static errno_t pl011_fun_online(ddf_fun_t *fun);
+static errno_t pl011_fun_offline(ddf_fun_t *fun);
+
+static driver_ops_t driver_ops = {
+	.dev_add = pl011_dev_add,
+	.dev_remove = pl011_dev_remove,
+	.dev_gone = pl011_dev_gone,
+	.fun_online = pl011_fun_online,
+	.fun_offline = pl011_fun_offline
+};
+
+static driver_t pl011_driver = {
+	.name = NAME,
+	.driver_ops = &driver_ops
+};
+
+static errno_t pl011_get_res(ddf_dev_t *dev, pl011_res_t *res)
+{
+	async_sess_t *parent_sess;
+	hw_res_list_parsed_t hw_res;
+	errno_t rc;
+
+	parent_sess = ddf_dev_parent_sess_get(dev);
+	if (parent_sess == NULL)
+		return ENOMEM;
+
+	hw_res_list_parsed_init(&hw_res);
+	rc = hw_res_get_list_parsed(parent_sess, &hw_res, 0);
+	if (rc != EOK)
+		return rc;
+
+	if (hw_res.mem_ranges.count != 1) {
+		rc = EINVAL;
+		goto error;
+	}
+
+	res->base = RNGABS(hw_res.mem_ranges.ranges[0]);
+
+	if (hw_res.irqs.count != 1) {
+		rc = EINVAL;
+		goto error;
+	}
+
+	res->irq = hw_res.irqs.irqs[0];
+
+	return EOK;
+error:
+	hw_res_list_parsed_clean(&hw_res);
+	return rc;
+}
+
+static errno_t pl011_dev_add(ddf_dev_t *dev)
+{
+	pl011_t *pl011;
+	pl011_res_t res;
+	errno_t rc;
+
+	ddf_msg(LVL_DEBUG, "pl011_dev_add(%p)", dev);
+
+	pl011 = ddf_dev_data_alloc(dev, sizeof(pl011_t));
+	if (pl011 == NULL) {
+		ddf_msg(LVL_ERROR, "Failed allocating soft state.");
+		return ENOMEM;
+	}
+
+	pl011->dev = dev;
+
+	rc = pl011_get_res(dev, &res);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed getting hardware resource list.");
+		return EIO;
+	}
+
+	return pl011_add(pl011, &res);
+}
+
+static errno_t pl011_dev_remove(ddf_dev_t *dev)
+{
+	pl011_t *pl011 = (pl011_t *)ddf_dev_data_get(dev);
+
+	ddf_msg(LVL_DEBUG, "pl011_dev_remove(%p)", dev);
+
+	return pl011_remove(pl011);
+}
+
+static errno_t pl011_dev_gone(ddf_dev_t *dev)
+{
+	pl011_t *pl011 = (pl011_t *)ddf_dev_data_get(dev);
+
+	ddf_msg(LVL_DEBUG, "pl011_dev_gone(%p)", dev);
+
+	return pl011_gone(pl011);
+}
+
+static errno_t pl011_fun_online(ddf_fun_t *fun)
+{
+	ddf_msg(LVL_DEBUG, "pl011_fun_online()");
+	return ddf_fun_online(fun);
+}
+
+static errno_t pl011_fun_offline(ddf_fun_t *fun)
+{
+	ddf_msg(LVL_DEBUG, "pl011_fun_offline()");
+	return ddf_fun_offline(fun);
+}
+
+int main(int argc, char *argv[])
+{
+	printf(NAME ": PL011 serial device driver\n");
+	ddf_log_init(NAME);
+	return ddf_driver_main(&pl011_driver);
+}
+
+/** @}
+ */
Index: uspace/drv/char/pl011/pl011.c
===================================================================
--- uspace/drv/char/pl011/pl011.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pl011/pl011.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 2016 Petr Pavlu
+ * 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 ARM PrimeCell PL011 UART driver.
+ */
+
+#include <async.h>
+#include <ddf/driver.h>
+#include <ddf/log.h>
+#include <ddi.h>
+#include <errno.h>
+#include <io/chardev_srv.h>
+#include <macros.h>
+
+#include "pl011.h"
+
+/** PL011 register map. */
+typedef struct {
+	/** UART data register. */
+	ioport32_t data;
+	union {
+		/** Receive status register (same values that are in upper bits
+		 * of data register).
+		 */
+		const ioport32_t status;
+		/** Error clear register (writing anything clears all errors).
+		 */
+		ioport32_t error_clear;
+	};
+	/** Reserved. */
+	PADD32(4);
+	/** Flag register. */
+	const ioport32_t flag;
+	/** Transmit FIFO full. */
+#define PL011_UART_FLAG_TXFF_FLAG  (1 << 5)
+
+	/** Reserved. */
+	PADD32(1);
+	/** IrDA low-power counter register. */
+	ioport32_t irda_low_power;
+	/** Integer baud rate register. */
+	ioport32_t int_baud_divisor;
+	/** Fractional baud rate register. */
+	ioport32_t fract_baud_divisor;
+	/** Line control register. */
+	ioport32_t line_control_high;
+	/** Control register. */
+	ioport32_t control;
+	/** Interrupt FIFO level select register. */
+	ioport32_t interrupt_fifo;
+	/** Interrupt mask set/clear register. */
+	ioport32_t interrupt_mask;
+	/** Raw interrupt status register (pending interrupts before applying
+	 * the mask).
+	 */
+	const ioport32_t raw_interrupt_status;
+	/** Masked interrupt status register (pending interrupts after applying
+	 * the mask).
+	 */
+	const ioport32_t masked_interrupt_status;
+	/** Interrupt clear register (write 1s to clear pending interrupts). */
+	ioport32_t interrupt_clear;
+
+	/** Interrupt indicating a change in the nUARTRI modem status. */
+#define PL011_UART_INTERRUPT_RIM_FLAG   (1 << 0)
+	/** Interrupt indicating a change in the nUARTCTS modem status. */
+#define PL011_UART_INTERRUPT_CTSM_FLAG  (1 << 1)
+	/** Interrupt indicating a change in the nUARTDCD modem status. */
+#define PL011_UART_INTERRUPT_DCDM_FLAG  (1 << 2)
+	/** Interrupt indicating a change in the nUARTDSR modem status. */
+#define PL011_UART_INTERRUPT_DSRM_FLAG  (1 << 3)
+	/** The receive interrupt. */
+#define PL011_UART_INTERRUPT_RX_FLAG    (1 << 4)
+	/** The transmit interrupt. */
+#define PL011_UART_INTERRUPT_TX_FLAG    (1 << 5)
+	/** The receive timeout interrupt.  */
+#define PL011_UART_INTERRUPT_RT_FLAG    (1 << 6)
+	/** Interrupt indicating an overrun error. */
+#define PL011_UART_INTERRUPT_FE_FLAG    (1 << 7)
+	/** Interrupt indicating a break in the reception. */
+#define PL011_UART_INTERRUPT_PE_FLAG    (1 << 8)
+	/** Interrupt indicating a parity error in the received character. */
+#define PL011_UART_INTERRUPT_BE_FLAG    (1 << 9)
+	/** Interrupt indicating a framing error in the received character. */
+#define PL011_UART_INTERRUPT_OE_FLAG    (1 << 10)
+	/** All interrupt mask. */
+#define PL011_UART_INTERRUPT_ALL        0x3ff
+
+	/** DMA control register. */
+	ioport32_t dma_control;
+	/** Reserved. */
+	PADD32(13);
+	/** Reserved for test purposes. */
+	PADD32(4);
+	/** Reserved. */
+	PADD32(976);
+	/** Reserved for future ID expansion. */
+	PADD32(4);
+	/** UARTPeriphID0 register. */
+	const ioport32_t periph_id0;
+	/** UARTPeriphID1 register. */
+	const ioport32_t periph_id1;
+	/** UARTPeriphID2 register. */
+	const ioport32_t periph_id2;
+	/** UARTPeriphID3 register. */
+	const ioport32_t periph_id3;
+	/** UARTPCellID0 register. */
+	const ioport32_t cell_id0;
+	/** UARTPCellID1 register. */
+	const ioport32_t cell_id1;
+	/** UARTPCellID2 register. */
+	const ioport32_t cell_id2;
+	/** UARTPCellID3 register. */
+	const ioport32_t cell_id3;
+} pl011_uart_regs_t;
+
+static void pl011_connection(ipc_call_t *, void *);
+
+static errno_t pl011_read(chardev_srv_t *, void *, size_t, size_t *,
+    chardev_flags_t);
+static errno_t pl011_write(chardev_srv_t *, const void *, size_t, size_t *);
+
+static chardev_ops_t pl011_chardev_ops = {
+	.read = pl011_read,
+	.write = pl011_write
+};
+
+/** Address range accessed by the PL011 interrupt pseudo-code. */
+static const irq_pio_range_t pl011_ranges_proto[] = {
+	{
+		.base = 0,
+		.size = sizeof(pl011_uart_regs_t)
+	}
+};
+
+/** PL011 interrupt pseudo-code instructions. */
+static const irq_cmd_t pl011_cmds_proto[] = {
+	{
+		/* Read masked_interrupt_status. */
+		.cmd = CMD_PIO_READ_32,
+		.addr = NULL,
+		.dstarg = 1
+	},
+	{
+		.cmd = CMD_AND,
+		.value = PL011_UART_INTERRUPT_RX_FLAG |
+		    PL011_UART_INTERRUPT_RT_FLAG,
+		.srcarg = 1,
+		.dstarg = 3
+	},
+	{
+		.cmd = CMD_PREDICATE,
+		.value = 1,
+		.srcarg = 3
+	},
+	{
+		/* Read data. */
+		.cmd = CMD_PIO_READ_32,
+		.addr = NULL,
+		.dstarg = 2
+	},
+	{
+		.cmd = CMD_ACCEPT
+	}
+};
+
+/** Process an interrupt from a PL011 device. */
+static void pl011_irq_handler(ipc_call_t *call, void *arg)
+{
+	pl011_t *pl011 = (pl011_t *) arg;
+	uint32_t intrs = ipc_get_arg1(call);
+	uint8_t c = ipc_get_arg2(call);
+	errno_t rc;
+
+	if ((intrs & (PL011_UART_INTERRUPT_RX_FLAG |
+	    PL011_UART_INTERRUPT_RT_FLAG)) == 0) {
+		/* TODO */
+		return;
+	}
+
+	fibril_mutex_lock(&pl011->buf_lock);
+
+	rc = circ_buf_push(&pl011->cbuf, &c);
+	if (rc != EOK)
+		ddf_msg(LVL_ERROR, "Buffer overrun");
+
+	fibril_mutex_unlock(&pl011->buf_lock);
+	fibril_condvar_broadcast(&pl011->buf_cv);
+}
+
+/** Add a PL011 device. */
+errno_t pl011_add(pl011_t *pl011, pl011_res_t *res)
+{
+	ddf_fun_t *fun = NULL;
+	irq_pio_range_t *pl011_ranges = NULL;
+	irq_cmd_t *pl011_cmds = NULL;
+	errno_t rc;
+
+	circ_buf_init(&pl011->cbuf, pl011->buf, pl011_buf_size, 1);
+	fibril_mutex_initialize(&pl011->buf_lock);
+	fibril_condvar_initialize(&pl011->buf_cv);
+
+	pl011->irq_handle = CAP_NIL;
+
+	pl011_ranges = malloc(sizeof(pl011_ranges_proto));
+	if (pl011_ranges == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+	pl011_cmds = malloc(sizeof(pl011_cmds_proto));
+	if (pl011_cmds == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+
+	pl011->res = *res;
+
+	fun = ddf_fun_create(pl011->dev, fun_exposed, "a");
+	if (fun == NULL) {
+		ddf_msg(LVL_ERROR, "Error creating function 'a'.");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	rc = pio_enable(
+	    (void *) res->base, sizeof(pl011_uart_regs_t), &pl011->regs);
+	if (rc != EOK)
+		goto error;
+
+	ddf_fun_set_conn_handler(fun, pl011_connection);
+
+	memcpy(pl011_ranges, pl011_ranges_proto, sizeof(pl011_ranges_proto));
+	memcpy(pl011_cmds, pl011_cmds_proto, sizeof(pl011_cmds_proto));
+	pl011_ranges[0].base = res->base;
+	pl011_uart_regs_t *regsphys = (pl011_uart_regs_t *) res->base;
+	pl011_cmds[0].addr = (void *) &regsphys->masked_interrupt_status;
+	pl011_cmds[3].addr = (void *) &regsphys->data;
+
+	pl011->irq_code.rangecount =
+	    sizeof(pl011_ranges_proto) / sizeof(irq_pio_range_t);
+	pl011->irq_code.ranges = pl011_ranges;
+	pl011->irq_code.cmdcount = sizeof(pl011_cmds_proto) / sizeof(irq_cmd_t);
+	pl011->irq_code.cmds = pl011_cmds;
+
+	rc = async_irq_subscribe(res->irq, pl011_irq_handler, pl011,
+	    &pl011->irq_code, &pl011->irq_handle);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error registering IRQ code.");
+		goto error;
+	}
+
+	chardev_srvs_init(&pl011->cds);
+	pl011->cds.ops = &pl011_chardev_ops;
+	pl011->cds.sarg = pl011;
+
+	rc = ddf_fun_bind(fun);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error binding function 'a'.");
+		goto error;
+	}
+
+	ddf_fun_add_to_category(fun, "console");
+
+	return EOK;
+error:
+	if (cap_handle_valid(pl011->irq_handle))
+		async_irq_unsubscribe(pl011->irq_handle);
+	if (fun != NULL)
+		ddf_fun_destroy(fun);
+	free(pl011_ranges);
+	free(pl011_cmds);
+
+	return rc;
+}
+
+/** Remove a PL011 device. */
+errno_t pl011_remove(pl011_t *pl011)
+{
+	return ENOTSUP;
+}
+
+/** A PL011 device gone. */
+errno_t pl011_gone(pl011_t *pl011)
+{
+	return ENOTSUP;
+}
+
+/** Send a character to a PL011 device.
+ *
+ * @param c Character to be printed.
+ */
+static void pl011_putchar(pl011_t *pl011, uint8_t ch)
+{
+	pl011_uart_regs_t *regs = (pl011_uart_regs_t *) pl011->regs;
+
+	/* Wait for space to become available in the TX FIFO. */
+	while (pio_read_32(&regs->flag) & PL011_UART_FLAG_TXFF_FLAG)
+		;
+
+	pio_write_32(&regs->data, ch);
+}
+
+/** Read from a PL011 device. */
+static errno_t pl011_read(chardev_srv_t *srv, void *buf, size_t size,
+    size_t *nread, chardev_flags_t flags)
+{
+	pl011_t *pl011 = (pl011_t *) srv->srvs->sarg;
+	size_t p;
+	uint8_t *bp = (uint8_t *) buf;
+	errno_t rc;
+
+	fibril_mutex_lock(&pl011->buf_lock);
+
+	while ((flags & chardev_f_nonblock) == 0 &&
+	    circ_buf_nused(&pl011->cbuf) == 0)
+		fibril_condvar_wait(&pl011->buf_cv, &pl011->buf_lock);
+
+	p = 0;
+	while (p < size) {
+		rc = circ_buf_pop(&pl011->cbuf, &bp[p]);
+		if (rc != EOK)
+			break;
+		++p;
+	}
+
+	fibril_mutex_unlock(&pl011->buf_lock);
+
+	*nread = p;
+	return EOK;
+}
+
+/** Write to a PL011 device. */
+static errno_t pl011_write(chardev_srv_t *srv, const void *data, size_t size,
+    size_t *nwr)
+{
+	pl011_t *pl011 = (pl011_t *) srv->srvs->sarg;
+	size_t i;
+	uint8_t *dp = (uint8_t *) data;
+
+	for (i = 0; i < size; i++)
+		pl011_putchar(pl011, dp[i]);
+
+	*nwr = size;
+	return EOK;
+}
+
+/** Character device connection handler. */
+static void pl011_connection(ipc_call_t *icall, void *arg)
+{
+	pl011_t *pl011 = (pl011_t *) ddf_dev_data_get(
+	    ddf_fun_get_dev((ddf_fun_t *) arg));
+
+	chardev_conn(icall, &pl011->cds);
+}
+
+/** @}
+ */
Index: uspace/drv/char/pl011/pl011.h
===================================================================
--- uspace/drv/char/pl011/pl011.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pl011/pl011.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2018 Petr Pavlu
+ * 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 uspace_drv_pl011
+ * @{
+ */
+/** @file
+ */
+
+#ifndef PL011_CON_H
+#define PL011_CON_H
+
+#include <adt/circ_buf.h>
+#include <async.h>
+#include <ddf/driver.h>
+#include <ddi.h>
+#include <fibril_synch.h>
+#include <io/chardev_srv.h>
+#include <loc.h>
+#include <stdint.h>
+
+enum {
+	pl011_buf_size = 64
+};
+
+/** PL011 device resources. */
+typedef struct {
+	uintptr_t base;
+	int irq;
+} pl011_res_t;
+
+/** PL011 device. */
+typedef struct {
+	ddf_dev_t *dev;
+	chardev_srvs_t cds;
+	pl011_res_t res;
+	irq_code_t irq_code;
+	circ_buf_t cbuf;
+	uint8_t buf[pl011_buf_size];
+	fibril_mutex_t buf_lock;
+	fibril_condvar_t buf_cv;
+	void *regs;
+	cap_irq_handle_t irq_handle;
+} pl011_t;
+
+extern errno_t pl011_add(pl011_t *, pl011_res_t *);
+extern errno_t pl011_remove(pl011_t *);
+extern errno_t pl011_gone(pl011_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/drv/char/pl011/pl011.ma
===================================================================
--- uspace/drv/char/pl011/pl011.ma	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pl011/pl011.ma	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+10 arm/pl011
Index: uspace/drv/char/pl050/pl050.c
===================================================================
--- uspace/drv/char/pl050/pl050.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/char/pl050/pl050.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -59,5 +59,6 @@
 static errno_t pl050_fun_offline(ddf_fun_t *);
 static void pl050_char_conn(ipc_call_t *, void *);
-static errno_t pl050_read(chardev_srv_t *, void *, size_t, size_t *);
+static errno_t pl050_read(chardev_srv_t *, void *, size_t, size_t *,
+    chardev_flags_t);
 static errno_t pl050_write(chardev_srv_t *, const void *, size_t, size_t *);
 
@@ -156,5 +157,5 @@
 	}
 
-	pl050->buffer[pl050->buf_wp] = IPC_GET_ARG2(*call);
+	pl050->buffer[pl050->buf_wp] = ipc_get_arg2(call);
 	pl050->buf_wp = nidx;
 	fibril_condvar_broadcast(&pl050->buf_cv);
@@ -242,5 +243,5 @@
 
 static errno_t pl050_read(chardev_srv_t *srv, void *buffer, size_t size,
-    size_t *nread)
+    size_t *nread, chardev_flags_t flags)
 {
 	pl050_t *pl050 = (pl050_t *)srv->srvs->sarg;
@@ -252,5 +253,6 @@
 	left = size;
 	while (left > 0) {
-		while (left == size && pl050->buf_rp == pl050->buf_wp)
+		while ((flags & chardev_f_nonblock) == 0 &&
+		    left == size && pl050->buf_rp == pl050->buf_wp)
 			fibril_condvar_wait(&pl050->buf_cv, &pl050->buf_lock);
 		if (pl050->buf_rp == pl050->buf_wp)
Index: uspace/drv/char/ski-con/ski-con.c
===================================================================
--- uspace/drv/char/ski-con/ski-con.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/char/ski-con/ski-con.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -55,5 +55,6 @@
 static void ski_con_connection(ipc_call_t *, void *);
 
-static errno_t ski_con_read(chardev_srv_t *, void *, size_t, size_t *);
+static errno_t ski_con_read(chardev_srv_t *, void *, size_t, size_t *,
+    chardev_flags_t);
 static errno_t ski_con_write(chardev_srv_t *, const void *, size_t, size_t *);
 
@@ -112,7 +113,12 @@
 	}
 
-	ddf_fun_add_to_category(fun, "console");
-
 	bound = true;
+
+	rc = ddf_fun_add_to_category(fun, "console");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error adding function 'a' to category "
+		    "'console'.");
+		goto error;
+	}
 
 	fid = fibril_create(ski_con_fibril, con);
@@ -255,5 +261,5 @@
 /** Read from Ski console device */
 static errno_t ski_con_read(chardev_srv_t *srv, void *buf, size_t size,
-    size_t *nread)
+    size_t *nread, chardev_flags_t flags)
 {
 	ski_con_t *con = (ski_con_t *) srv->srvs->sarg;
@@ -264,5 +270,6 @@
 	fibril_mutex_lock(&con->buf_lock);
 
-	while (circ_buf_nused(&con->cbuf) == 0)
+	while ((flags & chardev_f_nonblock) == 0 &&
+	    circ_buf_nused(&con->cbuf) == 0)
 		fibril_condvar_wait(&con->buf_cv, &con->buf_lock);
 
Index: uspace/drv/char/sun4v-con/sun4v-con.c
===================================================================
--- uspace/drv/char/sun4v-con/sun4v-con.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/char/sun4v-con/sun4v-con.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -46,5 +46,6 @@
 #define POLL_INTERVAL  10000
 
-static errno_t sun4v_con_read(chardev_srv_t *, void *, size_t, size_t *);
+static errno_t sun4v_con_read(chardev_srv_t *, void *, size_t, size_t *,
+    chardev_flags_t);
 static errno_t sun4v_con_write(chardev_srv_t *, const void *, size_t, size_t *);
 
@@ -74,4 +75,5 @@
 	ddf_fun_t *fun = NULL;
 	errno_t rc;
+	bool bound = false;
 
 	con->res = *res;
@@ -113,5 +115,12 @@
 	}
 
-	ddf_fun_add_to_category(fun, "console");
+	bound = true;
+
+	rc = ddf_fun_add_to_category(fun, "console");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error adding function 'a' to category "
+		    "'console'.");
+		goto error;
+	}
 
 	return EOK;
@@ -123,4 +132,7 @@
 		physmem_unmap((void *) con->output_buffer);
 
+	if (bound)
+		ddf_fun_unbind(fun);
+
 	if (fun != NULL)
 		ddf_fun_destroy(fun);
@@ -143,5 +155,5 @@
 /** Read from Sun4v console device */
 static errno_t sun4v_con_read(chardev_srv_t *srv, void *buf, size_t size,
-    size_t *nread)
+    size_t *nread, chardev_flags_t flags)
 {
 	sun4v_con_t *con = (sun4v_con_t *) srv->srvs->sarg;
@@ -150,5 +162,6 @@
 	char c;
 
-	while (con->input_buffer->read_ptr == con->input_buffer->write_ptr)
+	while ((flags & chardev_f_nonblock) == 0 &&
+	    con->input_buffer->read_ptr == con->input_buffer->write_ptr)
 		fibril_usleep(POLL_INTERVAL);
 
Index: uspace/drv/fb/amdm37x_dispc/main.c
===================================================================
--- uspace/drv/fb/amdm37x_dispc/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/fb/amdm37x_dispc/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -60,5 +60,5 @@
 	ddf_fun_t *fun = ddf_fun_create(dev, fun_exposed, "viz");
 	if (!fun) {
-		ddf_log_error("Failed to create visualizer function\n");
+		ddf_log_error("Failed to create visualizer function.");
 		return ENOMEM;
 	}
@@ -66,5 +66,5 @@
 	visualizer_t *vis = ddf_fun_data_alloc(fun, sizeof(visualizer_t));
 	if (!vis) {
-		ddf_log_error("Failed to allocate visualizer structure\n");
+		ddf_log_error("Failed to allocate visualizer structure.");
 		ddf_fun_destroy(fun);
 		return ENOMEM;
@@ -79,27 +79,36 @@
 	    ddf_dev_data_alloc(dev, sizeof(amdm37x_dispc_t));
 	if (!dispc) {
-		ddf_log_error("Failed to allocate dispc structure\n");
+		ddf_log_error("Failed to allocate dispc structure.");
 		ddf_fun_destroy(fun);
 		return ENOMEM;
 	}
 
-	errno_t ret = amdm37x_dispc_init(dispc, vis);
-	if (ret != EOK) {
-		ddf_log_error("Failed to init dispc: %s\n", str_error(ret));
+	errno_t rc = amdm37x_dispc_init(dispc, vis);
+	if (rc != EOK) {
+		ddf_log_error("Failed to init dispc: %s.", str_error(rc));
 		ddf_fun_destroy(fun);
-		return ret;
+		return rc;
 	}
 
 	/* Bind function */
-	ret = ddf_fun_bind(fun);
-	if (ret != EOK) {
-		ddf_log_error("Failed to bind function: %s\n", str_error(ret));
+	rc = ddf_fun_bind(fun);
+	if (rc != EOK) {
+		ddf_log_error("Failed to bind function: %s.", str_error(rc));
 		amdm37x_dispc_fini(dispc);
 		ddf_fun_destroy(fun);
-		return ret;
+		return rc;
 	}
-	ddf_fun_add_to_category(fun, "visualizer");
 
-	ddf_log_note("Added device `%s'\n", ddf_dev_get_name(dev));
+	rc = ddf_fun_add_to_category(fun, "visualizer");
+	if (rc != EOK) {
+		ddf_log_error("Failed to add function: %s to visualizer "
+		    "category.", str_error(rc));
+		amdm37x_dispc_fini(dispc);
+		ddf_fun_unbind(fun);
+		ddf_fun_destroy(fun);
+		return rc;
+	}
+
+	ddf_log_note("Added device `%s'", ddf_dev_get_name(dev));
 	return EOK;
 }
Index: uspace/drv/fb/kfb/port.c
===================================================================
--- uspace/drv/fb/kfb/port.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/fb/kfb/port.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -348,5 +348,12 @@
 
 	vs->reg_svc_handle = ddf_fun_get_handle(fun_vs);
-	ddf_fun_add_to_category(fun_vs, "visualizer");
+	rc = ddf_fun_add_to_category(fun_vs, "visualizer");
+	if (rc != EOK) {
+		list_remove(&pixel_mode.link);
+		ddf_fun_unbind(fun_vs);
+		ddf_fun_destroy(fun_vs);
+		as_area_destroy(kfb.addr);
+		return rc;
+	}
 
 	return EOK;
Index: uspace/drv/hid/adb-kbd/adb-kbd.c
===================================================================
--- uspace/drv/hid/adb-kbd/adb-kbd.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/hid/adb-kbd/adb-kbd.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -141,12 +141,12 @@
 		errno_t retval = EOK;
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			return;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case ADB_REG_NOTIF:
-			adb_kbd_reg0_data(kbd, IPC_GET_ARG1(call));
+			adb_kbd_reg0_data(kbd, ipc_get_arg1(&call));
 			break;
 		default:
@@ -205,5 +205,5 @@
 	while (true) {
 		async_get_call(&call);
-		method = IPC_GET_IMETHOD(call);
+		method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: uspace/drv/hid/adb-mouse/adb-mouse.c
===================================================================
--- uspace/drv/hid/adb-mouse/adb-mouse.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/hid/adb-mouse/adb-mouse.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -99,12 +99,12 @@
 		errno_t retval = EOK;
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			/* TODO: Handle hangup */
 			return;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case ADB_REG_NOTIF:
-			adb_mouse_data(mouse, IPC_GET_ARG1(call));
+			adb_mouse_data(mouse, ipc_get_arg1(&call));
 			break;
 		default:
@@ -215,5 +215,5 @@
 	while (true) {
 		async_get_call(&call);
-		method = IPC_GET_IMETHOD(call);
+		method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: uspace/drv/hid/atkbd/atkbd.c
===================================================================
--- uspace/drv/hid/atkbd/atkbd.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/hid/atkbd/atkbd.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -211,5 +211,5 @@
 	while (true) {
 		uint8_t code = 0;
-		rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+		rc = chardev_read(kbd->chardev, &code, 1, &nwr, chardev_f_none);
 		if (rc != EOK)
 			return EIO;
@@ -222,9 +222,11 @@
 			map_size = sizeof(scanmap_e0) / sizeof(unsigned int);
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
 		} else if (code == KBD_SCANCODE_SET_EXTENDED_SPECIAL) {
-			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -232,5 +234,6 @@
 				continue;
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -238,5 +241,6 @@
 				continue;
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -244,5 +248,6 @@
 				continue;
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -250,5 +255,6 @@
 				continue;
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -256,5 +262,6 @@
 				continue;
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -262,5 +269,6 @@
 				continue;
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -277,5 +285,6 @@
 		if (code == KBD_SCANCODE_KEY_RELEASE) {
 			type = KEY_RELEASE;
-			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -301,5 +310,5 @@
 static void default_connection_handler(ddf_fun_t *fun, ipc_call_t *icall)
 {
-	const sysarg_t method = IPC_GET_IMETHOD(*icall);
+	const sysarg_t method = ipc_get_imethod(icall);
 	at_kbd_t *kbd = ddf_dev_data_get(ddf_fun_get_dev(fun));
 	async_sess_t *sess;
@@ -418,5 +427,6 @@
 		return EIO;
 	}
-	rc = chardev_read(kbd->chardev, &code, 1, &bytes);
+	rc = chardev_read(kbd->chardev, &code, 1, &bytes,
+	    chardev_f_none);
 	if (rc != EOK || code != AT_KBD_ACK) {
 		ddf_msg(LVL_ERROR, "Failed to confirm keyboard enable: %hhx.",
Index: uspace/drv/hid/ps2mouse/ps2mouse.c
===================================================================
--- uspace/drv/hid/ps2mouse/ps2mouse.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/hid/ps2mouse/ps2mouse.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -49,4 +49,5 @@
 #define PS2_MOUSE_SET_SAMPLE_RATE   0xf3
 #define PS2_MOUSE_ENABLE_DATA_REPORT   0xf4
+#define PS2_MOUSE_DISABLE_DATA_REPORT   0xf5
 #define PS2_MOUSE_ACK   0xfa
 
@@ -77,5 +78,6 @@
 	uint8_t data = 0; \
 	size_t nread; \
-	const errno_t rc = chardev_read((mouse)->chardev, &data, 1, &nread); \
+	const errno_t rc = chardev_read((mouse)->chardev, &data, 1, &nread, \
+	    chardev_f_none); \
 	if (rc != EOK) { \
 		ddf_msg(LVL_ERROR, "Failed reading byte: %s", str_error_name(rc));\
@@ -164,4 +166,26 @@
 	}
 
+	/* Disable mouse data reporting. */
+	uint8_t report = PS2_MOUSE_ENABLE_DATA_REPORT;
+	size_t nwr;
+	rc = chardev_write(mouse->chardev, &report, 1, &nwr);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed to enable data reporting.");
+		rc = EIO;
+		goto error;
+	}
+
+	/* Drain input buffer */
+	size_t nread;
+	uint8_t b;
+	do {
+		rc = chardev_read(mouse->chardev, &b, 1, &nread, chardev_f_nonblock);
+		if (rc != EOK) {
+			ddf_msg(LVL_ERROR, "Failed to drain input buffer.\n");
+			rc = EIO;
+			goto error;
+		}
+	} while (nread > 0);
+
 	/* Probe IntelliMouse extensions. */
 	errno_t (*polling_f)(void *) = polling_ps2;
@@ -174,6 +198,5 @@
 
 	/* Enable mouse data reporting. */
-	uint8_t report = PS2_MOUSE_ENABLE_DATA_REPORT;
-	size_t nwr;
+	report = PS2_MOUSE_ENABLE_DATA_REPORT;
 	rc = chardev_write(mouse->chardev, &report, 1, &nwr);
 	if (rc != EOK) {
@@ -183,6 +206,5 @@
 	}
 
-	size_t nread;
-	rc = chardev_read(mouse->chardev, &report, 1, &nread);
+	rc = chardev_read(mouse->chardev, &report, 1, &nread, chardev_f_none);
 	if (rc != EOK || report != PS2_MOUSE_ACK) {
 		ddf_msg(LVL_ERROR, "Failed to confirm data reporting: %hhx.",
@@ -232,5 +254,5 @@
 	while (pos < psize) {
 		rc = chardev_read(mouse->chardev, pbuf + pos, psize - pos,
-		    &nread);
+		    &nread, chardev_f_none);
 		if (rc != EOK) {
 			ddf_msg(LVL_WARN, "Error reading packet.");
@@ -407,5 +429,5 @@
 void default_connection_handler(ddf_fun_t *fun, ipc_call_t *icall)
 {
-	const sysarg_t method = IPC_GET_IMETHOD(*icall);
+	const sysarg_t method = ipc_get_imethod(icall);
 	ps2_mouse_t *mouse = ddf_dev_data_get(ddf_fun_get_dev(fun));
 	async_sess_t *sess;
Index: uspace/drv/hid/usbhid/kbd/kbddev.c
===================================================================
--- uspace/drv/hid/usbhid/kbd/kbddev.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/hid/usbhid/kbd/kbddev.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -159,5 +159,5 @@
 static void default_connection_handler(ddf_fun_t *fun, ipc_call_t *icall)
 {
-	const sysarg_t method = IPC_GET_IMETHOD(*icall);
+	const sysarg_t method = ipc_get_imethod(icall);
 	usb_kbd_t *kbd_dev = ddf_fun_data_get(fun);
 	async_sess_t *sess;
@@ -165,5 +165,5 @@
 	switch (method) {
 	case KBDEV_SET_IND:
-		kbd_dev->mods = IPC_GET_ARG1(*icall);
+		kbd_dev->mods = ipc_get_arg1(icall);
 		usb_kbd_set_led(kbd_dev->hid_dev, kbd_dev);
 		async_answer_0(icall, EOK);
Index: uspace/drv/hid/xtkbd/xtkbd.c
===================================================================
--- uspace/drv/hid/xtkbd/xtkbd.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/hid/xtkbd/xtkbd.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -216,5 +216,5 @@
 
 		uint8_t code = 0;
-		rc = chardev_read(kbd->chardev, &code, 1, &nread);
+		rc = chardev_read(kbd->chardev, &code, 1, &nread, chardev_f_none);
 		if (rc != EOK)
 			return EIO;
@@ -229,5 +229,6 @@
 			map_size = sizeof(scanmap_e0) / sizeof(unsigned int);
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nread);
+			rc = chardev_read(kbd->chardev, &code, 1, &nread,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -236,5 +237,6 @@
 
 			if (code == 0x2a) {  /* Print Screen */
-				rc = chardev_read(kbd->chardev, &code, 1, &nread);
+				rc = chardev_read(kbd->chardev, &code, 1, &nread,
+				    chardev_f_none);
 				if (rc != EOK)
 					return EIO;
@@ -243,5 +245,6 @@
 					continue;
 
-				rc = chardev_read(kbd->chardev, &code, 1, &nread);
+				rc = chardev_read(kbd->chardev, &code, 1, &nread,
+				    chardev_f_none);
 				if (rc != EOK)
 					return EIO;
@@ -254,5 +257,6 @@
 
 			if (code == 0x46) {  /* Break */
-				rc = chardev_read(kbd->chardev, &code, 1, &nread);
+				rc = chardev_read(kbd->chardev, &code, 1, &nread,
+				    chardev_f_none);
 				if (rc != EOK)
 					return EIO;
@@ -261,5 +265,6 @@
 					continue;
 
-				rc = chardev_read(kbd->chardev, &code, 1, &nread);
+				rc = chardev_read(kbd->chardev, &code, 1, &nread,
+				    chardev_f_none);
 				if (rc != EOK)
 					return EIO;
@@ -274,5 +279,6 @@
 		/* Extended special set */
 		if (code == KBD_SCANCODE_SET_EXTENDED_SPECIAL) {
-			rc = chardev_read(kbd->chardev, &code, 1, &nread);
+			rc = chardev_read(kbd->chardev, &code, 1, &nread,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -281,5 +287,6 @@
 				continue;
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nread);
+			rc = chardev_read(kbd->chardev, &code, 1, &nread,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -288,5 +295,6 @@
 				continue;
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nread);
+			rc = chardev_read(kbd->chardev, &code, 1, &nread,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -295,5 +303,6 @@
 				continue;
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nread);
+			rc = chardev_read(kbd->chardev, &code, 1, &nread,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -302,5 +311,6 @@
 				continue;
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nread);
+			rc = chardev_read(kbd->chardev, &code, 1, &nread,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -334,5 +344,5 @@
 static void default_connection_handler(ddf_fun_t *fun, ipc_call_t *icall)
 {
-	const sysarg_t method = IPC_GET_IMETHOD(*icall);
+	const sysarg_t method = ipc_get_imethod(icall);
 	xt_kbd_t *kbd = ddf_dev_data_get(ddf_fun_get_dev(fun));
 	unsigned mods;
@@ -345,5 +355,5 @@
 		 * assume AT keyboard with Scan Code Set 1.
 		 */
-		mods = IPC_GET_ARG1(*icall);
+		mods = ipc_get_arg1(icall);
 		const uint8_t status = 0 |
 		    ((mods & KM_CAPS_LOCK) ? LI_CAPS : 0) |
Index: uspace/drv/intctl/apic/apic.c
===================================================================
--- uspace/drv/intctl/apic/apic.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/intctl/apic/apic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -179,5 +179,5 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			/* The other side has hung up. */
 			async_answer_0(&call, EOK);
@@ -185,8 +185,8 @@
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case IRC_ENABLE_INTERRUPT:
 			async_answer_0(&call, apic_enable_irq(apic,
-			    IPC_GET_ARG1(call)));
+			    ipc_get_arg1(&call)));
 			break;
 		case IRC_DISABLE_INTERRUPT:
@@ -212,4 +212,5 @@
 	void *regs;
 	errno_t rc;
+	bool bound = false;
 
 	if ((sysinfo_get_value("apic", &have_apic) != EOK) || (!have_apic)) {
@@ -241,4 +242,6 @@
 	}
 
+	bound = true;
+
 	rc = ddf_fun_add_to_category(fun_a, "irc");
 	if (rc != EOK)
@@ -247,4 +250,6 @@
 	return EOK;
 error:
+	if (bound)
+		ddf_fun_unbind(fun_a);
 	if (fun_a != NULL)
 		ddf_fun_destroy(fun_a);
Index: uspace/drv/intctl/gicv2/Makefile
===================================================================
--- uspace/drv/intctl/gicv2/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/intctl/gicv2/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2016 Petr Pavlu
+# 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 = drv
+BINARY = gicv2
+
+SOURCES = \
+	gicv2.c \
+	main.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/intctl/gicv2/gicv2.c
===================================================================
--- uspace/drv/intctl/gicv2/gicv2.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/intctl/gicv2/gicv2.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2018 Petr Pavlu
+ * 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 uspace_drv_gicv2
+ * @{
+ */
+
+/** @file
+ */
+
+#include <async.h>
+#include <bitops.h>
+#include <ddi.h>
+#include <ddf/log.h>
+#include <errno.h>
+#include <macros.h>
+#include <str_error.h>
+#include <ipc/irc.h>
+#include <stdint.h>
+
+#include "gicv2.h"
+
+/** GICv2 distributor register map. */
+typedef struct {
+	/** Distributor control register. */
+	ioport32_t ctlr;
+#define GICV2D_CTLR_ENABLE_FLAG  0x1
+
+	/** Interrupt controller type register. */
+	const ioport32_t typer;
+#define GICV2D_TYPER_IT_LINES_NUMBER_SHIFT  0
+#define GICV2D_TYPER_IT_LINES_NUMBER_MASK \
+	(0x1f << GICV2D_TYPER_IT_LINES_NUMBER_SHIFT)
+
+	/** Distributor implementer identification register. */
+	const ioport32_t iidr;
+	/** Reserved. */
+	PADD32(5);
+	/** Implementation defined registers. */
+	ioport32_t impl[8];
+	/** Reserved. */
+	PADD32(16);
+	/** Interrupt group registers. */
+	ioport32_t igroupr[32];
+	/** Interrupt set-enable registers. */
+	ioport32_t isenabler[32];
+	/** Interrupt clear-enable registers. */
+	ioport32_t icenabler[32];
+	/** Interrupt set-pending registers. */
+	ioport32_t ispendr[32];
+	/** Interrupt clear-pending registers. */
+	ioport32_t icpendr[32];
+	/** GICv2 interrupt set-active registers. */
+	ioport32_t isactiver[32];
+	/** Interrupt clear-active registers. */
+	ioport32_t icactiver[32];
+	/** Interrupt priority registers. */
+	ioport32_t ipriorityr[255];
+	/** Reserved. */
+	PADD32(1);
+	/** Interrupt processor target registers. First 8 words are read-only.
+	 */
+	ioport32_t itargetsr[255];
+	/** Reserved. */
+	PADD32(1);
+	/** Interrupt configuration registers. */
+	ioport32_t icfgr[64];
+	/** Implementation defined registers. */
+	ioport32_t impl2[64];
+	/** Non-secure access control registers. */
+	ioport32_t nsacr[64];
+	/** Software generated interrupt register. */
+	ioport32_t sgir;
+	/** Reserved. */
+	PADD32(3);
+	/** SGI clear-pending registers. */
+	ioport32_t cpendsgir[4];
+	/** SGI set-pending registers. */
+	ioport32_t spendsgir[4];
+	/** Reserved. */
+	PADD32(40);
+	/** Implementation defined identification registers. */
+	const ioport32_t impl3[12];
+} gicv2_distr_regs_t;
+
+/* GICv2 CPU interface register map. */
+typedef struct {
+	/** CPU interface control register. */
+	ioport32_t ctlr;
+#define GICV2C_CTLR_ENABLE_FLAG  0x1
+
+	/** Interrupt priority mask register. */
+	ioport32_t pmr;
+	/** Binary point register. */
+	ioport32_t bpr;
+	/** Interrupt acknowledge register. */
+	const ioport32_t iar;
+#define GICV2C_IAR_INTERRUPT_ID_SHIFT  0
+#define GICV2C_IAR_INTERRUPT_ID_MASK \
+	(0x3ff << GICV2C_IAR_INTERRUPT_ID_SHIFT)
+#define GICV2C_IAR_CPUID_SHIFT  10
+#define GICV2C_IAR_CPUID_MASK \
+	(0x7 << GICV2C_IAR_CPUID_SHIFT)
+
+	/** End of interrupt register. */
+	ioport32_t eoir;
+	/** Running priority register. */
+	const ioport32_t rpr;
+	/** Highest priority pending interrupt register. */
+	const ioport32_t hppir;
+	/** Aliased binary point register. */
+	ioport32_t abpr;
+	/** Aliased interrupt acknowledge register. */
+	const ioport32_t aiar;
+	/** Aliased end of interrupt register. */
+	ioport32_t aeoir;
+	/** Aliased highest priority pending interrupt register. */
+	const ioport32_t ahppir;
+	/** Reserved. */
+	PADD32(5);
+	/** Implementation defined registers. */
+	ioport32_t impl[36];
+	/** Active priorities registers. */
+	ioport32_t apr[4];
+	/** Non-secure active priorities registers. */
+	ioport32_t nsapr[4];
+	/** Reserved. */
+	PADD32(3);
+	/** CPU interface identification register. */
+	const ioport32_t iidr;
+	/** Unallocated. */
+	PADD32(960);
+	/** Deactivate interrupt register. */
+	ioport32_t dir;
+} gicv2_cpui_regs_t;
+
+static errno_t gicv2_enable_irq(gicv2_t *gicv2, sysarg_t irq)
+{
+	if (irq > gicv2->max_irq)
+		return EINVAL;
+
+	ddf_msg(LVL_NOTE, "Enable interrupt '%" PRIun "'.", irq);
+
+	gicv2_distr_regs_t *distr = (gicv2_distr_regs_t *) gicv2->distr;
+	pio_write_32(&distr->isenabler[irq / 32], BIT_V(uint32_t, irq % 32));
+	return EOK;
+}
+
+/** Client connection handler.
+ *
+ * @param icall Call data of the request that opened the connection.
+ * @param arg   Local argument.
+ */
+static void gicv2_connection(ipc_call_t *icall, void *arg)
+{
+	ipc_call_t call;
+	gicv2_t *gicv2;
+
+	/*
+	 * Answer the first IPC_M_CONNECT_ME_TO call.
+	 */
+	async_answer_0(icall, EOK);
+
+	gicv2 = (gicv2_t *)ddf_dev_data_get(ddf_fun_get_dev((ddf_fun_t *)arg));
+
+	while (true) {
+		async_get_call(&call);
+
+		if (!ipc_get_imethod(&call)) {
+			/* The other side has hung up. */
+			async_answer_0(&call, EOK);
+			return;
+		}
+
+		switch (ipc_get_imethod(&call)) {
+		case IRC_ENABLE_INTERRUPT:
+			async_answer_0(&call,
+			    gicv2_enable_irq(gicv2, ipc_get_arg1(&call)));
+			break;
+		case IRC_DISABLE_INTERRUPT:
+			/* XXX TODO */
+			async_answer_0(&call, EOK);
+			break;
+		case IRC_CLEAR_INTERRUPT:
+			/* Noop */
+			async_answer_0(&call, EOK);
+			break;
+		default:
+			async_answer_0(&call, EINVAL);
+			break;
+		}
+	}
+}
+
+/** Add a GICv2 device. */
+errno_t gicv2_add(gicv2_t *gicv2, gicv2_res_t *res)
+{
+	ddf_fun_t *fun_a = NULL;
+	errno_t rc;
+
+	rc = pio_enable((void *) res->distr_base, sizeof(gicv2_distr_regs_t),
+	    &gicv2->distr);
+	if (rc != EOK) {
+		ddf_msg(
+		    LVL_ERROR, "Error enabling PIO for distributor registers.");
+		goto error;
+	}
+
+	rc = pio_enable(
+	    (void *) res->cpui_base, sizeof(gicv2_cpui_regs_t), &gicv2->cpui);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR,
+		    "Error enabling PIO for CPU interface registers.");
+		goto error;
+	}
+
+	fun_a = ddf_fun_create(gicv2->dev, fun_exposed, "a");
+	if (fun_a == NULL) {
+		ddf_msg(LVL_ERROR, "Failed creating function 'a'.");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	ddf_fun_set_conn_handler(fun_a, gicv2_connection);
+
+	rc = ddf_fun_bind(fun_a);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed binding function 'a': %s",
+		    str_error(rc));
+		goto error;
+	}
+
+	rc = ddf_fun_add_to_category(fun_a, "irc");
+	if (rc != EOK)
+		goto error;
+
+	/* Get maximum number of interrupts. */
+	gicv2_distr_regs_t *distr = (gicv2_distr_regs_t *) gicv2->distr;
+	uint32_t typer = pio_read_32(&distr->typer);
+	gicv2->max_irq = (((typer & GICV2D_TYPER_IT_LINES_NUMBER_MASK) >>
+	    GICV2D_TYPER_IT_LINES_NUMBER_SHIFT) + 1) * 32;
+
+	return EOK;
+error:
+	if (fun_a != NULL)
+		ddf_fun_destroy(fun_a);
+	return rc;
+}
+
+/** Remove a GICv2 device. */
+errno_t gicv2_remove(gicv2_t *gicv2)
+{
+	return ENOTSUP;
+}
+
+/** A GICv2 device gone. */
+errno_t gicv2_gone(gicv2_t *gicv2)
+{
+	return ENOTSUP;
+}
+
+/** @}
+ */
Index: uspace/drv/intctl/gicv2/gicv2.h
===================================================================
--- uspace/drv/intctl/gicv2/gicv2.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/intctl/gicv2/gicv2.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2018 Petr Pavlu
+ * 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 uspace_drv_gicv2
+ * @{
+ */
+/** @file
+ */
+
+#ifndef GICV2_H_
+#define GICV2_H_
+
+#include <ddf/driver.h>
+#include <loc.h>
+#include <stdint.h>
+
+typedef struct {
+	uintptr_t distr_base;
+	uintptr_t cpui_base;
+} gicv2_res_t;
+
+/** GICv2 interrupt controller. */
+typedef struct {
+	ddf_dev_t *dev;
+	void *distr;
+	void *cpui;
+	unsigned max_irq;
+} gicv2_t;
+
+extern errno_t gicv2_add(gicv2_t *, gicv2_res_t *);
+extern errno_t gicv2_remove(gicv2_t *);
+extern errno_t gicv2_gone(gicv2_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/drv/intctl/gicv2/gicv2.ma
===================================================================
--- uspace/drv/intctl/gicv2/gicv2.ma	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/intctl/gicv2/gicv2.ma	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+10 arm/gicv2
Index: uspace/drv/intctl/gicv2/main.c
===================================================================
--- uspace/drv/intctl/gicv2/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/intctl/gicv2/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2018 Petr Pavlu
+ * 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 uspace_drv_gicv2
+ * @{
+ */
+/** @file GICv2 driver.
+ * @brief ARM Generic Interrupt Controller, Architecture version 2.0.
+ *
+ * This IRQ controller is present on the QEMU virt platform for ARM.
+ */
+
+#include <ddf/driver.h>
+#include <ddf/log.h>
+#include <device/hw_res_parsed.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "gicv2.h"
+
+#define NAME  "gicv2"
+
+static errno_t gicv2_dev_add(ddf_dev_t *dev);
+static errno_t gicv2_dev_remove(ddf_dev_t *dev);
+static errno_t gicv2_dev_gone(ddf_dev_t *dev);
+static errno_t gicv2_fun_online(ddf_fun_t *fun);
+static errno_t gicv2_fun_offline(ddf_fun_t *fun);
+
+static driver_ops_t driver_ops = {
+	.dev_add = gicv2_dev_add,
+	.dev_remove = gicv2_dev_remove,
+	.dev_gone = gicv2_dev_gone,
+	.fun_online = gicv2_fun_online,
+	.fun_offline = gicv2_fun_offline
+};
+
+static driver_t gicv2_driver = {
+	.name = NAME,
+	.driver_ops = &driver_ops
+};
+
+static errno_t gicv2_get_res(ddf_dev_t *dev, gicv2_res_t *res)
+{
+	async_sess_t *parent_sess;
+	hw_res_list_parsed_t hw_res;
+	errno_t rc;
+
+	parent_sess = ddf_dev_parent_sess_get(dev);
+	if (parent_sess == NULL)
+		return ENOMEM;
+
+	hw_res_list_parsed_init(&hw_res);
+	rc = hw_res_get_list_parsed(parent_sess, &hw_res, 0);
+	if (rc != EOK)
+		return rc;
+
+	if (hw_res.mem_ranges.count != 2) {
+		rc = EINVAL;
+		goto error;
+	}
+
+	res->distr_base = RNGABS(hw_res.mem_ranges.ranges[0]);
+	res->cpui_base = RNGABS(hw_res.mem_ranges.ranges[1]);
+
+	return EOK;
+error:
+	hw_res_list_parsed_clean(&hw_res);
+	return rc;
+}
+
+static errno_t gicv2_dev_add(ddf_dev_t *dev)
+{
+	gicv2_t *gicv2;
+	gicv2_res_t gicv2_res;
+	errno_t rc;
+
+	ddf_msg(LVL_DEBUG, "gicv2_dev_add(%p)", dev);
+	gicv2 = ddf_dev_data_alloc(dev, sizeof(gicv2_t));
+	if (gicv2 == NULL) {
+		ddf_msg(LVL_ERROR, "Failed allocating soft state.");
+		return ENOMEM;
+	}
+
+	gicv2->dev = dev;
+
+	rc = gicv2_get_res(dev, &gicv2_res);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed getting hardware resource list.\n");
+		return EIO;
+	}
+
+	return gicv2_add(gicv2, &gicv2_res);
+}
+
+static errno_t gicv2_dev_remove(ddf_dev_t *dev)
+{
+	gicv2_t *gicv2 = (gicv2_t *)ddf_dev_data_get(dev);
+
+	ddf_msg(LVL_DEBUG, "gicv2_dev_remove(%p)", dev);
+
+	return gicv2_remove(gicv2);
+}
+
+static errno_t gicv2_dev_gone(ddf_dev_t *dev)
+{
+	gicv2_t *gicv2 = (gicv2_t *)ddf_dev_data_get(dev);
+
+	ddf_msg(LVL_DEBUG, "gicv2_dev_gone(%p)", dev);
+
+	return gicv2_gone(gicv2);
+}
+
+static errno_t gicv2_fun_online(ddf_fun_t *fun)
+{
+	ddf_msg(LVL_DEBUG, "gicv2_fun_online()");
+	return ddf_fun_online(fun);
+}
+
+static errno_t gicv2_fun_offline(ddf_fun_t *fun)
+{
+	ddf_msg(LVL_DEBUG, "gicv2_fun_offline()");
+	return ddf_fun_offline(fun);
+}
+
+int main(int argc, char *argv[])
+{
+	printf(NAME ": GICv2 interrupt controller driver\n");
+	ddf_log_init(NAME);
+	return ddf_driver_main(&gicv2_driver);
+}
+
+/** @}
+ */
Index: uspace/drv/intctl/i8259/i8259.c
===================================================================
--- uspace/drv/intctl/i8259/i8259.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/intctl/i8259/i8259.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -108,5 +108,5 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			/* The other side has hung up. */
 			async_answer_0(&call, EOK);
@@ -114,8 +114,8 @@
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case IRC_ENABLE_INTERRUPT:
 			async_answer_0(&call, pic_enable_irq(i8259,
-			    IPC_GET_ARG1(call)));
+			    ipc_get_arg1(&call)));
 			break;
 		case IRC_DISABLE_INTERRUPT:
@@ -142,4 +142,5 @@
 	ddf_fun_t *fun_a = NULL;
 	errno_t rc;
+	bool bound = false;
 
 	if ((sysinfo_get_value("i8259", &have_i8259) != EOK) || (!have_i8259)) {
@@ -174,4 +175,6 @@
 	}
 
+	bound = true;
+
 	rc = ddf_fun_add_to_category(fun_a, "irc");
 	if (rc != EOK)
@@ -180,4 +183,6 @@
 	return EOK;
 error:
+	if (bound)
+		ddf_fun_unbind(fun_a);
 	if (fun_a != NULL)
 		ddf_fun_destroy(fun_a);
Index: uspace/drv/intctl/icp-ic/icp-ic.c
===================================================================
--- uspace/drv/intctl/icp-ic/icp-ic.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/intctl/icp-ic/icp-ic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -84,5 +84,5 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			/* The other side has hung up. */
 			async_answer_0(&call, EOK);
@@ -90,8 +90,8 @@
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case IRC_ENABLE_INTERRUPT:
 			async_answer_0(&call,
-			    icpic_enable_irq(icpic, IPC_GET_ARG1(call)));
+			    icpic_enable_irq(icpic, ipc_get_arg1(&call)));
 			break;
 		case IRC_DISABLE_INTERRUPT:
@@ -116,4 +116,5 @@
 	void *regs;
 	errno_t rc;
+	bool bound = false;
 
 	rc = pio_enable((void *)res->base, sizeof(icpic_regs_t), &regs);
@@ -146,4 +147,6 @@
 	return EOK;
 error:
+	if (bound)
+		ddf_fun_unbind(fun_a);
 	if (fun_a != NULL)
 		ddf_fun_destroy(fun_a);
Index: uspace/drv/intctl/obio/obio.c
===================================================================
--- uspace/drv/intctl/obio/obio.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/intctl/obio/obio.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -90,7 +90,7 @@
 		async_get_call(&call);
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case IRC_ENABLE_INTERRUPT:
-			inr = IPC_GET_ARG1(call);
+			inr = ipc_get_arg1(&call);
 			pio_set_64(&obio->regs[OBIO_IMR(inr & INO_MASK)],
 			    1UL << 31, 0);
@@ -102,5 +102,5 @@
 			break;
 		case IRC_CLEAR_INTERRUPT:
-			inr = IPC_GET_ARG1(call);
+			inr = ipc_get_arg1(&call);
 			pio_write_64(&obio->regs[OBIO_CIR(inr & INO_MASK)], 0);
 			async_answer_0(&call, EOK);
@@ -118,4 +118,5 @@
 	ddf_fun_t *fun_a = NULL;
 	errno_t rc;
+	bool bound = false;
 
 	rc = pio_enable((void *)res->base, OBIO_SIZE, (void **) &obio->regs);
@@ -149,4 +150,6 @@
 	return EOK;
 error:
+	if (bound)
+		ddf_fun_unbind(fun_a);
 	if (fun_a != NULL)
 		ddf_fun_destroy(fun_a);
Index: uspace/drv/nic/e1k/e1k.c
===================================================================
--- uspace/drv/nic/e1k/e1k.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/nic/e1k/e1k.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1244,5 +1244,5 @@
     ddf_dev_t *dev)
 {
-	uint32_t icr = (uint32_t) IPC_GET_ARG2(*icall);
+	uint32_t icr = (uint32_t) ipc_get_arg2(icall);
 	nic_t *nic = NIC_DATA_DEV(dev);
 	e1000_t *e1000 = DRIVER_DATA_NIC(nic);
Index: uspace/drv/nic/ne2k/ne2k.c
===================================================================
--- uspace/drv/nic/ne2k/ne2k.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/nic/ne2k/ne2k.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -52,5 +52,5 @@
  *
  */
-#define IRQ_GET_ISR(call)  ((int) IPC_GET_ARG2(call))
+#define IRQ_GET_ISR(call)  ((int) ipc_get_arg2(&call))
 
 /** Return the TSR from the interrupt call.
@@ -59,5 +59,5 @@
  *
  */
-#define IRQ_GET_TSR(call)  ((int) IPC_GET_ARG3(call))
+#define IRQ_GET_TSR(call)  ((int) ipc_get_arg3(&call))
 
 #define DRIVER_DATA(dev) ((nic_t *) ddf_dev_data_get(dev))
Index: uspace/drv/nic/rtl8139/driver.c
===================================================================
--- uspace/drv/nic/rtl8139/driver.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/nic/rtl8139/driver.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -827,5 +827,5 @@
 	assert(icall);
 
-	uint16_t isr = (uint16_t) IPC_GET_ARG2(*icall);
+	uint16_t isr = (uint16_t) ipc_get_arg2(icall);
 	nic_t *nic_data = nic_get_from_ddf_dev(dev);
 	rtl8139_t *rtl8139 = nic_get_specific(nic_data);
Index: uspace/drv/nic/rtl8139/driver.h
===================================================================
--- uspace/drv/nic/rtl8139/driver.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/nic/rtl8139/driver.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -107,5 +107,5 @@
 	void *tx_buff_virt;
 
-	/** Virtual adresses of the Tx buffers */
+	/** Virtual addresses of the Tx buffers */
 	void *tx_buff[TX_BUFF_COUNT];
 
Index: uspace/drv/nic/rtl8169/driver.c
===================================================================
--- uspace/drv/nic/rtl8169/driver.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/nic/rtl8169/driver.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1038,5 +1038,5 @@
 	assert(icall);
 
-	uint16_t isr = (uint16_t) IPC_GET_ARG2(*icall) & INT_KNOWN;
+	uint16_t isr = (uint16_t) ipc_get_arg2(icall) & INT_KNOWN;
 	nic_t *nic_data = nic_get_from_ddf_dev(dev);
 	rtl8169_t *rtl8169 = nic_get_specific(nic_data);
Index: uspace/drv/nic/virtio-net/virtio-net.c
===================================================================
--- uspace/drv/nic/virtio-net/virtio-net.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/nic/virtio-net/virtio-net.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -211,4 +211,5 @@
 		ddf_msg(LVL_NOTE, "Unsupported number of virtqueues: %u",
 		    num_queues);
+		rc = ELIMIT;
 		goto fail;
 	}
@@ -342,8 +343,9 @@
 	assert(descno < TX_BUFFERS);
 
-	/* Setup the packed header */
+	/* Setup the packet header */
 	virtio_net_hdr_t *hdr = (virtio_net_hdr_t *) virtio_net->tx_buf[descno];
 	memset(hdr, 0, sizeof(virtio_net_hdr_t));
 	hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
+	hdr->num_buffers = 0;
 
 	/* Copy packet data into the buffer just past the header */
@@ -403,5 +405,5 @@
 	if (fun == NULL) {
 		rc = ENOMEM;
-		goto error;
+		goto uninitialize;
 	}
 	nic_t *nic = ddf_dev_data_get(dev);
@@ -417,5 +419,5 @@
 	if (rc != EOK) {
 		ddf_msg(LVL_ERROR, "Failed binding device function");
-		goto uninitialize;
+		goto destroy;
 	}
 
@@ -433,7 +435,8 @@
 unbind:
 	ddf_fun_unbind(fun);
+destroy:
+	ddf_fun_destroy(fun);
 uninitialize:
 	virtio_net_uninitialize(dev);
-error:
 	return rc;
 }
Index: uspace/drv/nic/virtio-net/virtio-net.h
===================================================================
--- uspace/drv/nic/virtio-net/virtio-net.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/nic/virtio-net/virtio-net.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -55,9 +55,5 @@
 	uint16_t csum_start;
 	uint16_t csum_offset;
-
-	// XXX: QEMU uses the legacy layout for some reason
-#if 0
 	uint16_t num_buffers;
-#endif
 } virtio_net_hdr_t;
 
Index: uspace/drv/platform/arm64virt/Makefile
===================================================================
--- uspace/drv/platform/arm64virt/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/platform/arm64virt/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2016 Petr Pavlu
+# 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 = drv
+BINARY = arm64virt
+
+SOURCES = \
+	arm64virt.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/platform/arm64virt/arm64virt.c
===================================================================
--- uspace/drv/platform/arm64virt/arm64virt.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/platform/arm64virt/arm64virt.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2016 Petr Pavlu
+ * 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 arm64virt
+ * @{
+ */
+
+/** @file
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include <ddf/driver.h>
+#include <ddf/log.h>
+#include <ops/hw_res.h>
+#include <ops/pio_window.h>
+
+#define NAME  "arm64virt"
+
+enum {
+	arm64virt_ic_distr_membase = 0x08000000,
+	arm64virt_ic_distr_memsize = 0x00001000,
+	arm64virt_ic_cpui_membase = 0x08010000,
+	arm64virt_ic_cpui_memsize = 0x00001004,
+	arm64virt_uart_irq = 33,
+	arm64virt_uart_membase = 0x09000000,
+	arm64virt_uart_memsize = 0x00001000
+};
+
+typedef struct arm64virt_fun {
+	hw_resource_list_t hw_resources;
+} arm64virt_fun_t;
+
+static errno_t arm64virt_dev_add(ddf_dev_t *);
+
+static driver_ops_t arm64virt_ops = {
+	.dev_add = &arm64virt_dev_add
+};
+
+static driver_t arm64virt_driver = {
+	.name = NAME,
+	.driver_ops = &arm64virt_ops
+};
+
+static hw_resource_t arm64virt_ic_res[] = {
+	{
+		.type = MEM_RANGE,
+		.res.mem_range = {
+			.address = arm64virt_ic_distr_membase,
+			.size = arm64virt_ic_distr_memsize,
+			.relative = false,
+			.endianness = LITTLE_ENDIAN
+		}
+	},
+	{
+		.type = MEM_RANGE,
+		.res.mem_range = {
+			.address = arm64virt_ic_cpui_membase,
+			.size = arm64virt_ic_cpui_memsize,
+			.relative = false,
+			.endianness = LITTLE_ENDIAN
+		}
+	}
+};
+
+static hw_resource_t arm64virt_uart_res[] = {
+	{
+		.type = MEM_RANGE,
+		.res.mem_range = {
+			.address = arm64virt_uart_membase,
+			.size = arm64virt_uart_memsize,
+			.relative = false,
+			.endianness = LITTLE_ENDIAN
+		}
+	},
+	{
+		.type = INTERRUPT,
+		.res.interrupt = {
+			.irq = arm64virt_uart_irq
+		}
+	}
+};
+
+static pio_window_t arm64virt_pio_window = {
+	.mem = {
+		.base = 0,
+		.size = -1
+	}
+};
+
+static arm64virt_fun_t arm64virt_ic_fun_proto = {
+	.hw_resources = {
+		sizeof(arm64virt_ic_res) / sizeof(arm64virt_ic_res[0]),
+		arm64virt_ic_res
+	},
+};
+
+static arm64virt_fun_t arm64virt_uart_fun_proto = {
+	.hw_resources = {
+		sizeof(arm64virt_uart_res) / sizeof(arm64virt_uart_res[0]),
+		arm64virt_uart_res
+	},
+};
+
+/** Obtain function soft-state from DDF function node. */
+static arm64virt_fun_t *arm64virt_fun(ddf_fun_t *fnode)
+{
+	return ddf_fun_data_get(fnode);
+}
+
+static hw_resource_list_t *arm64virt_get_resources(ddf_fun_t *fnode)
+{
+	arm64virt_fun_t *fun = arm64virt_fun(fnode);
+
+	assert(fun != NULL);
+	return &fun->hw_resources;
+}
+
+static errno_t arm64virt_enable_interrupt(ddf_fun_t *fun, int irq)
+{
+	/* TODO */
+	return false;
+}
+
+static pio_window_t *arm64virt_get_pio_window(ddf_fun_t *fnode)
+{
+	return &arm64virt_pio_window;
+}
+
+static hw_res_ops_t arm64virt_hw_res_ops = {
+	.get_resource_list = &arm64virt_get_resources,
+	.enable_interrupt = &arm64virt_enable_interrupt,
+};
+
+static pio_window_ops_t arm64virt_pio_window_ops = {
+	.get_pio_window = &arm64virt_get_pio_window
+};
+
+static ddf_dev_ops_t arm64virt_fun_ops = {
+	.interfaces = {
+		[HW_RES_DEV_IFACE] = &arm64virt_hw_res_ops,
+		[PIO_WINDOW_DEV_IFACE] = &arm64virt_pio_window_ops
+	}
+};
+
+static errno_t arm64virt_add_fun(ddf_dev_t *dev, const char *name,
+    const char *str_match_id, arm64virt_fun_t *fun_proto)
+{
+	ddf_msg(LVL_NOTE, "Adding function '%s'.", name);
+
+	ddf_fun_t *fnode = NULL;
+	errno_t rc;
+
+	/* Create new device. */
+	fnode = ddf_fun_create(dev, fun_inner, name);
+	if (fnode == NULL) {
+		ddf_msg(LVL_ERROR, "Error creating function '%s'.", name);
+		rc = ENOMEM;
+		goto error;
+	}
+
+	arm64virt_fun_t *fun = ddf_fun_data_alloc(fnode,
+	    sizeof(arm64virt_fun_t));
+	*fun = *fun_proto;
+
+	/* Add match ID. */
+	rc = ddf_fun_add_match_id(fnode, str_match_id, 100);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error adding match ID to function '%s'.",
+		    name);
+		goto error;
+	}
+
+	/* Set provided operations to the device. */
+	ddf_fun_set_ops(fnode, &arm64virt_fun_ops);
+
+	/* Register function. */
+	rc = ddf_fun_bind(fnode);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed binding function '%s'.", name);
+		goto error;
+	}
+
+	return EOK;
+
+error:
+	if (fnode != NULL)
+		ddf_fun_destroy(fnode);
+
+	return rc;
+}
+
+static errno_t arm64virt_add_functions(ddf_dev_t *dev)
+{
+	errno_t rc;
+
+	rc = arm64virt_add_fun(dev, "intctl", "arm/gicv2",
+	    &arm64virt_ic_fun_proto);
+	if (rc != EOK)
+		return rc;
+
+	rc = arm64virt_add_fun(dev, "uart", "arm/pl011",
+	    &arm64virt_uart_fun_proto);
+	if (rc != EOK)
+		return rc;
+
+	return EOK;
+}
+
+/** Add device. */
+static errno_t arm64virt_dev_add(ddf_dev_t *dev)
+{
+	ddf_msg(LVL_NOTE, "arm64virt_dev_add(), device=%s.",
+	    ddf_dev_get_name(dev));
+
+	/* Register functions. */
+	if (arm64virt_add_functions(dev))
+		ddf_msg(LVL_ERROR, "Failed to add functions for ARM64 QEMU "
+		    "virt platform.");
+
+	return EOK;
+}
+
+int main(int argc, char *argv[])
+{
+	errno_t rc;
+
+	printf(NAME ": HelenOS ARM64 QEMU virt platform driver\n");
+
+	rc = ddf_log_init(NAME);
+	if (rc != EOK) {
+		printf(NAME ": Failed connecting logging service.");
+		return 1;
+	}
+
+	return ddf_driver_main(&arm64virt_driver);
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/platform/arm64virt/arm64virt.ma
===================================================================
--- uspace/drv/platform/arm64virt/arm64virt.ma	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/platform/arm64virt/arm64virt.ma	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+10 platform/arm64virt
Index: uspace/drv/test/test1/test1.c
===================================================================
--- uspace/drv/test/test1/test1.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/test/test1/test1.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -176,5 +176,12 @@
 	}
 
-	ddf_fun_add_to_category(fun_a, "virtual");
+	rc = ddf_fun_add_to_category(fun_a, "virtual");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed adding function 'a' to category "
+		    "'virtual'.");
+		ddf_fun_unbind(fun_a);
+		ddf_fun_destroy(fun_a);
+		goto error;
+	}
 
 	if (str_cmp(dev_name, "test1") == 0) {
Index: uspace/drv/test/test2/test2.c
===================================================================
--- uspace/drv/test/test2/test2.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/test/test2/test2.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,7 +31,7 @@
 
 #include <assert.h>
-#include <async.h>
 #include <stdio.h>
 #include <errno.h>
+#include <fibril.h>
 #include <str.h>
 #include <str_error.h>
@@ -140,9 +140,18 @@
 	rc = ddf_fun_bind(fun_a);
 	if (rc != EOK) {
+		ddf_fun_destroy(fun_a);
 		ddf_msg(LVL_ERROR, "Failed binding function 'a'.");
 		return rc;
 	}
 
-	ddf_fun_add_to_category(fun_a, "virtual");
+	rc = ddf_fun_add_to_category(fun_a, "virtual");
+	if (rc != EOK) {
+		ddf_fun_unbind(fun_a);
+		ddf_fun_destroy(fun_a);
+		ddf_msg(LVL_ERROR, "Failed adding function 'a' to category "
+		    "'virtual'.");
+		return rc;
+	}
+
 	test2->fun_a = fun_a;
 
Index: uspace/drv/test/test3/test3.c
===================================================================
--- uspace/drv/test/test3/test3.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/test/test3/test3.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -70,4 +70,5 @@
 	errno_t rc;
 	char *fun_name = NULL;
+	bool bound = false;
 
 	if (asprintf(&fun_name, "%s%zu", base_name, index) < 0) {
@@ -91,5 +92,12 @@
 	}
 
-	ddf_fun_add_to_category(fun, class_name);
+	bound = true;
+
+	rc = ddf_fun_add_to_category(fun, class_name);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed addning function %s to category %s: "
+		    "%s", fun_name, class_name, str_error(rc));
+		goto leave;
+	}
 
 	ddf_msg(LVL_NOTE, "Registered exposed function `%s'.", fun_name);
@@ -98,4 +106,6 @@
 	free(fun_name);
 
+	if (bound)
+		ddf_fun_unbind(fun);
 	if ((rc != EOK) && (fun != NULL)) {
 		ddf_fun_destroy(fun);
Index: uspace/drv/time/cmos-rtc/cmos-rtc.c
===================================================================
--- uspace/drv/time/cmos-rtc/cmos-rtc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/time/cmos-rtc/cmos-rtc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -588,4 +588,5 @@
 	errno_t rc;
 	bool need_cleanup = false;
+	bool bound = false;
 
 	ddf_msg(LVL_DEBUG, "rtc_dev_add %s (handle = %d)",
@@ -624,7 +625,12 @@
 	}
 
+	bound = true;
 	rtc->fun = fun;
 
-	ddf_fun_add_to_category(fun, "clock");
+	rc = ddf_fun_add_to_category(fun, "clock");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed adding service to clock category.");
+		goto error;
+	}
 
 	ddf_msg(LVL_NOTE, "Device %s successfully initialized",
@@ -634,4 +640,6 @@
 
 error:
+	if (bound)
+		ddf_fun_unbind(fun);
 	if (fun)
 		ddf_fun_destroy(fun);
@@ -754,6 +762,8 @@
 
 	rc = ddf_fun_online(fun);
-	if (rc == EOK)
-		ddf_fun_add_to_category(fun, "clock");
+	if (rc == EOK) {
+		// XXX This should be probably handled by the framework
+		rc = ddf_fun_add_to_category(fun, "clock");
+	}
 
 	return rc;
Index: uspace/lib/block/block.c
===================================================================
--- uspace/lib/block/block.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/block/block.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -241,7 +241,7 @@
 }
 
-static size_t cache_key_hash(void *key)
-{
-	aoff64_t *lba = (aoff64_t *)key;
+static size_t cache_key_hash(const void *key)
+{
+	const aoff64_t *lba = key;
 	return *lba;
 }
@@ -253,7 +253,7 @@
 }
 
-static bool cache_key_equal(void *key, const ht_link_t *item)
-{
-	aoff64_t *lba = (aoff64_t *)key;
+static bool cache_key_equal(const void *key, const ht_link_t *item)
+{
+	const aoff64_t *lba = key;
 	block_t *b = hash_table_get_inst(item, block_t, hash_link);
 	return b->lba == *lba;
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,5 +34,5 @@
 
 EXTRA_OUTPUT = $(START_FILES)
-EXTRA_CFLAGS += -fno-builtin
+EXTRA_CFLAGS += -fno-builtin -D_LIBC_SOURCE
 LIBRARY = libc
 SOVERSION = 0.0
@@ -53,4 +53,5 @@
 	generic/context.c \
 	generic/corecfg.c \
+	generic/ctype.c \
 	generic/devman.c \
 	generic/device/hw_res.c \
@@ -165,4 +166,5 @@
 	generic/assert.c \
 	generic/bsearch.c \
+	generic/pci.c \
 	generic/pio_trace.c \
 	generic/qsort.c \
@@ -188,18 +190,28 @@
 TEST_SOURCES = \
 	test/adt/circ_buf.c \
+	test/adt/odict.c \
+	test/cap.c \
+	test/casting.c \
+	test/double_to_str.c \
 	test/fibril/timer.c \
+	test/getopt.c \
+	test/gsort.c \
+	test/ieee_double.c \
+	test/imath.c \
+	test/inttypes.c \
+	test/io/table.c \
 	test/main.c \
 	test/mem.c \
-	test/inttypes.c \
-	test/io/table.c \
-	test/stdio/scanf.c \
-	test/odict.c \
+	test/perf.c \
 	test/perm.c \
 	test/qsort.c \
 	test/sprintf.c \
+	test/stdio/scanf.c \
 	test/stdio.c \
 	test/stdlib.c \
 	test/str.c \
-	test/string.c
+	test/string.c \
+	test/strtol.c \
+	test/uuid.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/c/arch/abs32le/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/config.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/abs32le/include/libarch/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_abs32le_CONFIG_H_
-#define LIBC_abs32le_CONFIG_H_
+#ifndef _LIBC_abs32le_CONFIG_H_
+#define _LIBC_abs32le_CONFIG_H_
 
 #define PAGE_WIDTH  12
Index: uspace/lib/c/arch/abs32le/include/libarch/ddi.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/ddi.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/abs32le/include/libarch/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,6 +30,6 @@
  */
 
-#ifndef LIBC_abs32le_DDI_H_
-#define LIBC_abs32le_DDI_H_
+#ifndef _LIBC_abs32le_DDI_H_
+#define _LIBC_abs32le_DDI_H_
 
 #include <ddi.h>
Index: uspace/lib/c/arch/abs32le/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/elf_linux.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/abs32le/include/libarch/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_abs32le_ELF_LINUX_H_
-#define LIBC_abs32le_ELF_LINUX_H_
+#ifndef _LIBC_abs32le_ELF_LINUX_H_
+#define _LIBC_abs32le_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/abs32le/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/faddr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/abs32le/include/libarch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_abs32le_FADDR_H_
-#define LIBC_abs32le_FADDR_H_
+#ifndef _LIBC_abs32le_FADDR_H_
+#define _LIBC_abs32le_FADDR_H_
 
 #include <types/common.h>
Index: uspace/lib/c/arch/abs32le/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/fibril.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/abs32le/include/libarch/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_abs32le_FIBRIL_H_
-#define LIBC_abs32le_FIBRIL_H_
+#ifndef _LIBC_abs32le_FIBRIL_H_
+#define _LIBC_abs32le_FIBRIL_H_
 
 #include <stdint.h>
Index: uspace/lib/c/arch/abs32le/include/libarch/fibril_context.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/fibril_context.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/abs32le/include/libarch/fibril_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,6 +27,6 @@
  */
 
-#ifndef LIBC_abs32le_FIBRIL_CONTEXT_H_
-#define LIBC_abs32le_FIBRIL_CONTEXT_H_
+#ifndef _LIBC_abs32le_FIBRIL_CONTEXT_H_
+#define _LIBC_abs32le_FIBRIL_CONTEXT_H_
 
 #include <stdint.h>
@@ -36,10 +36,10 @@
  * need to be preserved across function calls.
  */
-typedef struct context {
+typedef struct __context {
 	uintptr_t sp;
 	uintptr_t fp;
 	uintptr_t pc;
 	uintptr_t tls;
-} context_t;
+} __context_t;
 
 #endif
Index: uspace/lib/c/arch/abs32le/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/syscall.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/abs32le/include/libarch/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_abs32le_SYSCALL_H_
-#define LIBC_abs32le_SYSCALL_H_
+#ifndef _LIBC_abs32le_SYSCALL_H_
+#define _LIBC_abs32le_SYSCALL_H_
 
 #include <abi/syscall.h>
Index: uspace/lib/c/arch/abs32le/include/libarch/thread.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/thread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/abs32le/include/libarch/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_abs32le_THREAD_H_
-#define LIBC_abs32le_THREAD_H_
+#ifndef _LIBC_abs32le_THREAD_H_
+#define _LIBC_abs32le_THREAD_H_
 
 #endif
Index: uspace/lib/c/arch/abs32le/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/tls.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/abs32le/include/libarch/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_abs32le_TLS_H_
-#define LIBC_abs32le_TLS_H_
+#ifndef _LIBC_abs32le_TLS_H_
+#define _LIBC_abs32le_TLS_H_
 
 #define CONFIG_TLS_VARIANT_2
Index: uspace/lib/c/arch/abs32le/src/fibril.c
===================================================================
--- uspace/lib/c/arch/abs32le/src/fibril.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/abs32le/src/fibril.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,10 +33,10 @@
 #include <stdbool.h>
 
-int __setjmp(context_t *ctx)
+int __context_save(__context_t *ctx)
 {
 	return 0;
 }
 
-void __longjmp(context_t *ctx, int val)
+void __context_restore(__context_t *ctx, int val)
 {
 	while (true)
Index: uspace/lib/c/arch/amd64/Makefile.common
===================================================================
--- uspace/lib/c/arch/amd64/Makefile.common	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/Makefile.common	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -28,5 +28,5 @@
 
 # TODO: We need to implement DWARF unwinding and get rid of this flag.
-COMMON_CFLAGS += -fno-omit-frame-pointer
+COMMON_CFLAGS += -fno-omit-frame-pointer -Wl,-z,max-page-size=0x1000
 
 # XXX: This architecture requires unoptimized TLS pointer access,
Index: uspace/lib/c/arch/amd64/Makefile.inc
===================================================================
--- uspace/lib/c/arch/amd64/Makefile.inc	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,5 +34,7 @@
 	arch/$(UARCH)/src/tls.c \
 	arch/$(UARCH)/src/stacktrace.c \
-	arch/$(UARCH)/src/stacktrace_asm.S
+	arch/$(UARCH)/src/stacktrace_asm.S \
+	arch/$(UARCH)/src/rtld/dynamic.c \
+	arch/$(UARCH)/src/rtld/reloc.c
 
 ARCH_AUTOCHECK_HEADERS = \
Index: uspace/lib/c/arch/amd64/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/config.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/include/libarch/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_amd64_CONFIG_H_
-#define LIBC_amd64_CONFIG_H_
+#ifndef _LIBC_amd64_CONFIG_H_
+#define _LIBC_amd64_CONFIG_H_
 
 #define PAGE_WIDTH	12
Index: uspace/lib/c/arch/amd64/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/elf_linux.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/include/libarch/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_amd64_ELF_LINUX_H_
-#define LIBC_amd64_ELF_LINUX_H_
+#ifndef _LIBC_amd64_ELF_LINUX_H_
+#define _LIBC_amd64_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/amd64/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/faddr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/include/libarch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_amd64_FADDR_H_
-#define LIBC_amd64_FADDR_H_
+#ifndef _LIBC_amd64_FADDR_H_
+#define _LIBC_amd64_FADDR_H_
 
 #include <types/common.h>
Index: uspace/lib/c/arch/amd64/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/fibril.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/include/libarch/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_amd64_FIBRIL_H_
-#define LIBC_amd64_FIBRIL_H_
+#ifndef _LIBC_amd64_FIBRIL_H_
+#define _LIBC_amd64_FIBRIL_H_
 
 #include <libarch/fibril_context.h>
Index: uspace/lib/c/arch/amd64/include/libarch/fibril_context.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/fibril_context.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/include/libarch/fibril_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,17 +27,17 @@
  */
 
-#ifndef LIBC_ARCH_FIBRIL_CONTEXT_H_
-#define LIBC_ARCH_FIBRIL_CONTEXT_H_
+#ifndef _LIBC_ARCH_FIBRIL_CONTEXT_H_
+#define _LIBC_ARCH_FIBRIL_CONTEXT_H_
 
-#define CONTEXT_OFFSET_SP   0x00
-#define CONTEXT_OFFSET_PC   0x08
-#define CONTEXT_OFFSET_RBX  0x10
-#define CONTEXT_OFFSET_RBP  0x18
-#define CONTEXT_OFFSET_R12  0x20
-#define CONTEXT_OFFSET_R13  0x28
-#define CONTEXT_OFFSET_R14  0x30
-#define CONTEXT_OFFSET_R15  0x38
-#define CONTEXT_OFFSET_TLS  0x40
-#define CONTEXT_SIZE        0x48
+#define __CONTEXT_OFFSET_SP   0x00
+#define __CONTEXT_OFFSET_PC   0x08
+#define __CONTEXT_OFFSET_RBX  0x10
+#define __CONTEXT_OFFSET_RBP  0x18
+#define __CONTEXT_OFFSET_R12  0x20
+#define __CONTEXT_OFFSET_R13  0x28
+#define __CONTEXT_OFFSET_R14  0x30
+#define __CONTEXT_OFFSET_R15  0x38
+#define __CONTEXT_OFFSET_TLS  0x40
+#define __CONTEXT_SIZE        0x48
 
 #ifndef __ASSEMBLER__
@@ -45,5 +45,5 @@
 #include <stdint.h>
 
-typedef struct context {
+typedef struct __context {
 	/*
 	 * We include only registers that must be preserved
@@ -59,5 +59,5 @@
 	uint64_t r15;
 	uint64_t tls;
-} context_t;
+} __context_t;
 
 #endif
Index: uspace/lib/c/arch/amd64/include/libarch/rtld/dynamic.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/rtld/dynamic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/amd64/include/libarch/rtld/dynamic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 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 generic
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_amd64_RTLD_DYNAMIC_H_
+#define _LIBC_amd64_RTLD_DYNAMIC_H_
+
+typedef struct {
+	/* Empty. */
+} dyn_info_arch_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/amd64/include/libarch/rtld/elf_dyn.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/rtld/elf_dyn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/amd64/include/libarch/rtld/elf_dyn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016 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 generic
+ * @{
+ */
+/** @file amd64 dynamic relocation types
+ */
+
+#ifndef _LIBC_amd64_RTLD_ELF_DYN_H_
+#define _LIBC_amd64_RTLD_ELF_DYN_H_
+
+#define R_X86_64_64		1
+#define R_X86_64_PC32		2
+#define R_X86_64_COPY		5
+#define R_X86_64_GLOB_DAT	6
+#define R_X86_64_JUMP_SLOT	7
+#define R_X86_64_RELATIVE	8
+
+#define R_X86_64_DTPMOD64	16
+#define R_X86_64_DTPOFF64	17
+#define R_X86_64_TPOFF64	18
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/amd64/include/libarch/rtld/module.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/amd64/include/libarch/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_amd64_RTLD_MODULE_H_
+#define _LIBC_amd64_RTLD_MODULE_H_
+
+#include <elf/elf_mod.h>
+
+/** ELF module load flags */
+#define RTLD_MODULE_LDF 0
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/amd64/include/libarch/stackarg.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/stackarg.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/include/libarch/stackarg.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_STACKARG_H_
-#define LIBC_STACKARG_H_
+#ifndef _LIBC_STACKARG_H_
+#define _LIBC_STACKARG_H_
 
 #endif
Index: uspace/lib/c/arch/amd64/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/syscall.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/include/libarch/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_amd64_SYSCALL_H_
-#define LIBC_amd64_SYSCALL_H_
+#ifndef _LIBC_amd64_SYSCALL_H_
+#define _LIBC_amd64_SYSCALL_H_
 
 #define LIBARCH_SYSCALL_GENERIC
Index: uspace/lib/c/arch/amd64/include/libarch/thread.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/thread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/include/libarch/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_amd64_THREAD_H_
-#define LIBC_amd64_THREAD_H_
+#ifndef _LIBC_amd64_THREAD_H_
+#define _LIBC_amd64_THREAD_H_
 
 #endif
Index: uspace/lib/c/arch/amd64/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/tls.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/include/libarch/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_amd64_TLS_H_
-#define LIBC_amd64_TLS_H_
+#ifndef _LIBC_amd64_TLS_H_
+#define _LIBC_amd64_TLS_H_
 
 #define CONFIG_TLS_VARIANT_2
@@ -45,4 +45,6 @@
 	void *self;
 	void *fibril_data;
+	void **dtv;
+	void *pad;
 } tcb_t;
 
Index: uspace/lib/c/arch/amd64/src/entry.S
===================================================================
--- uspace/lib/c/arch/amd64/src/entry.S	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/src/entry.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -47,3 +47,3 @@
 	# %rdi was deliberately chosen as the first argument is also in %rdi
 	# Pass PCB pointer to __c_start (no operation)
-	call __c_start
+	call FUNCTION_REF(__c_start)
Index: uspace/lib/c/arch/amd64/src/fibril.S
===================================================================
--- uspace/lib/c/arch/amd64/src/fibril.S	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/src/fibril.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,24 +37,24 @@
 # pointed by the 1st argument. Returns 0 in RAX.
 #
-FUNCTION_BEGIN(__setjmp)
+FUNCTION_BEGIN(__context_save)
 	movq (%rsp), %rdx     # the caller's return %eip
 
 	# in %rdi is passed 1st argument
-	movq %rdx, CONTEXT_OFFSET_PC(%rdi)
-	movq %rsp, CONTEXT_OFFSET_SP(%rdi)
+	movq %rdx, __CONTEXT_OFFSET_PC(%rdi)
+	movq %rsp, __CONTEXT_OFFSET_SP(%rdi)
 
-	movq %rbx, CONTEXT_OFFSET_RBX(%rdi)
-	movq %rbp, CONTEXT_OFFSET_RBP(%rdi)
-	movq %r12, CONTEXT_OFFSET_R12(%rdi)
-	movq %r13, CONTEXT_OFFSET_R13(%rdi)
-	movq %r14, CONTEXT_OFFSET_R14(%rdi)
-	movq %r15, CONTEXT_OFFSET_R15(%rdi)
+	movq %rbx, __CONTEXT_OFFSET_RBX(%rdi)
+	movq %rbp, __CONTEXT_OFFSET_RBP(%rdi)
+	movq %r12, __CONTEXT_OFFSET_R12(%rdi)
+	movq %r13, __CONTEXT_OFFSET_R13(%rdi)
+	movq %r14, __CONTEXT_OFFSET_R14(%rdi)
+	movq %r15, __CONTEXT_OFFSET_R15(%rdi)
 
 	movq %fs:0, %rax
-	movq %rax, CONTEXT_OFFSET_TLS(%rdi)
+	movq %rax, __CONTEXT_OFFSET_TLS(%rdi)
 
-	xorq %rax, %rax                      # __setjmp returns 0
+	xorq %rax, %rax                      # __context_save returns 0
 	ret
-FUNCTION_END(__setjmp)
+FUNCTION_END(__context_save)
 
 ## Restore current CPU context
@@ -63,23 +63,23 @@
 # pointed by the 1st argument. Returns second argument in RAX.
 #
-FUNCTION_BEGIN(__longjmp)
-	movq CONTEXT_OFFSET_R15(%rdi), %r15
-	movq CONTEXT_OFFSET_R14(%rdi), %r14
-	movq CONTEXT_OFFSET_R13(%rdi), %r13
-	movq CONTEXT_OFFSET_R12(%rdi), %r12
-	movq CONTEXT_OFFSET_RBP(%rdi), %rbp
-	movq CONTEXT_OFFSET_RBX(%rdi), %rbx
+FUNCTION_BEGIN(__context_restore)
+	movq __CONTEXT_OFFSET_R15(%rdi), %r15
+	movq __CONTEXT_OFFSET_R14(%rdi), %r14
+	movq __CONTEXT_OFFSET_R13(%rdi), %r13
+	movq __CONTEXT_OFFSET_R12(%rdi), %r12
+	movq __CONTEXT_OFFSET_RBP(%rdi), %rbp
+	movq __CONTEXT_OFFSET_RBX(%rdi), %rbx
 
-	movq CONTEXT_OFFSET_SP(%rdi), %rsp   # ctx->sp -> %rsp
+	movq __CONTEXT_OFFSET_SP(%rdi), %rsp   # ctx->sp -> %rsp
 
-	movq CONTEXT_OFFSET_PC(%rdi), %rdx
+	movq __CONTEXT_OFFSET_PC(%rdi), %rdx
 
 	movq %rdx,(%rsp)
 
-	movq CONTEXT_OFFSET_TLS(%rdi), %rdi
+	movq __CONTEXT_OFFSET_TLS(%rdi), %rdi
 	movq %rdi, %fs:0
 
-	movq %rsi, %rax                      # __longjmp returns second argument
+	movq %rsi, %rax                      # __context_restore returns second argument
 	ret
-FUNCTION_END(__longjmp)
+FUNCTION_END(__context_restore)
 
Index: uspace/lib/c/arch/amd64/src/rtld/dynamic.c
===================================================================
--- uspace/lib/c/arch/amd64/src/rtld/dynamic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/amd64/src/rtld/dynamic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016 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 libcamd64
+ * @brief
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <rtld/elf_dyn.h>
+#include <rtld/dynamic.h>
+
+void dyn_parse_arch(elf_dyn_t *dp, size_t bias, dyn_info_t *info)
+{
+	(void) dp;
+	(void) bias;
+	(void) info;
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/amd64/src/rtld/reloc.c
===================================================================
--- uspace/lib/c/arch/amd64/src/rtld/reloc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/amd64/src/rtld/reloc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2016 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 libcamd64
+ * @brief
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <mem.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <libarch/rtld/elf_dyn.h>
+#include <rtld/symbol.h>
+#include <rtld/rtld.h>
+#include <rtld/rtld_debug.h>
+#include <rtld/rtld_arch.h>
+
+void module_process_pre_arch(module_t *m)
+{
+	/* Unused */
+}
+
+/**
+ * Process (fixup) all relocations in a relocation table with implicit addends.
+ */
+void rel_table_process(module_t *m, elf_rel_t *rt, size_t rt_size)
+{
+
+	DPRINTF("rel table address: 0x%zx, size: %zd\n", (uintptr_t)rt, rt_size);
+	/* Unused */
+	(void)m;
+	(void)rt;
+	(void)rt_size;
+}
+
+/**
+ * Process (fixup) all relocations in a relocation table with explicit addends.
+ */
+void rela_table_process(module_t *m, elf_rela_t *rt, size_t rt_size)
+{
+	unsigned i;
+
+	size_t rt_entries;
+	size_t r_offset;
+	size_t r_addend;
+	elf_xword r_info;
+	unsigned rel_type;
+	elf_word sym_idx;
+	uintptr_t sym_addr;
+
+	elf_symbol_t *sym_table;
+	elf_symbol_t *sym;
+	uintptr_t *r_ptr;
+	uint32_t *r_ptr32;
+	uintptr_t sym_size;
+	char *str_tab;
+
+	elf_symbol_t *sym_def;
+	module_t *dest;
+
+	DPRINTF("parse relocation table\n");
+
+	sym_table = m->dyn.sym_tab;
+	rt_entries = rt_size / sizeof(elf_rela_t);
+	str_tab = m->dyn.str_tab;
+
+	DPRINTF("rel table address: 0x%zx, entries: %zd\n", (uintptr_t)rt, rt_entries);
+
+	for (i = 0; i < rt_entries; ++i) {
+#if 0
+		DPRINTF("symbol %d: ", i);
+#endif
+		r_offset = rt[i].r_offset;
+		r_info = rt[i].r_info;
+		r_addend = rt[i].r_addend;
+
+		sym_idx = ELF64_R_SYM(r_info);
+		sym = &sym_table[sym_idx];
+
+#if 0
+		DPRINTF("name '%s', value 0x%x, size 0x%x\n",
+		    str_tab + sym->st_name,
+		    sym->st_value,
+		    sym->st_size);
+#endif
+		rel_type = ELF64_R_TYPE(r_info);
+		r_ptr = (uintptr_t *)(r_offset + m->bias);
+		r_ptr32 = (uint32_t *)r_ptr;
+
+		if (sym->st_name != 0) {
+			DPRINTF("rel_type: %x, rel_offset: 0x%zx\n", rel_type, r_offset);
+			sym_def = symbol_def_find(str_tab + sym->st_name,
+			    m, ssf_none, &dest);
+			DPRINTF("dest name: '%s'\n", dest->dyn.soname);
+			DPRINTF("dest bias: 0x%zx\n", dest->bias);
+			if (sym_def) {
+				sym_addr = (uintptr_t)
+				    symbol_get_addr(sym_def, dest, NULL);
+				DPRINTF("symbol definition found, value=0x%zx addr=0x%zx\n", sym_def->st_value, sym_addr);
+			} else {
+				printf("Definition of '%s' not found.\n",
+				    str_tab + sym->st_name);
+				continue;
+			}
+		} else {
+			sym_addr = 0;
+			sym_def = NULL;
+
+			/*
+			 * DTPMOD with null st_name should return the index
+			 * of the current module.
+			 */
+			dest = m;
+		}
+
+		switch (rel_type) {
+		case R_X86_64_64:
+			DPRINTF("fixup R_X86_64_64 (S+A)\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, sym_addr + r_addend);
+			*r_ptr = sym_addr + r_addend;
+			DPRINTF("OK\n");
+			break;
+
+		case R_X86_64_PC32:
+			DPRINTF("fixup R_X86_64_PC32 (S+A-P)\n");
+			DPRINTF("(32)*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, sym_addr + r_addend - (uintptr_t) r_ptr);
+			*r_ptr32 = sym_addr + r_addend - (uintptr_t) r_ptr;
+			DPRINTF("OK\n");
+			break;
+
+		case R_X86_64_COPY:
+			/*
+			 * Copy symbol data from shared object to specified
+			 * location. Need to find the 'source', i.e. the
+			 * other instance of the object than the one in the
+			 * executable program.
+			 */
+			DPRINTF("fixup R_X86_64_COPY (s)\n");
+
+			sym_def = symbol_def_find(str_tab + sym->st_name,
+			    m, ssf_noexec, &dest);
+
+			if (sym_def) {
+				sym_addr = (uintptr_t)
+				    symbol_get_addr(sym_def, dest, NULL);
+			} else {
+				printf("Source definition of '%s' not found.\n",
+				    str_tab + sym->st_name);
+				continue;
+			}
+
+			sym_size = sym->st_size;
+			if (sym_size != sym_def->st_size) {
+				printf("Warning: Mismatched symbol sizes.\n");
+				/* Take the lower value. */
+				if (sym_size > sym_def->st_size)
+					sym_size = sym_def->st_size;
+			}
+
+			memcpy(r_ptr, (const void *)sym_addr, sym_size);
+			DPRINTF("OK\n");
+			break;
+
+		case R_X86_64_GLOB_DAT:
+		case R_X86_64_JUMP_SLOT:
+			DPRINTF("fixup R_X86_64_GLOB_DAT/JUMP_SLOT (S)\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, sym_addr);
+			*r_ptr = sym_addr;
+			DPRINTF("OK\n");
+			break;
+
+		case R_X86_64_RELATIVE:
+			DPRINTF("fixup R_X86_64_RELATIVE (B+A)\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, m->bias + r_addend);
+			*r_ptr = m->bias + r_addend;
+			DPRINTF("OK\n");
+			break;
+
+		case R_X86_64_DTPMOD64:
+			DPRINTF("fixup R_X86_64_DTPMOD64\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, (size_t)dest->id);
+			*r_ptr = dest->id;
+			DPRINTF("OK\n");
+			break;
+
+		case R_X86_64_DTPOFF64:
+			DPRINTF("fixup R_X86_64_DTPOFF64\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, sym_def->st_value);
+			*r_ptr = sym_def->st_value;
+			DPRINTF("OK\n");
+			break;
+
+		case R_X86_64_TPOFF64:
+			DPRINTF("fixup R_X86_64_TPOFF64\n");
+			*r_ptr = sym_def->st_value + dest->tpoff;
+			break;
+
+		default:
+			printf("Error: Unknown relocation type %d\n",
+			    rel_type);
+			exit(1);
+		}
+
+	}
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/amd64/src/thread_entry.S
===================================================================
--- uspace/lib/c/arch/amd64/src/thread_entry.S	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/src/thread_entry.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -46,4 +46,4 @@
 	#
 	movq %rax, %rdi
-	call __thread_main
+	call FUNCTION_REF(__thread_main)
 SYMBOL_END(__thread_entry)
Index: uspace/lib/c/arch/amd64/src/tls.c
===================================================================
--- uspace/lib/c/arch/amd64/src/tls.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/src/tls.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,4 +38,8 @@
 #include <stddef.h>
 
+#ifdef CONFIG_RTLD
+#include <rtld/rtld.h>
+#endif
+
 tcb_t *tls_alloc_arch(size_t size, size_t align)
 {
@@ -48,4 +52,32 @@
 }
 
+/*
+ * Rtld TLS support
+ */
+
+typedef struct {
+	unsigned long int ti_module;
+	unsigned long int ti_offset;
+} tls_index;
+
+void __attribute__((__regparm__(1)))
+    *__tls_get_addr(tls_index *ti);
+
+void __attribute__((__regparm__(1)))
+    *__tls_get_addr(tls_index *ti)
+{
+	uint8_t *tls;
+
+#ifdef CONFIG_RTLD
+	if (runtime_env != NULL) {
+		return rtld_tls_get_addr(runtime_env, __tcb_get(),
+		    ti->ti_module, ti->ti_offset);
+	}
+#endif
+	/* Get address of static TLS block */
+	tls = tls_get();
+	return tls + ti->ti_offset;
+}
+
 /** @}
  */
Index: uspace/lib/c/arch/arm32/Makefile.common
===================================================================
--- uspace/lib/c/arch/arm32/Makefile.common	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/Makefile.common	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -29,5 +29,5 @@
 
 COMMON_CFLAGS += -ffixed-r9 -mtp=soft -fno-omit-frame-pointer -mapcs-frame \
-	-mcpu=$(subst _,-,$(PROCESSOR))
+	-mcpu=$(subst _,-,$(PROCESSOR)) -Wl,-z,max-page-size=0x1000
 
 LDFLAGS += -Wl,--gc-sections
Index: uspace/lib/c/arch/arm32/Makefile.inc
===================================================================
--- uspace/lib/c/arch/arm32/Makefile.inc	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,3 +37,5 @@
 	arch/$(UARCH)/src/eabi.S \
 	arch/$(UARCH)/src/stacktrace.c \
-	arch/$(UARCH)/src/stacktrace_asm.S
+	arch/$(UARCH)/src/stacktrace_asm.S \
+	arch/$(UARCH)/src/rtld/dynamic.c \
+	arch/$(UARCH)/src/rtld/reloc.c
Index: uspace/lib/c/arch/arm32/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/config.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/include/libarch/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_arm32_CONFIG_H_
-#define LIBC_arm32_CONFIG_H_
+#ifndef _LIBC_arm32_CONFIG_H_
+#define _LIBC_arm32_CONFIG_H_
 
 #define PAGE_WIDTH	12
Index: uspace/lib/c/arch/arm32/include/libarch/ddi.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/ddi.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/include/libarch/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_arm32_DDI_H_
-#define LIBC_arm32_DDI_H_
+#ifndef _LIBC_arm32_DDI_H_
+#define _LIBC_arm32_DDI_H_
 
 #include <ddi.h>
Index: uspace/lib/c/arch/arm32/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/elf_linux.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/include/libarch/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_arm32_ELF_LINUX_H_
-#define LIBC_arm32_ELF_LINUX_H_
+#ifndef _LIBC_arm32_ELF_LINUX_H_
+#define _LIBC_arm32_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/arm32/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/faddr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/include/libarch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_arm32_FADDR_H_
-#define LIBC_arm32_FADDR_H_
+#ifndef _LIBC_arm32_FADDR_H_
+#define _LIBC_arm32_FADDR_H_
 
 #include <types/common.h>
Index: uspace/lib/c/arch/arm32/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/fibril.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/include/libarch/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_arm32_FIBRIL_H_
-#define LIBC_arm32_FIBRIL_H_
+#ifndef _LIBC_arm32_FIBRIL_H_
+#define _LIBC_arm32_FIBRIL_H_
 
 #include <types/common.h>
Index: uspace/lib/c/arch/arm32/include/libarch/fibril_context.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/fibril_context.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/include/libarch/fibril_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,6 +27,6 @@
  */
 
-#ifndef LIBC_ARCH_FIBRIL_CONTEXT_H_
-#define LIBC_ARCH_FIBRIL_CONTEXT_H_
+#ifndef _LIBC_ARCH_FIBRIL_CONTEXT_H_
+#define _LIBC_ARCH_FIBRIL_CONTEXT_H_
 
 #include <stdint.h>
@@ -41,5 +41,5 @@
 // XXX: This struct must match the assembly code in src/fibril.S
 
-typedef struct context {
+typedef struct __context {
 	uintptr_t sp;
 	uintptr_t pc;
@@ -54,5 +54,5 @@
 	/* r11 */
 	uint32_t fp;
-} context_t;
+} __context_t;
 
 #endif
Index: uspace/lib/c/arch/arm32/include/libarch/rtld/dynamic.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/rtld/dynamic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm32/include/libarch/rtld/dynamic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2019 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_arm32_RTLD_DYNAMIC_H_
+#define _LIBC_arm32_RTLD_DYNAMIC_H_
+
+typedef struct {
+	/* Empty. */
+} dyn_info_arch_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm32/include/libarch/rtld/elf_dyn.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/rtld/elf_dyn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm32/include/libarch/rtld/elf_dyn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2019 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_arm32_RTLD_ELF_DYN_H_
+#define _LIBC_arm32_RTLD_ELF_DYN_H_
+
+/*
+ * arm32 dynamic relocation types
+ */
+
+#define R_ARM_ABS32         2
+#define R_ARM_TLS_DTPMOD32 17
+#define R_ARM_TLS_DTPOFF32 18
+#define R_ARM_TLS_TPOFF32  19
+#define R_ARM_COPY         20
+#define R_ARM_GLOB_DAT     21
+#define R_ARM_JUMP_SLOT    22
+#define R_ARM_RELATIVE     23
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm32/include/libarch/rtld/module.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm32/include/libarch/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_arm32_RTLD_MODULE_H_
+#define _LIBC_arm32_RTLD_MODULE_H_
+
+#include <elf/elf_mod.h>
+
+/** ELF module load flags */
+#define RTLD_MODULE_LDF 0
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm32/include/libarch/stackarg.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/stackarg.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/include/libarch/stackarg.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_arm32_STACKARG_H_
-#define LIBC_arm32_STACKARG_H_
+#ifndef _LIBC_arm32_STACKARG_H_
+#define _LIBC_arm32_STACKARG_H_
 
 #endif
Index: uspace/lib/c/arch/arm32/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/syscall.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/include/libarch/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_arm32_SYSCALL_H_
-#define LIBC_arm32_SYSCALL_H_
+#ifndef _LIBC_arm32_SYSCALL_H_
+#define _LIBC_arm32_SYSCALL_H_
 
 #define LIBARCH_SYSCALL_GENERIC
Index: uspace/lib/c/arch/arm32/include/libarch/thread.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/thread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/include/libarch/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_arm32_THREAD_H_
-#define LIBC_arm32_THREAD_H_
+#ifndef _LIBC_arm32_THREAD_H_
+#define _LIBC_arm32_THREAD_H_
 
 #endif
Index: uspace/lib/c/arch/arm32/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/tls.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/include/libarch/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_arm32_TLS_H_
-#define LIBC_arm32_TLS_H_
+#ifndef _LIBC_arm32_TLS_H_
+#define _LIBC_arm32_TLS_H_
 
 #include <stdint.h>
@@ -49,4 +49,6 @@
  */
 typedef struct {
+	void **dtv;
+	void *pad;
 	/** Fibril data. */
 	void *fibril_data;
Index: uspace/lib/c/arch/arm32/src/atomic.c
===================================================================
--- uspace/lib/c/arch/arm32/src/atomic.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/src/atomic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,5 +35,5 @@
 #include <stdbool.h>
 
-extern volatile unsigned *ras_page;
+volatile unsigned *ras_page;
 
 bool __atomic_compare_exchange_4(volatile unsigned *mem, unsigned *expected, unsigned desired, bool weak, int success, int failure)
Index: uspace/lib/c/arch/arm32/src/entry.S
===================================================================
--- uspace/lib/c/arch/arm32/src/entry.S	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/src/entry.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -56,5 +56,2 @@
 
 .data
-
-SYMBOL(ras_page)
-	.long 0
Index: uspace/lib/c/arch/arm32/src/fibril.S
===================================================================
--- uspace/lib/c/arch/arm32/src/fibril.S	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/src/fibril.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,5 +31,5 @@
 .text
 
-FUNCTION_BEGIN(__setjmp)
+FUNCTION_BEGIN(__context_save)
 	stmia r0!, {sp, lr}
 	stmia r0!, {r4-r11}
@@ -38,7 +38,7 @@
 	mov r0, #0
 	mov pc, lr
-FUNCTION_END(__setjmp)
+FUNCTION_END(__context_save)
 
-FUNCTION_BEGIN(__longjmp)
+FUNCTION_BEGIN(__context_restore)
 	ldmia r0!, {sp, lr}
 	ldmia r0!, {r4-r11}
@@ -47,4 +47,4 @@
 	mov r0, r1
 	mov pc, lr
-FUNCTION_END(__longjmp)
+FUNCTION_END(__context_restore)
 
Index: uspace/lib/c/arch/arm32/src/rtld/dynamic.c
===================================================================
--- uspace/lib/c/arch/arm32/src/rtld/dynamic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm32/src/rtld/dynamic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019 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 libcarm32
+ * @brief
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <rtld/elf_dyn.h>
+#include <rtld/dynamic.h>
+
+void dyn_parse_arch(elf_dyn_t *dp, size_t bias, dyn_info_t *info)
+{
+	(void) dp;
+	(void) bias;
+	(void) info;
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm32/src/rtld/reloc.c
===================================================================
--- uspace/lib/c/arch/arm32/src/rtld/reloc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm32/src/rtld/reloc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2019 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 libcarm32
+ * @brief
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <bitops.h>
+#include <smc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <str.h>
+
+#include <libarch/rtld/elf_dyn.h>
+#include <rtld/symbol.h>
+#include <rtld/rtld.h>
+#include <rtld/rtld_debug.h>
+#include <rtld/rtld_arch.h>
+
+void module_process_pre_arch(module_t *m)
+{
+	/* Unused */
+}
+
+/**
+ * Process (fixup) all relocations in a relocation table.
+ */
+void rel_table_process(module_t *m, elf_rel_t *rt, size_t rt_size)
+{
+	unsigned i;
+
+	size_t rt_entries;
+	size_t r_offset;
+	elf_word r_info;
+	unsigned rel_type;
+	elf_word sym_idx;
+	uint32_t sym_addr;
+
+	elf_symbol_t *sym_table;
+	elf_symbol_t *sym;
+	uint32_t *r_ptr;
+	uint32_t sym_size;
+	char *str_tab;
+
+	elf_symbol_t *sym_def;
+	module_t *dest;
+
+	DPRINTF("parse relocation table\n");
+
+	sym_table = m->dyn.sym_tab;
+	rt_entries = rt_size / sizeof(elf_rel_t);
+	str_tab = m->dyn.str_tab;
+
+	DPRINTF("address: 0x%" PRIxPTR ", entries: %zd\n", (uintptr_t)rt, rt_entries);
+
+	for (i = 0; i < rt_entries; ++i) {
+#if 0
+		DPRINTF("symbol %d: ", i);
+#endif
+		r_offset = rt[i].r_offset;
+		r_info = rt[i].r_info;
+
+		sym_idx = ELF32_R_SYM(r_info);
+		sym = &sym_table[sym_idx];
+
+#if 0
+		DPRINTF("name '%s', value 0x%x, size 0x%x\n",
+		    str_tab + sym->st_name, sym->st_value, sym->st_size);
+#endif
+		rel_type = ELF32_R_TYPE(r_info);
+		r_ptr = (uint32_t *)(r_offset + m->bias);
+
+		if (sym->st_name != 0) {
+#if 0
+			DPRINTF("rel_type: %x, rel_offset: 0x%x\n", rel_type, r_offset);
+#endif
+			sym_def = symbol_def_find(str_tab + sym->st_name,
+			    m, ssf_none, &dest);
+			DPRINTF("dest name: '%s'\n", dest->dyn.soname);
+			DPRINTF("dest bias: 0x%x\n", dest->bias);
+			if (sym_def) {
+				sym_addr = (uint32_t)
+				    symbol_get_addr(sym_def, dest, NULL);
+#if 0
+				DPRINTF("symbol definition found, addr=0x%x\n", sym_addr);
+#endif
+			} else {
+				printf("Definition of '%s' not found.\n",
+				    str_tab + sym->st_name);
+				continue;
+			}
+		} else {
+			sym_addr = 0;
+			sym_def = NULL;
+			dest = m;
+		}
+
+		switch (rel_type) {
+		case R_ARM_ABS32:
+			DPRINTF("ignore R_ARM_ABS32\n");
+			/*
+			 * Not sure why we get these static relocations, but
+			 * attempting to process them will crash the
+			 * loader. If we ignore them, everything
+			 * seems to work.
+			 */
+			break;
+
+		case R_ARM_TLS_DTPMOD32:
+			DPRINTF("fixup R_ARM_TLS_DTPMOD32\n");
+			*r_ptr = dest->id;
+			break;
+
+		case R_ARM_TLS_DTPOFF32:
+			DPRINTF("fixup R_ARM_TLS_DTPOFF32\n");
+			*r_ptr = sym_def->st_value;
+			break;
+
+		case R_ARM_TLS_TPOFF32:
+			DPRINTF("fixup R_ARM_TLS_TPOFF\n");
+			if (sym_def != NULL)
+				*r_ptr = sym_def->st_value + dest->tpoff;
+			else
+				*r_ptr = m->tpoff;
+			break;
+
+		case R_ARM_COPY:
+			/*
+			 * Copy symbol data from shared object to specified
+			 * location. Need to find the 'source', i.e. the
+			 * other instance of the object than the one in the
+			 * executable program.
+			 */
+			DPRINTF("fixup R_ARM_COPY (s)\n");
+
+			sym_def = symbol_def_find(str_tab + sym->st_name,
+			    m, ssf_noexec, &dest);
+
+			if (sym_def) {
+				sym_addr = (uint32_t)
+				    symbol_get_addr(sym_def, dest, NULL);
+			} else {
+				printf("Source definition of '%s' not found.\n",
+				    str_tab + sym->st_name);
+				continue;
+			}
+
+			sym_size = sym->st_size;
+			if (sym_size != sym_def->st_size) {
+				printf("Warning: Mismatched symbol sizes.\n");
+				/* Take the lower value. */
+				if (sym_size > sym_def->st_size)
+					sym_size = sym_def->st_size;
+			}
+
+			memcpy(r_ptr, (const void *)sym_addr, sym_size);
+			break;
+
+		case R_ARM_GLOB_DAT:
+		case R_ARM_JUMP_SLOT:
+			DPRINTF("fixup R_ARM_GLOB_DAT/JUMP_SLOT (S)\n");
+			*r_ptr = sym_addr;
+			break;
+
+		case R_ARM_RELATIVE:
+			DPRINTF("fixup R_ARM_RELATIVE (B)\n");
+			*r_ptr += dest->bias;
+			break;
+
+		default:
+			printf("Error: Unknown relocation type %d\n",
+			    rel_type);
+			exit(1);
+		}
+	}
+}
+
+/**
+ * Process (fixup) all relocations in a relocation table with explicit addends.
+ */
+void rela_table_process(module_t *m, elf_rela_t *rt, size_t rt_size)
+{
+	(void) m;
+	(void) rt;
+	(void) rt_size;
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm32/src/syscall.c
===================================================================
--- uspace/lib/c/arch/arm32/src/syscall.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/src/syscall.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -70,4 +70,10 @@
 	      "r" (__arm_reg_r5),
 	      "r" (__arm_reg_r6)
+	    :
+	      /*
+	       * Clobber memory too as some arguments might be
+	       * actually pointers.
+	       */
+	      "memory"
 	);
 
Index: uspace/lib/c/arch/arm32/src/tls.c
===================================================================
--- uspace/lib/c/arch/arm32/src/tls.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/src/tls.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,3 +1,4 @@
 /*
+ * Copyright (c) 2019 Jiri Svoboda
  * Copyright (c) 2007 Pavel Jancik
  * All rights reserved.
@@ -38,4 +39,8 @@
 #include <stddef.h>
 
+#ifdef CONFIG_RTLD
+#include <rtld/rtld.h>
+#endif
+
 tcb_t *tls_alloc_arch(size_t size, size_t align)
 {
@@ -48,4 +53,32 @@
 }
 
+/*
+ * Rtld TLS support
+ */
+
+typedef struct {
+	unsigned long int ti_module;
+	unsigned long int ti_offset;
+} tls_index;
+
+int __tls_debug = 0;
+
+void *__tls_get_addr(tls_index *ti);
+
+void *__tls_get_addr(tls_index *ti)
+{
+	uint8_t *tls;
+
+#ifdef CONFIG_RTLD
+	if (runtime_env != NULL) {
+		return rtld_tls_get_addr(runtime_env, __tcb_get(),
+		    ti->ti_module, ti->ti_offset);
+	}
+#endif
+	/* Get address of static TLS block */
+	tls = tls_get();
+	return tls + ti->ti_offset;
+}
+
 /** @}
  */
Index: uspace/lib/c/arch/arm64/Makefile.common
===================================================================
--- uspace/lib/c/arch/arm64/Makefile.common	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/Makefile.common	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2015 Petr Pavlu
+# 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.
+#
+
+COMMON_CFLAGS += -fno-omit-frame-pointer
+
+LDFLAGS += -Wl,--gc-sections
+
+ENDIANESS = LE
+
+BFD_NAME = elf64-littleaarch64
+BFD_ARCH = aarch64
Index: uspace/lib/c/arch/arm64/Makefile.inc
===================================================================
--- uspace/lib/c/arch/arm64/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2015 Petr Pavlu
+# 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/entryjmp.S \
+	arch/$(UARCH)/src/fibril.S \
+	arch/$(UARCH)/src/stacktrace.c \
+	arch/$(UARCH)/src/stacktrace_asm.S \
+	arch/$(UARCH)/src/syscall.c \
+	arch/$(UARCH)/src/tls.c \
+	arch/$(UARCH)/src/thread_entry.S
+
+ARCH_AUTOCHECK_HEADERS = \
+	arch/$(UARCH)/include/libarch/fibril_context.h
Index: uspace/lib/c/arch/arm64/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 libcarm64
+ * @{
+ */
+/** @file
+ * @brief Configuration constants.
+ */
+
+#ifndef _LIBC_arm64_CONFIG_H_
+#define _LIBC_arm64_CONFIG_H_
+
+#define PAGE_WIDTH  12
+#define PAGE_SIZE   (1 << PAGE_WIDTH)
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm64/include/libarch/ddi.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 libcarm64
+ * @{
+ */
+/** @file
+ * @brief
+ */
+
+#ifndef _LIBC_arm64_DDI_H_
+#define _LIBC_arm64_DDI_H_
+
+#include <ddi.h>
+
+static inline void arch_pio_write_8(ioport8_t *port, uint8_t v)
+{
+	*port = v;
+}
+
+static inline void arch_pio_write_16(ioport16_t *port, uint16_t v)
+{
+	*port = v;
+}
+
+static inline void arch_pio_write_32(ioport32_t *port, uint32_t v)
+{
+	*port = v;
+}
+
+static inline void arch_pio_write_64(ioport64_t *port, uint64_t v)
+{
+	*port = v;
+}
+
+static inline uint8_t arch_pio_read_8(const ioport8_t *port)
+{
+	return *port;
+}
+
+static inline uint16_t arch_pio_read_16(const ioport16_t *port)
+{
+	return *port;
+}
+
+static inline uint32_t arch_pio_read_32(const ioport32_t *port)
+{
+	return *port;
+}
+
+static inline uint64_t arch_pio_read_64(const ioport64_t *port)
+{
+	return *port;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm64/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 libcarm64
+ * @{
+ */
+/** @file Definitions needed to write core files in Linux-ELF format.
+ */
+
+#ifndef _LIBC_arm64_ELF_LINUX_H_
+#define _LIBC_arm64_ELF_LINUX_H_
+
+#include <libarch/istate.h>
+#include <stdint.h>
+
+/** Linux kernel struct pt_regs structure.
+ *
+ * We need this to save register state to a core file in Linux format
+ * (readable by GDB configured for Linux target).
+ */
+typedef struct {
+	uint64_t x0;
+	uint64_t x1;
+	uint64_t x2;
+	uint64_t x3;
+	uint64_t x4;
+	uint64_t x5;
+	uint64_t x6;
+	uint64_t x7;
+	uint64_t x8;
+	uint64_t x9;
+	uint64_t x10;
+	uint64_t x11;
+	uint64_t x12;
+	uint64_t x13;
+	uint64_t x14;
+	uint64_t x15;
+	uint64_t x16;
+	uint64_t x17;
+	uint64_t x18;
+	uint64_t x19;
+	uint64_t x20;
+	uint64_t x21;
+	uint64_t x22;
+	uint64_t x23;
+	uint64_t x24;
+	uint64_t x25;
+	uint64_t x26;
+	uint64_t x27;
+	uint64_t x28;
+	uint64_t x29;
+	uint64_t x30;
+
+	uint64_t sp;
+	uint64_t pc;
+	uint64_t pstate;
+
+	uint64_t orig_x0;
+	uint64_t syscallno;
+} elf_regs_t;
+
+/** Convert istate_t to elf_regs_t. */
+static inline void istate_to_elf_regs(istate_t *istate, elf_regs_t *elf_regs)
+{
+	elf_regs->x0 = istate->x0;
+	elf_regs->x1 = istate->x1;
+	elf_regs->x2 = istate->x2;
+	elf_regs->x3 = istate->x3;
+	elf_regs->x4 = istate->x4;
+	elf_regs->x5 = istate->x5;
+	elf_regs->x6 = istate->x6;
+	elf_regs->x7 = istate->x7;
+	elf_regs->x8 = istate->x8;
+	elf_regs->x9 = istate->x9;
+	elf_regs->x10 = istate->x10;
+	elf_regs->x11 = istate->x11;
+	elf_regs->x12 = istate->x12;
+	elf_regs->x13 = istate->x13;
+	elf_regs->x14 = istate->x14;
+	elf_regs->x15 = istate->x15;
+	elf_regs->x16 = istate->x16;
+	elf_regs->x17 = istate->x17;
+	elf_regs->x18 = istate->x18;
+	elf_regs->x19 = istate->x19;
+	elf_regs->x20 = istate->x20;
+	elf_regs->x21 = istate->x21;
+	elf_regs->x22 = istate->x22;
+	elf_regs->x23 = istate->x23;
+	elf_regs->x24 = istate->x24;
+	elf_regs->x25 = istate->x25;
+	elf_regs->x26 = istate->x26;
+	elf_regs->x27 = istate->x27;
+	elf_regs->x28 = istate->x28;
+	elf_regs->x29 = istate->x29;
+	elf_regs->x30 = istate->x30;
+
+	elf_regs->sp = istate->sp;
+	elf_regs->pc = istate->pc;
+	elf_regs->pstate = istate->spsr;
+
+	elf_regs->orig_x0 = 0;
+	elf_regs->syscallno = 0;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm64/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 libcarm64
+ * @{
+ */
+/** @file
+ * @brief Function address conversion.
+ */
+
+#ifndef _LIBC_arm64_FADDR_H_
+#define _LIBC_arm64_FADDR_H_
+
+#include <types/common.h>
+
+/** Calculate absolute address of function referenced by fptr pointer.
+ *
+ * @param f Function pointer.
+ */
+#define FADDR(f)  ((uintptr_t) (f))
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm64/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 libcarm64
+ * @{
+ */
+/** @file
+ * @brief Fibrils related declarations.
+ */
+
+#ifndef _LIBC_arm64_FIBRIL_H_
+#define _LIBC_arm64_FIBRIL_H_
+
+#include <types/common.h>
+#include <align.h>
+#include <libarch/fibril_context.h>
+
+/** Size of a stack item. */
+#define STACK_ITEM_SIZE	 8
+
+/** Required stack alignment. */
+#define STACK_ALIGNMENT	 16
+
+#define SP_DELTA  (0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
+
+/** Sets data to the context.
+ *
+ * @param c Context (#context_t).
+ * @param _pc Program counter.
+ * @param stack Stack address.
+ * @param size Stack size.
+ * @param ptls Pointer to the TCB.
+ */
+#define context_set(c, _pc, stack, size, ptls) \
+	do { \
+		(c)->pc = (uint64_t) (_pc); \
+		(c)->sp = ((uint64_t) (stack)) + (size) - SP_DELTA; \
+		(c)->tls = ((uint64_t) (ptls)) + ARCH_TP_OFFSET; \
+		/* Set frame pointer too. */ \
+		(c)->x29 = 0; \
+	} while (0)
+
+static inline uintptr_t _context_get_fp(context_t *ctx)
+{
+	return ctx->x29;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm64/include/libarch/fibril_context.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/fibril_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/fibril_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 _LIBC_ARCH_FIBRIL_CONTEXT_H_
+#define _LIBC_ARCH_FIBRIL_CONTEXT_H_
+
+#define __CONTEXT_OFFSET_SP     0x00
+#define __CONTEXT_OFFSET_PC     0x08
+#define __CONTEXT_OFFSET_X19    0x10
+#define __CONTEXT_OFFSET_X20    0x18
+#define __CONTEXT_OFFSET_X21    0x20
+#define __CONTEXT_OFFSET_X22    0x28
+#define __CONTEXT_OFFSET_X23    0x30
+#define __CONTEXT_OFFSET_X24    0x38
+#define __CONTEXT_OFFSET_X25    0x40
+#define __CONTEXT_OFFSET_X26    0x48
+#define __CONTEXT_OFFSET_X27    0x50
+#define __CONTEXT_OFFSET_X28    0x58
+#define __CONTEXT_OFFSET_X29    0x60
+#define __CONTEXT_OFFSET_TLS    0x68
+#define __CONTEXT_OFFSET_VREGS  0x70
+#define __CONTEXT_SIZE          0xb0
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+typedef struct __context {
+	uint64_t sp;
+	uint64_t pc;
+	uint64_t x19;
+	uint64_t x20;
+	uint64_t x21;
+	uint64_t x22;
+	uint64_t x23;
+	uint64_t x24;
+	uint64_t x25;
+	uint64_t x26;
+	uint64_t x27;
+	uint64_t x28;
+	uint64_t x29;
+	uint64_t tls;
+	/* v8-v15, low 64 bits only. */
+	uint64_t vregs[8];
+} __context_t;
+
+#endif
+#endif
Index: uspace/lib/c/arch/arm64/include/libarch/istate.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/istate.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/istate.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+../../../../../../../kernel/arch/arm64/include/arch/istate.h
Index: uspace/lib/c/arch/arm64/include/libarch/istate_struct.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/istate_struct.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/istate_struct.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+../../../../../../../kernel/arch/arm64/include/arch/istate_struct.h
Index: uspace/lib/c/arch/arm64/include/libarch/regutils.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/regutils.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/regutils.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+../../../../../../../kernel/arch/arm64/include/arch/regutils.h
Index: uspace/lib/c/arch/arm64/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 libcarm64
+ * @{
+ */
+/** @file
+ * @brief
+ */
+
+#ifndef _LIBC_arm64_SYSCALL_H_
+#define _LIBC_arm64_SYSCALL_H_
+
+#define LIBARCH_SYSCALL_GENERIC
+
+#include <syscall.h>
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm64/include/libarch/thread.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 libcarm64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_arm64_THREAD_H_
+#define _LIBC_arm64_THREAD_H_
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm64/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 libcarm64
+ * @{
+ */
+/** @file
+ * @brief Thread-local storage.
+ */
+
+#ifndef _LIBC_arm64_TLS_H_
+#define _LIBC_arm64_TLS_H_
+
+#define CONFIG_TLS_VARIANT_1
+
+/** Offsets for accessing thread-local variables are shifted 16 bytes higher. */
+#define ARCH_TP_OFFSET  (sizeof(tcb_t) - 16)
+
+/** TCB (Thread Control Block) struct.
+ *
+ * TLS starts just after this struct.
+ */
+typedef struct {
+	/** Fibril data. */
+	void *fibril_data;
+} tcb_t;
+
+static inline void __tcb_raw_set(void *tls)
+{
+	asm volatile ("msr tpidr_el0, %[tls]" : : [tls] "r" (tls));
+}
+
+static inline void *__tcb_raw_get(void)
+{
+	void *retval;
+	asm volatile ("mrs %[tls], tpidr_el0" : [tls] "=r" (retval));
+	return retval;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm64/src/entry.S
===================================================================
--- uspace/lib/c/arch/arm64/src/entry.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/src/entry.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,48 @@
+#
+# Copyright (c) 2015 Petr Pavlu
+# 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 <abi/asmtool.h>
+
+.text
+
+.org 0
+
+## User-space task entry point
+#
+# x0 contains the PCB pointer
+#
+SYMBOL(_start)
+	#
+	# Create the first stack frame.
+	#
+	mov x29, #0
+	stp x29, x30, [sp, #-16]!
+	mov x29, sp
+
+	# Pass pcb_ptr to __c_start as the first argument (in x0)
+	bl __c_start
Index: uspace/lib/c/arch/arm64/src/entryjmp.S
===================================================================
--- uspace/lib/c/arch/arm64/src/entryjmp.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/src/entryjmp.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,41 @@
+#
+# Copyright (c) 2015 Petr Pavlu
+# 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 <abi/asmtool.h>
+
+## void entry_point_jmp(void *entry_point, void *pcb);
+#
+# x0	contains entry_point
+# x1	contains pcb
+#
+# Jump to program entry point
+SYMBOL(entry_point_jmp)
+	# Pass PCB in x0 to the entry point and jump to it.
+	mov x2, x0
+	mov x0, x1
+	br x2
Index: uspace/lib/c/arch/arm64/src/fibril.S
===================================================================
--- uspace/lib/c/arch/arm64/src/fibril.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/src/fibril.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 <abi/asmtool.h>
+#include <libarch/fibril_context.h>
+
+.text
+
+/* Static checks for the context_t save/load. */
+#if __CONTEXT_OFFSET_SP + 8 != __CONTEXT_OFFSET_PC
+#error sp and pc are not successive in context_t
+#endif
+#if __CONTEXT_OFFSET_X19 + 8 != __CONTEXT_OFFSET_X20
+#error x19 and x20 are not successive in context_t
+#endif
+#if __CONTEXT_OFFSET_X21 + 8 != __CONTEXT_OFFSET_X22
+#error x21 and x22 are not successive in context_t
+#endif
+#if __CONTEXT_OFFSET_X23 + 8 != __CONTEXT_OFFSET_X24
+#error x23 and x24 are not successive in context_t
+#endif
+#if __CONTEXT_OFFSET_X25 + 8 != __CONTEXT_OFFSET_X26
+#error x25 and x26 are not successive in context_t
+#endif
+#if __CONTEXT_OFFSET_X27 + 8 != __CONTEXT_OFFSET_X28
+#error x27 and x28 are not successive in context_t
+#endif
+#if __CONTEXT_OFFSET_X29 + 8 != __CONTEXT_OFFSET_TLS
+#error x29 and tls are not successive in context_t
+#endif
+
+FUNCTION_BEGIN(__context_save)
+	/* Save callee-saved registers into context_t pointed by x0. */
+	mov x1, sp
+	stp x1, x30, [x0, #__CONTEXT_OFFSET_SP]
+	stp x19, x20, [x0, #__CONTEXT_OFFSET_X19]
+	stp x21, x22, [x0, #__CONTEXT_OFFSET_X21]
+	stp x23, x24, [x0, #__CONTEXT_OFFSET_X23]
+	stp x25, x26, [x0, #__CONTEXT_OFFSET_X25]
+	stp x27, x28, [x0, #__CONTEXT_OFFSET_X27]
+	/* Save the last general-purpose register and TLS. */
+	mrs x1, tpidr_el0
+	stp x29, x1, [x0, #__CONTEXT_OFFSET_X29]
+	/* Save low 64 bits of v8-v15. */
+	stp d8, d9, [x0, #__CONTEXT_OFFSET_VREGS + 8 * 0]
+	stp d10, d11, [x0, #__CONTEXT_OFFSET_VREGS + 8 * 2]
+	stp d12, d13, [x0, #__CONTEXT_OFFSET_VREGS + 8 * 4]
+	stp d14, d15, [x0, #__CONTEXT_OFFSET_VREGS + 8 * 6]
+
+	/* Return 0. */
+	mov x0, #0
+	ret
+FUNCTION_END(__context_save)
+
+FUNCTION_BEGIN(__context_restore)
+	/* Restore callee-saved registers from context_t pointed by x0. */
+	ldp x2, x30, [x0, #__CONTEXT_OFFSET_SP]
+	mov sp, x2
+	ldp x19, x20, [x0, #__CONTEXT_OFFSET_X19]
+	ldp x21, x22, [x0, #__CONTEXT_OFFSET_X21]
+	ldp x23, x24, [x0, #__CONTEXT_OFFSET_X23]
+	ldp x25, x26, [x0, #__CONTEXT_OFFSET_X25]
+	ldp x27, x28, [x0, #__CONTEXT_OFFSET_X27]
+	/* Restore the last general-purpose register and TLS. */
+	ldp x29, x2, [x0, #__CONTEXT_OFFSET_X29]
+	msr tpidr_el0, x2
+	/* Restore low 64 bits of v8-v15. */
+	ldp d8, d9, [x0, #__CONTEXT_OFFSET_VREGS + 8 * 0]
+	ldp d10, d11, [x0, #__CONTEXT_OFFSET_VREGS + 8 * 2]
+	ldp d12, d13, [x0, #__CONTEXT_OFFSET_VREGS + 8 * 4]
+	ldp d14, d15, [x0, #__CONTEXT_OFFSET_VREGS + 8 * 6]
+
+	/* Return the second argument. */
+	mov x0, x1
+	ret
+FUNCTION_END(__context_restore)
Index: uspace/lib/c/arch/arm64/src/stacktrace.c
===================================================================
--- uspace/lib/c/arch/arm64/src/stacktrace.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/src/stacktrace.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 libcarm64
+ * @{
+ */
+/** @file
+ * @brief
+ */
+
+#include <stacktrace.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#define FRAME_OFFSET_FP_PREV  0
+#define FRAME_OFFSET_RA       8
+
+bool stacktrace_fp_valid(stacktrace_t *st __attribute__((unused)),
+    uintptr_t fp)
+{
+	return fp != 0;
+}
+
+errno_t stacktrace_fp_prev(stacktrace_t *st, uintptr_t fp, uintptr_t *prev)
+{
+	return (*st->ops->read_uintptr)(st->op_arg, fp + FRAME_OFFSET_FP_PREV,
+	    prev);
+}
+
+errno_t stacktrace_ra_get(stacktrace_t *st, uintptr_t fp, uintptr_t *ra)
+{
+	return (*st->ops->read_uintptr)(st->op_arg, fp + FRAME_OFFSET_RA, ra);
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm64/src/stacktrace_asm.S
===================================================================
--- uspace/lib/c/arch/arm64/src/stacktrace_asm.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/src/stacktrace_asm.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,45 @@
+#
+# Copyright (c) 2015 Petr Pavlu
+# 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 <abi/asmtool.h>
+
+.text
+
+FUNCTION_BEGIN(stacktrace_prepare)
+	ret
+FUNCTION_END(stacktrace_prepare)
+
+FUNCTION_BEGIN(stacktrace_fp_get)
+	mov x0, x29
+	ret
+FUNCTION_END(stacktrace_fp_get)
+
+FUNCTION_BEGIN(stacktrace_pc_get)
+	mov x0, x30
+	ret
+FUNCTION_END(stacktrace_pc_get)
Index: uspace/lib/c/arch/arm64/src/syscall.c
===================================================================
--- uspace/lib/c/arch/arm64/src/syscall.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/src/syscall.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 libcarm64
+ * @{
+ */
+/** @file
+ * @brief Syscall routine.
+ */
+
+#include <libc.h>
+
+/** Syscall routine.
+ *
+ * Stores p1-p6, id to r0-r6 registers and calls <code>svc</code> instruction.
+ * Returned value is read from r0 register.
+ *
+ * @param p1 Parameter 1.
+ * @param p2 Parameter 2.
+ * @param p3 Parameter 3.
+ * @param p4 Parameter 4.
+ * @param p5 Parameter 5.
+ * @param p6 Parameter 6.
+ * @param id Number of syscall.
+ *
+ * @return Syscall return value.
+ */
+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 sysarg_t __arm_reg_x0 asm("x0") = p1;
+	register sysarg_t __arm_reg_x1 asm("x1") = p2;
+	register sysarg_t __arm_reg_x2 asm("x2") = p3;
+	register sysarg_t __arm_reg_x3 asm("x3") = p4;
+	register sysarg_t __arm_reg_x4 asm("x4") = p5;
+	register sysarg_t __arm_reg_x5 asm("x5") = p6;
+	register sysarg_t __arm_reg_x6 asm("x6") = id;
+
+	asm volatile (
+	    "svc #0"
+	    : "=r" (__arm_reg_x0)
+	    : "r" (__arm_reg_x0),
+	      "r" (__arm_reg_x1),
+	      "r" (__arm_reg_x2),
+	      "r" (__arm_reg_x3),
+	      "r" (__arm_reg_x4),
+	      "r" (__arm_reg_x5),
+	      "r" (__arm_reg_x6)
+	    :
+	      /*
+	       * Clobber memory too as some arguments might be actually
+	       * pointers.
+	       */
+	      "memory"
+	);
+
+	return __arm_reg_x0;
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm64/src/thread_entry.S
===================================================================
--- uspace/lib/c/arch/arm64/src/thread_entry.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/src/thread_entry.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2015 Petr Pavlu
+# 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 <abi/asmtool.h>
+
+.text
+
+## User-space thread entry point for all but the first thread.
+#
+#
+SYMBOL(__thread_entry)
+	#
+	# Create the first stack frame.
+	#
+	mov x29, #0
+	stp x29, x30, [sp, #-16]!
+	mov x29, sp
+
+	b __thread_main
Index: uspace/lib/c/arch/arm64/src/tls.c
===================================================================
--- uspace/lib/c/arch/arm64/src/tls.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/src/tls.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 libcarm64
+ */
+/** @file
+ * @brief Thread-local storage.
+ */
+
+#include <tls.h>
+#include <stddef.h>
+
+tcb_t *tls_alloc_arch(size_t size, size_t align)
+{
+	return tls_alloc_variant_1(size, align);
+}
+
+void tls_free_arch(tcb_t *tcb, size_t size, size_t align)
+{
+	tls_free_variant_1(tcb, size, align);
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/ia32/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/config.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/include/libarch/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia32_CONFIG_H_
-#define LIBC_ia32_CONFIG_H_
+#ifndef _LIBC_ia32_CONFIG_H_
+#define _LIBC_ia32_CONFIG_H_
 
 #define PAGE_WIDTH  12
Index: uspace/lib/c/arch/ia32/include/libarch/ddi.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/ddi.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/include/libarch/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_ia32_DDI_H_
-#define LIBC_ia32_DDI_H_
+#ifndef _LIBC_ia32_DDI_H_
+#define _LIBC_ia32_DDI_H_
 
 #include <ddi.h>
Index: uspace/lib/c/arch/ia32/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/elf_linux.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/include/libarch/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia32_ELF_LINUX_H_
-#define LIBC_ia32_ELF_LINUX_H_
+#ifndef _LIBC_ia32_ELF_LINUX_H_
+#define _LIBC_ia32_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/ia32/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/faddr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/include/libarch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia32_FADDR_H_
-#define LIBC_ia32_FADDR_H_
+#ifndef _LIBC_ia32_FADDR_H_
+#define _LIBC_ia32_FADDR_H_
 
 #include <types/common.h>
Index: uspace/lib/c/arch/ia32/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/fibril.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/include/libarch/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia32_FIBRIL_H_
-#define LIBC_ia32_FIBRIL_H_
+#ifndef _LIBC_ia32_FIBRIL_H_
+#define _LIBC_ia32_FIBRIL_H_
 
 #include <types/common.h>
Index: uspace/lib/c/arch/ia32/include/libarch/fibril_context.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/fibril_context.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/include/libarch/fibril_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,15 +27,15 @@
  */
 
-#ifndef LIBC_ARCH_FIBRIL_CONTEXT_H_
-#define LIBC_ARCH_FIBRIL_CONTEXT_H_
+#ifndef _LIBC_ARCH_FIBRIL_CONTEXT_H_
+#define _LIBC_ARCH_FIBRIL_CONTEXT_H_
 
-#define CONTEXT_OFFSET_SP   0x00
-#define CONTEXT_OFFSET_PC   0x04
-#define CONTEXT_OFFSET_EBX  0x08
-#define CONTEXT_OFFSET_ESI  0x0c
-#define CONTEXT_OFFSET_EDI  0x10
-#define CONTEXT_OFFSET_EBP  0x14
-#define CONTEXT_OFFSET_TLS  0x18
-#define CONTEXT_SIZE        0x1c
+#define __CONTEXT_OFFSET_SP   0x00
+#define __CONTEXT_OFFSET_PC   0x04
+#define __CONTEXT_OFFSET_EBX  0x08
+#define __CONTEXT_OFFSET_ESI  0x0c
+#define __CONTEXT_OFFSET_EDI  0x10
+#define __CONTEXT_OFFSET_EBP  0x14
+#define __CONTEXT_OFFSET_TLS  0x18
+#define __CONTEXT_SIZE        0x1c
 
 #ifndef __ASSEMBLER__
@@ -44,5 +44,5 @@
 
 /* We include only registers that must be preserved during function call. */
-typedef struct context {
+typedef struct __context {
 	uint32_t sp;
 	uint32_t pc;
@@ -52,5 +52,5 @@
 	uint32_t ebp;
 	uint32_t tls;
-} context_t;
+} __context_t;
 
 #endif
Index: uspace/lib/c/arch/ia32/include/libarch/rtld/dynamic.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/rtld/dynamic.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/include/libarch/rtld/dynamic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia32_RTLD_DYNAMIC_H_
-#define LIBC_ia32_RTLD_DYNAMIC_H_
+#ifndef _LIBC_ia32_RTLD_DYNAMIC_H_
+#define _LIBC_ia32_RTLD_DYNAMIC_H_
 
 typedef struct {
Index: uspace/lib/c/arch/ia32/include/libarch/rtld/elf_dyn.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/rtld/elf_dyn.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/include/libarch/rtld/elf_dyn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia32_RTLD_ELF_DYN_H_
-#define LIBC_ia32_RTLD_ELF_DYN_H_
+#ifndef _LIBC_ia32_RTLD_ELF_DYN_H_
+#define _LIBC_ia32_RTLD_ELF_DYN_H_
 
 /*
Index: uspace/lib/c/arch/ia32/include/libarch/rtld/module.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/ia32/include/libarch/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2019 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_ia32_RTLD_MODULE_H_
+#define _LIBC_ia32_RTLD_MODULE_H_
+
+#include <elf/elf_mod.h>
+
+/** ELF module load flags.
+ *
+ * Keep code segment read-write
+ */
+#define RTLD_MODULE_LDF ELDF_RW
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/ia32/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/syscall.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/include/libarch/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_ia32_SYSCALL_H_
-#define LIBC_ia32_SYSCALL_H_
+#ifndef _LIBC_ia32_SYSCALL_H_
+#define _LIBC_ia32_SYSCALL_H_
 
 #include <abi/syscall.h>
Index: uspace/lib/c/arch/ia32/include/libarch/thread.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/thread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/include/libarch/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia32_THREAD_H_
-#define LIBC_ia32_THREAD_H_
+#ifndef _LIBC_ia32_THREAD_H_
+#define _LIBC_ia32_THREAD_H_
 
 #endif
Index: uspace/lib/c/arch/ia32/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/tls.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/include/libarch/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia32_TLS_H_
-#define LIBC_ia32_TLS_H_
+#ifndef _LIBC_ia32_TLS_H_
+#define _LIBC_ia32_TLS_H_
 
 #define CONFIG_TLS_VARIANT_2
Index: uspace/lib/c/arch/ia32/src/fibril.S
===================================================================
--- uspace/lib/c/arch/ia32/src/fibril.S	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/src/fibril.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,23 +37,23 @@
 # pointed by the 1st argument. Returns 0 in EAX.
 #
-FUNCTION_BEGIN(__setjmp)
+FUNCTION_BEGIN(__context_save)
 	movl 0(%esp), %eax  # the caller's return %eip
 	movl 4(%esp), %edx  # address of the context variable to save context to
 
 	# save registers to the context structure
-	movl %esp, CONTEXT_OFFSET_SP(%edx)	# %esp -> ctx->sp
-	movl %eax, CONTEXT_OFFSET_PC(%edx)	# %eip -> ctx->pc
-	movl %ebx, CONTEXT_OFFSET_EBX(%edx)	# %ebx -> ctx->ebx
-	movl %esi, CONTEXT_OFFSET_ESI(%edx)	# %esi -> ctx->esi
-	movl %edi, CONTEXT_OFFSET_EDI(%edx)	# %edi -> ctx->edi
-	movl %ebp, CONTEXT_OFFSET_EBP(%edx)	# %ebp -> ctx->ebp
+	movl %esp, __CONTEXT_OFFSET_SP(%edx)	# %esp -> ctx->sp
+	movl %eax, __CONTEXT_OFFSET_PC(%edx)	# %eip -> ctx->pc
+	movl %ebx, __CONTEXT_OFFSET_EBX(%edx)	# %ebx -> ctx->ebx
+	movl %esi, __CONTEXT_OFFSET_ESI(%edx)	# %esi -> ctx->esi
+	movl %edi, __CONTEXT_OFFSET_EDI(%edx)	# %edi -> ctx->edi
+	movl %ebp, __CONTEXT_OFFSET_EBP(%edx)	# %ebp -> ctx->ebp
 
 	# save TLS
 	movl %gs:0, %eax
-	movl %eax, CONTEXT_OFFSET_TLS(%edx)	# tls -> ctx->tls
+	movl %eax, __CONTEXT_OFFSET_TLS(%edx)	# tls -> ctx->tls
 
-	xorl %eax, %eax		# __setjmp returns 0
+	xorl %eax, %eax		# __context_save returns 0
 	ret
-FUNCTION_END(__setjmp)
+FUNCTION_END(__context_save)
 
 ## Restore saved CPU context
@@ -62,24 +62,24 @@
 # pointed by the 1st argument. Returns second argument in EAX.
 #
-FUNCTION_BEGIN(__longjmp)
+FUNCTION_BEGIN(__context_restore)
 	movl 4(%esp), %eax  # address of the context variable to restore context from
 	movl 8(%esp), %ecx  # return value
 
 	# restore registers from the context structure
-	movl CONTEXT_OFFSET_SP(%eax),%esp	# ctx->sp -> %esp
-	movl CONTEXT_OFFSET_PC(%eax),%edx	# ctx->pc -> \pc
-	movl CONTEXT_OFFSET_EBX(%eax),%ebx	# ctx->ebx -> %ebx
-	movl CONTEXT_OFFSET_ESI(%eax),%esi	# ctx->esi -> %esi
-	movl CONTEXT_OFFSET_EDI(%eax),%edi	# ctx->edi -> %edi
-	movl CONTEXT_OFFSET_EBP(%eax),%ebp	# ctx->ebp -> %ebp
+	movl __CONTEXT_OFFSET_SP(%eax),%esp	# ctx->sp -> %esp
+	movl __CONTEXT_OFFSET_PC(%eax),%edx	# ctx->pc -> \pc
+	movl __CONTEXT_OFFSET_EBX(%eax),%ebx	# ctx->ebx -> %ebx
+	movl __CONTEXT_OFFSET_ESI(%eax),%esi	# ctx->esi -> %esi
+	movl __CONTEXT_OFFSET_EDI(%eax),%edi	# ctx->edi -> %edi
+	movl __CONTEXT_OFFSET_EBP(%eax),%ebp	# ctx->ebp -> %ebp
 
 	movl %edx, 0(%esp)  # ctx->pc -> saver's return %eip
 
 	# set thread local storage
-	movl CONTEXT_OFFSET_TLS(%eax), %edx	# Set arg1 to TLS addr
+	movl __CONTEXT_OFFSET_TLS(%eax), %edx	# Set arg1 to TLS addr
 	movl %edx, %gs:0
 
 	movl %ecx, %eax
 	ret
-FUNCTION_END(__longjmp)
+FUNCTION_END(__context_restore)
 
Index: uspace/lib/c/arch/ia64/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/config.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/include/libarch/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia64_CONFIG_H_
-#define LIBC_ia64_CONFIG_H_
+#ifndef _LIBC_ia64_CONFIG_H_
+#define _LIBC_ia64_CONFIG_H_
 
 #define PAGE_WIDTH	14
Index: uspace/lib/c/arch/ia64/include/libarch/ddi.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/ddi.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/include/libarch/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia64_DDI_H_
-#define LIBC_ia64_DDI_H_
+#ifndef _LIBC_ia64_DDI_H_
+#define _LIBC_ia64_DDI_H_
 
 #include <ddi.h>
Index: uspace/lib/c/arch/ia64/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/elf_linux.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/include/libarch/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia64_ELF_LINUX_H_
-#define LIBC_ia64_ELF_LINUX_H_
+#ifndef _LIBC_ia64_ELF_LINUX_H_
+#define _LIBC_ia64_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/ia64/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/faddr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/include/libarch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia64_FADDR_H_
-#define LIBC_ia64_FADDR_H_
+#ifndef _LIBC_ia64_FADDR_H_
+#define _LIBC_ia64_FADDR_H_
 
 #include <types/common.h>
Index: uspace/lib/c/arch/ia64/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/fibril.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/include/libarch/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia64_FIBRIL_H_
-#define LIBC_ia64_FIBRIL_H_
+#ifndef _LIBC_ia64_FIBRIL_H_
+#define _LIBC_ia64_FIBRIL_H_
 
 #include <stdint.h>
@@ -43,5 +43,5 @@
 
 /*
- * __setjmp() and __longjmp() are both leaf procedures.
+ * __context_save() and __context_restore() are both leaf procedures.
  * No need to allocate scratch area.
  */
Index: uspace/lib/c/arch/ia64/include/libarch/fibril_context.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/fibril_context.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/include/libarch/fibril_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,49 +27,49 @@
  */
 
-#ifndef LIBC_ARCH_FIBRIL_CONTEXT_H_
-#define LIBC_ARCH_FIBRIL_CONTEXT_H_
+#ifndef _LIBC_ARCH_FIBRIL_CONTEXT_H_
+#define _LIBC_ARCH_FIBRIL_CONTEXT_H_
 
-#define CONTEXT_OFFSET_AR_PFS          0x000
-#define CONTEXT_OFFSET_AR_UNAT_CALLER  0x008
-#define CONTEXT_OFFSET_AR_UNAT_CALLEE  0x010
-#define CONTEXT_OFFSET_AR_RSC          0x018
-#define CONTEXT_OFFSET_BSP             0x020
-#define CONTEXT_OFFSET_AR_RNAT         0x028
-#define CONTEXT_OFFSET_AR_LC           0x030
-#define CONTEXT_OFFSET_R1              0x038
-#define CONTEXT_OFFSET_R4              0x040
-#define CONTEXT_OFFSET_R5              0x048
-#define CONTEXT_OFFSET_R6              0x050
-#define CONTEXT_OFFSET_R7              0x058
-#define CONTEXT_OFFSET_SP              0x060
-#define CONTEXT_OFFSET_TP              0x068
-#define CONTEXT_OFFSET_PC              0x070
-#define CONTEXT_OFFSET_B1              0x078
-#define CONTEXT_OFFSET_B2              0x080
-#define CONTEXT_OFFSET_B3              0x088
-#define CONTEXT_OFFSET_B4              0x090
-#define CONTEXT_OFFSET_B5              0x098
-#define CONTEXT_OFFSET_PR              0x0a0
-#define CONTEXT_OFFSET_F2              0x0b0
-#define CONTEXT_OFFSET_F3              0x0c0
-#define CONTEXT_OFFSET_F4              0x0d0
-#define CONTEXT_OFFSET_F5              0x0e0
-#define CONTEXT_OFFSET_F16             0x0f0
-#define CONTEXT_OFFSET_F17             0x100
-#define CONTEXT_OFFSET_F18             0x110
-#define CONTEXT_OFFSET_F19             0x120
-#define CONTEXT_OFFSET_F20             0x130
-#define CONTEXT_OFFSET_F21             0x140
-#define CONTEXT_OFFSET_F22             0x150
-#define CONTEXT_OFFSET_F23             0x160
-#define CONTEXT_OFFSET_F24             0x170
-#define CONTEXT_OFFSET_F25             0x180
-#define CONTEXT_OFFSET_F26             0x190
-#define CONTEXT_OFFSET_F27             0x1a0
-#define CONTEXT_OFFSET_F28             0x1b0
-#define CONTEXT_OFFSET_F29             0x1c0
-#define CONTEXT_OFFSET_F30             0x1d0
-#define CONTEXT_OFFSET_F31             0x1e0
-#define CONTEXT_SIZE                   0x1f0
+#define __CONTEXT_OFFSET_AR_PFS          0x000
+#define __CONTEXT_OFFSET_AR_UNAT_CALLER  0x008
+#define __CONTEXT_OFFSET_AR_UNAT_CALLEE  0x010
+#define __CONTEXT_OFFSET_AR_RSC          0x018
+#define __CONTEXT_OFFSET_BSP             0x020
+#define __CONTEXT_OFFSET_AR_RNAT         0x028
+#define __CONTEXT_OFFSET_AR_LC           0x030
+#define __CONTEXT_OFFSET_R1              0x038
+#define __CONTEXT_OFFSET_R4              0x040
+#define __CONTEXT_OFFSET_R5              0x048
+#define __CONTEXT_OFFSET_R6              0x050
+#define __CONTEXT_OFFSET_R7              0x058
+#define __CONTEXT_OFFSET_SP              0x060
+#define __CONTEXT_OFFSET_TP              0x068
+#define __CONTEXT_OFFSET_PC              0x070
+#define __CONTEXT_OFFSET_B1              0x078
+#define __CONTEXT_OFFSET_B2              0x080
+#define __CONTEXT_OFFSET_B3              0x088
+#define __CONTEXT_OFFSET_B4              0x090
+#define __CONTEXT_OFFSET_B5              0x098
+#define __CONTEXT_OFFSET_PR              0x0a0
+#define __CONTEXT_OFFSET_F2              0x0b0
+#define __CONTEXT_OFFSET_F3              0x0c0
+#define __CONTEXT_OFFSET_F4              0x0d0
+#define __CONTEXT_OFFSET_F5              0x0e0
+#define __CONTEXT_OFFSET_F16             0x0f0
+#define __CONTEXT_OFFSET_F17             0x100
+#define __CONTEXT_OFFSET_F18             0x110
+#define __CONTEXT_OFFSET_F19             0x120
+#define __CONTEXT_OFFSET_F20             0x130
+#define __CONTEXT_OFFSET_F21             0x140
+#define __CONTEXT_OFFSET_F22             0x150
+#define __CONTEXT_OFFSET_F23             0x160
+#define __CONTEXT_OFFSET_F24             0x170
+#define __CONTEXT_OFFSET_F25             0x180
+#define __CONTEXT_OFFSET_F26             0x190
+#define __CONTEXT_OFFSET_F27             0x1a0
+#define __CONTEXT_OFFSET_F28             0x1b0
+#define __CONTEXT_OFFSET_F29             0x1c0
+#define __CONTEXT_OFFSET_F30             0x1d0
+#define __CONTEXT_OFFSET_F31             0x1e0
+#define __CONTEXT_SIZE                   0x1f0
 
 #ifndef __ASSEMBLER__
@@ -79,5 +79,5 @@
 
 // Only save registers that must be preserved across function calls.
-typedef struct context {
+typedef struct __context {
 	// Application registers.
 	uint64_t ar_pfs;
@@ -132,5 +132,5 @@
 	uint128_t f30;
 	uint128_t f31;
-} context_t;
+} __context_t;
 
 #endif  /* __ASSEMBLER__ */
Index: uspace/lib/c/arch/ia64/include/libarch/stack.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/stack.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/include/libarch/stack.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia64_STACK_H_
-#define LIBC_ia64_STACK_H_
+#ifndef _LIBC_ia64_STACK_H_
+#define _LIBC_ia64_STACK_H_
 
 #define STACK_ITEM_SIZE			8
Index: uspace/lib/c/arch/ia64/include/libarch/stackarg.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/stackarg.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/include/libarch/stackarg.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_STACKARG_H_
-#define LIBC_STACKARG_H_
+#ifndef _LIBC_STACKARG_H_
+#define _LIBC_STACKARG_H_
 
 #endif
Index: uspace/lib/c/arch/ia64/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/syscall.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/include/libarch/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_ia64_SYSCALL_H_
-#define LIBC_ia64_SYSCALL_H_
+#ifndef _LIBC_ia64_SYSCALL_H_
+#define _LIBC_ia64_SYSCALL_H_
 
 #define LIBARCH_SYSCALL_GENERIC
Index: uspace/lib/c/arch/ia64/include/libarch/thread.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/thread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/include/libarch/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia64_THREAD_H_
-#define LIBC_ia64_THREAD_H_
+#ifndef _LIBC_ia64_THREAD_H_
+#define _LIBC_ia64_THREAD_H_
 
 #endif
Index: uspace/lib/c/arch/ia64/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/tls.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/include/libarch/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia64_TLS_H_
-#define LIBC_ia64_TLS_H_
+#ifndef _LIBC_ia64_TLS_H_
+#define _LIBC_ia64_TLS_H_
 
 #define CONFIG_TLS_VARIANT_1
Index: uspace/lib/c/arch/ia64/src/fibril.S
===================================================================
--- uspace/lib/c/arch/ia64/src/fibril.S	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/src/fibril.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -32,5 +32,5 @@
 .text
 
-FUNCTION_BEGIN(__setjmp)
+FUNCTION_BEGIN(__context_save)
 	alloc loc0 = ar.pfs, 1, 49, 0, 0
 	mov loc1 = ar.unat ;;
@@ -58,50 +58,50 @@
 	mov loc6 = ar.lc
 
-	add loc8 = CONTEXT_OFFSET_AR_PFS, in0
-	add loc9 = CONTEXT_OFFSET_AR_UNAT_CALLER, in0
-	add loc10 = CONTEXT_OFFSET_AR_UNAT_CALLEE, in0
-	add loc11 = CONTEXT_OFFSET_AR_RSC, in0
-	add loc12 = CONTEXT_OFFSET_BSP, in0
-	add loc13 = CONTEXT_OFFSET_AR_RNAT, in0
-	add loc14 = CONTEXT_OFFSET_AR_LC, in0
-
-	add loc15 = CONTEXT_OFFSET_R1, in0
-	add loc16 = CONTEXT_OFFSET_R4, in0
-	add loc17 = CONTEXT_OFFSET_R5, in0
-	add loc18 = CONTEXT_OFFSET_R6, in0
-	add loc19 = CONTEXT_OFFSET_R7, in0
-	add loc20 = CONTEXT_OFFSET_SP, in0
-	add loc21 = CONTEXT_OFFSET_TP, in0
-
-	add loc22 = CONTEXT_OFFSET_PC, in0
-	add loc23 = CONTEXT_OFFSET_B1, in0
-	add loc24 = CONTEXT_OFFSET_B2, in0
-	add loc25 = CONTEXT_OFFSET_B3, in0
-	add loc26 = CONTEXT_OFFSET_B4, in0
-	add loc27 = CONTEXT_OFFSET_B5, in0
-
-	add loc28 = CONTEXT_OFFSET_PR, in0
-
-	add loc29 = CONTEXT_OFFSET_F2, in0
-	add loc30 = CONTEXT_OFFSET_F3, in0
-	add loc31 = CONTEXT_OFFSET_F4, in0
-	add loc32 = CONTEXT_OFFSET_F5, in0
-
-	add loc33 = CONTEXT_OFFSET_F16, in0
-	add loc34 = CONTEXT_OFFSET_F17, in0
-	add loc35 = CONTEXT_OFFSET_F18, in0
-	add loc36 = CONTEXT_OFFSET_F19, in0
-	add loc37 = CONTEXT_OFFSET_F20, in0
-	add loc38 = CONTEXT_OFFSET_F21, in0
-	add loc39 = CONTEXT_OFFSET_F22, in0
-	add loc40 = CONTEXT_OFFSET_F23, in0
-	add loc41 = CONTEXT_OFFSET_F24, in0
-	add loc42 = CONTEXT_OFFSET_F25, in0
-	add loc43 = CONTEXT_OFFSET_F26, in0
-	add loc44 = CONTEXT_OFFSET_F27, in0
-	add loc45 = CONTEXT_OFFSET_F28, in0
-	add loc46 = CONTEXT_OFFSET_F29, in0
-	add loc47 = CONTEXT_OFFSET_F30, in0
-	add loc48 = CONTEXT_OFFSET_F31, in0 ;;
+	add loc8 = __CONTEXT_OFFSET_AR_PFS, in0
+	add loc9 = __CONTEXT_OFFSET_AR_UNAT_CALLER, in0
+	add loc10 = __CONTEXT_OFFSET_AR_UNAT_CALLEE, in0
+	add loc11 = __CONTEXT_OFFSET_AR_RSC, in0
+	add loc12 = __CONTEXT_OFFSET_BSP, in0
+	add loc13 = __CONTEXT_OFFSET_AR_RNAT, in0
+	add loc14 = __CONTEXT_OFFSET_AR_LC, in0
+
+	add loc15 = __CONTEXT_OFFSET_R1, in0
+	add loc16 = __CONTEXT_OFFSET_R4, in0
+	add loc17 = __CONTEXT_OFFSET_R5, in0
+	add loc18 = __CONTEXT_OFFSET_R6, in0
+	add loc19 = __CONTEXT_OFFSET_R7, in0
+	add loc20 = __CONTEXT_OFFSET_SP, in0
+	add loc21 = __CONTEXT_OFFSET_TP, in0
+
+	add loc22 = __CONTEXT_OFFSET_PC, in0
+	add loc23 = __CONTEXT_OFFSET_B1, in0
+	add loc24 = __CONTEXT_OFFSET_B2, in0
+	add loc25 = __CONTEXT_OFFSET_B3, in0
+	add loc26 = __CONTEXT_OFFSET_B4, in0
+	add loc27 = __CONTEXT_OFFSET_B5, in0
+
+	add loc28 = __CONTEXT_OFFSET_PR, in0
+
+	add loc29 = __CONTEXT_OFFSET_F2, in0
+	add loc30 = __CONTEXT_OFFSET_F3, in0
+	add loc31 = __CONTEXT_OFFSET_F4, in0
+	add loc32 = __CONTEXT_OFFSET_F5, in0
+
+	add loc33 = __CONTEXT_OFFSET_F16, in0
+	add loc34 = __CONTEXT_OFFSET_F17, in0
+	add loc35 = __CONTEXT_OFFSET_F18, in0
+	add loc36 = __CONTEXT_OFFSET_F19, in0
+	add loc37 = __CONTEXT_OFFSET_F20, in0
+	add loc38 = __CONTEXT_OFFSET_F21, in0
+	add loc39 = __CONTEXT_OFFSET_F22, in0
+	add loc40 = __CONTEXT_OFFSET_F23, in0
+	add loc41 = __CONTEXT_OFFSET_F24, in0
+	add loc42 = __CONTEXT_OFFSET_F25, in0
+	add loc43 = __CONTEXT_OFFSET_F26, in0
+	add loc44 = __CONTEXT_OFFSET_F27, in0
+	add loc45 = __CONTEXT_OFFSET_F28, in0
+	add loc46 = __CONTEXT_OFFSET_F29, in0
+	add loc47 = __CONTEXT_OFFSET_F30, in0
+	add loc48 = __CONTEXT_OFFSET_F31, in0 ;;
 
 	/*
@@ -178,57 +178,57 @@
 	mov ar.unat = loc1
 
-	mov r8 = 0 	/* __setjmp returns 0 */
+	mov r8 = 0 	/* __context_save returns 0 */
 	br.ret.sptk.many b0
-FUNCTION_END(__setjmp)
-
-FUNCTION_BEGIN(__longjmp)
+FUNCTION_END(__context_save)
+
+FUNCTION_BEGIN(__context_restore)
 	alloc loc0 = ar.pfs, 2, 50, 0, 0 ;;
 
-	add loc9 = CONTEXT_OFFSET_AR_PFS, in0
-	add loc10 = CONTEXT_OFFSET_AR_UNAT_CALLER, in0
-	add loc11 = CONTEXT_OFFSET_AR_UNAT_CALLEE, in0
-	add loc12 = CONTEXT_OFFSET_AR_RSC, in0
-	add loc13 = CONTEXT_OFFSET_BSP, in0
-	add loc14 = CONTEXT_OFFSET_AR_RNAT, in0
-	add loc15 = CONTEXT_OFFSET_AR_LC, in0
-
-	add loc16 = CONTEXT_OFFSET_R1, in0
-	add loc17 = CONTEXT_OFFSET_R4, in0
-	add loc18 = CONTEXT_OFFSET_R5, in0
-	add loc19 = CONTEXT_OFFSET_R6, in0
-	add loc20 = CONTEXT_OFFSET_R7, in0
-	add loc21 = CONTEXT_OFFSET_SP, in0
-	add loc22 = CONTEXT_OFFSET_TP, in0
-
-	add loc23 = CONTEXT_OFFSET_PC, in0
-	add loc24 = CONTEXT_OFFSET_B1, in0
-	add loc25 = CONTEXT_OFFSET_B2, in0
-	add loc26 = CONTEXT_OFFSET_B3, in0
-	add loc27 = CONTEXT_OFFSET_B4, in0
-	add loc28 = CONTEXT_OFFSET_B5, in0
-
-	add loc29 = CONTEXT_OFFSET_PR, in0
-
-	add loc30 = CONTEXT_OFFSET_F2, in0
-	add loc31 = CONTEXT_OFFSET_F3, in0
-	add loc32 = CONTEXT_OFFSET_F4, in0
-	add loc33 = CONTEXT_OFFSET_F5, in0
-
-	add loc34 = CONTEXT_OFFSET_F16, in0
-	add loc35 = CONTEXT_OFFSET_F17, in0
-	add loc36 = CONTEXT_OFFSET_F18, in0
-	add loc37 = CONTEXT_OFFSET_F19, in0
-	add loc38 = CONTEXT_OFFSET_F20, in0
-	add loc39 = CONTEXT_OFFSET_F21, in0
-	add loc40 = CONTEXT_OFFSET_F22, in0
-	add loc41 = CONTEXT_OFFSET_F23, in0
-	add loc42 = CONTEXT_OFFSET_F24, in0
-	add loc43 = CONTEXT_OFFSET_F25, in0
-	add loc44 = CONTEXT_OFFSET_F26, in0
-	add loc45 = CONTEXT_OFFSET_F27, in0
-	add loc46 = CONTEXT_OFFSET_F28, in0
-	add loc47 = CONTEXT_OFFSET_F29, in0
-	add loc48 = CONTEXT_OFFSET_F30, in0
-	add loc49 = CONTEXT_OFFSET_F31, in0 ;;
+	add loc9 = __CONTEXT_OFFSET_AR_PFS, in0
+	add loc10 = __CONTEXT_OFFSET_AR_UNAT_CALLER, in0
+	add loc11 = __CONTEXT_OFFSET_AR_UNAT_CALLEE, in0
+	add loc12 = __CONTEXT_OFFSET_AR_RSC, in0
+	add loc13 = __CONTEXT_OFFSET_BSP, in0
+	add loc14 = __CONTEXT_OFFSET_AR_RNAT, in0
+	add loc15 = __CONTEXT_OFFSET_AR_LC, in0
+
+	add loc16 = __CONTEXT_OFFSET_R1, in0
+	add loc17 = __CONTEXT_OFFSET_R4, in0
+	add loc18 = __CONTEXT_OFFSET_R5, in0
+	add loc19 = __CONTEXT_OFFSET_R6, in0
+	add loc20 = __CONTEXT_OFFSET_R7, in0
+	add loc21 = __CONTEXT_OFFSET_SP, in0
+	add loc22 = __CONTEXT_OFFSET_TP, in0
+
+	add loc23 = __CONTEXT_OFFSET_PC, in0
+	add loc24 = __CONTEXT_OFFSET_B1, in0
+	add loc25 = __CONTEXT_OFFSET_B2, in0
+	add loc26 = __CONTEXT_OFFSET_B3, in0
+	add loc27 = __CONTEXT_OFFSET_B4, in0
+	add loc28 = __CONTEXT_OFFSET_B5, in0
+
+	add loc29 = __CONTEXT_OFFSET_PR, in0
+
+	add loc30 = __CONTEXT_OFFSET_F2, in0
+	add loc31 = __CONTEXT_OFFSET_F3, in0
+	add loc32 = __CONTEXT_OFFSET_F4, in0
+	add loc33 = __CONTEXT_OFFSET_F5, in0
+
+	add loc34 = __CONTEXT_OFFSET_F16, in0
+	add loc35 = __CONTEXT_OFFSET_F17, in0
+	add loc36 = __CONTEXT_OFFSET_F18, in0
+	add loc37 = __CONTEXT_OFFSET_F19, in0
+	add loc38 = __CONTEXT_OFFSET_F20, in0
+	add loc39 = __CONTEXT_OFFSET_F21, in0
+	add loc40 = __CONTEXT_OFFSET_F22, in0
+	add loc41 = __CONTEXT_OFFSET_F23, in0
+	add loc42 = __CONTEXT_OFFSET_F24, in0
+	add loc43 = __CONTEXT_OFFSET_F25, in0
+	add loc44 = __CONTEXT_OFFSET_F26, in0
+	add loc45 = __CONTEXT_OFFSET_F27, in0
+	add loc46 = __CONTEXT_OFFSET_F28, in0
+	add loc47 = __CONTEXT_OFFSET_F29, in0
+	add loc48 = __CONTEXT_OFFSET_F30, in0
+	add loc49 = __CONTEXT_OFFSET_F31, in0 ;;
 
 	ld8 loc0 = [loc9]	/* load ar.pfs */
@@ -335,5 +335,5 @@
 	mov ar.unat = loc1
 
-	mov r8 = in1			/* __longjmp returns second argument */
+	mov r8 = in1			/* __context_restore returns second argument */
 	br.ret.sptk.many b0
-FUNCTION_END(__longjmp)
+FUNCTION_END(__context_restore)
Index: uspace/lib/c/arch/mips32/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/config.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/include/libarch/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_mips32_CONFIG_H_
-#define LIBC_mips32_CONFIG_H_
+#ifndef _LIBC_mips32_CONFIG_H_
+#define _LIBC_mips32_CONFIG_H_
 
 #define PAGE_WIDTH  14
Index: uspace/lib/c/arch/mips32/include/libarch/ddi.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/ddi.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/include/libarch/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_mips32_DDI_H_
-#define LIBC_mips32_DDI_H_
+#ifndef _LIBC_mips32_DDI_H_
+#define _LIBC_mips32_DDI_H_
 
 #include <ddi.h>
Index: uspace/lib/c/arch/mips32/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/elf_linux.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/include/libarch/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_mips32_ELF_LINUX_H_
-#define LIBC_mips32_ELF_LINUX_H_
+#ifndef _LIBC_mips32_ELF_LINUX_H_
+#define _LIBC_mips32_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/mips32/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/faddr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/include/libarch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_mips32_FADDR_H_
-#define LIBC_mips32_FADDR_H_
+#ifndef _LIBC_mips32_FADDR_H_
+#define _LIBC_mips32_FADDR_H_
 
 #include <types/common.h>
Index: uspace/lib/c/arch/mips32/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/fibril.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/include/libarch/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_mips32_FIBRIL_H_
-#define LIBC_mips32_FIBRIL_H_
+#ifndef _LIBC_mips32_FIBRIL_H_
+#define _LIBC_mips32_FIBRIL_H_
 
 #include <stdint.h>
Index: uspace/lib/c/arch/mips32/include/libarch/fibril_context.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/fibril_context.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/include/libarch/fibril_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,32 +27,32 @@
  */
 
-#ifndef LIBC_ARCH_FIBRIL_CONTEXT_H_
-#define LIBC_ARCH_FIBRIL_CONTEXT_H_
+#ifndef _LIBC_ARCH_FIBRIL_CONTEXT_H_
+#define _LIBC_ARCH_FIBRIL_CONTEXT_H_
 
-#define CONTEXT_OFFSET_SP   0x00
-#define CONTEXT_OFFSET_PC   0x04
-#define CONTEXT_OFFSET_S0   0x08
-#define CONTEXT_OFFSET_S1   0x0c
-#define CONTEXT_OFFSET_S2   0x10
-#define CONTEXT_OFFSET_S3   0x14
-#define CONTEXT_OFFSET_S4   0x18
-#define CONTEXT_OFFSET_S5   0x1c
-#define CONTEXT_OFFSET_S6   0x20
-#define CONTEXT_OFFSET_S7   0x24
-#define CONTEXT_OFFSET_S8   0x28
-#define CONTEXT_OFFSET_GP   0x2c
-#define CONTEXT_OFFSET_TLS  0x30
-#define CONTEXT_OFFSET_F20  0x34
-#define CONTEXT_OFFSET_F21  0x38
-#define CONTEXT_OFFSET_F22  0x3c
-#define CONTEXT_OFFSET_F23  0x40
-#define CONTEXT_OFFSET_F24  0x44
-#define CONTEXT_OFFSET_F25  0x48
-#define CONTEXT_OFFSET_F26  0x4c
-#define CONTEXT_OFFSET_F27  0x50
-#define CONTEXT_OFFSET_F28  0x54
-#define CONTEXT_OFFSET_F29  0x58
-#define CONTEXT_OFFSET_F30  0x5c
-#define CONTEXT_SIZE        0x60
+#define __CONTEXT_OFFSET_SP   0x00
+#define __CONTEXT_OFFSET_PC   0x04
+#define __CONTEXT_OFFSET_S0   0x08
+#define __CONTEXT_OFFSET_S1   0x0c
+#define __CONTEXT_OFFSET_S2   0x10
+#define __CONTEXT_OFFSET_S3   0x14
+#define __CONTEXT_OFFSET_S4   0x18
+#define __CONTEXT_OFFSET_S5   0x1c
+#define __CONTEXT_OFFSET_S6   0x20
+#define __CONTEXT_OFFSET_S7   0x24
+#define __CONTEXT_OFFSET_S8   0x28
+#define __CONTEXT_OFFSET_GP   0x2c
+#define __CONTEXT_OFFSET_TLS  0x30
+#define __CONTEXT_OFFSET_F20  0x34
+#define __CONTEXT_OFFSET_F21  0x38
+#define __CONTEXT_OFFSET_F22  0x3c
+#define __CONTEXT_OFFSET_F23  0x40
+#define __CONTEXT_OFFSET_F24  0x44
+#define __CONTEXT_OFFSET_F25  0x48
+#define __CONTEXT_OFFSET_F26  0x4c
+#define __CONTEXT_OFFSET_F27  0x50
+#define __CONTEXT_OFFSET_F28  0x54
+#define __CONTEXT_OFFSET_F29  0x58
+#define __CONTEXT_OFFSET_F30  0x5c
+#define __CONTEXT_SIZE        0x60
 
 #ifndef __ASSEMBLER__
@@ -61,5 +61,5 @@
 #include <stdint.h>
 
-typedef struct context {
+typedef struct __context {
 	uint32_t sp;
 	uint32_t pc;
@@ -87,5 +87,5 @@
 	uint32_t f29;
 	uint32_t f30;
-} context_t;
+} __context_t;
 
 #endif
Index: uspace/lib/c/arch/mips32/include/libarch/stack.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/stack.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/include/libarch/stack.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_mips32_STACK_H_
-#define LIBC_mips32_STACK_H_
+#ifndef _LIBC_mips32_STACK_H_
+#define _LIBC_mips32_STACK_H_
 
 #define STACK_ITEM_SIZE  4
Index: uspace/lib/c/arch/mips32/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/syscall.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/include/libarch/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_mips32_SYSCALL_H_
-#define LIBC_mips32_SYSCALL_H_
+#ifndef _LIBC_mips32_SYSCALL_H_
+#define _LIBC_mips32_SYSCALL_H_
 
 #define LIBARCH_SYSCALL_GENERIC
Index: uspace/lib/c/arch/mips32/include/libarch/thread.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/thread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/include/libarch/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_mips32_THREAD_H_
-#define LIBC_mips32_THREAD_H_
+#ifndef _LIBC_mips32_THREAD_H_
+#define _LIBC_mips32_THREAD_H_
 
 #endif
Index: uspace/lib/c/arch/mips32/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/tls.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/include/libarch/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -36,6 +36,6 @@
 /* TLS for MIPS is described in http://www.linux-mips.org/wiki/NPTL */
 
-#ifndef LIBC_mips32_TLS_H_
-#define LIBC_mips32_TLS_H_
+#ifndef _LIBC_mips32_TLS_H_
+#define _LIBC_mips32_TLS_H_
 
 /*
Index: uspace/lib/c/arch/mips32/src/fibril.S
===================================================================
--- uspace/lib/c/arch/mips32/src/fibril.S	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/src/fibril.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,111 +35,111 @@
 #include <libarch/fibril_context.h>
 
-FUNCTION_BEGIN(__setjmp)
-	sw $s0, CONTEXT_OFFSET_S0($a0)
-	sw $s1, CONTEXT_OFFSET_S1($a0)
-	sw $s2, CONTEXT_OFFSET_S2($a0)
-	sw $s3, CONTEXT_OFFSET_S3($a0)
-	sw $s4, CONTEXT_OFFSET_S4($a0)
-	sw $s5, CONTEXT_OFFSET_S5($a0)
-	sw $s6, CONTEXT_OFFSET_S6($a0)
-	sw $s7, CONTEXT_OFFSET_S7($a0)
-	sw $s8, CONTEXT_OFFSET_S8($a0)
-	sw $gp, CONTEXT_OFFSET_GP($a0)
+FUNCTION_BEGIN(__context_save)
+	sw $s0, __CONTEXT_OFFSET_S0($a0)
+	sw $s1, __CONTEXT_OFFSET_S1($a0)
+	sw $s2, __CONTEXT_OFFSET_S2($a0)
+	sw $s3, __CONTEXT_OFFSET_S3($a0)
+	sw $s4, __CONTEXT_OFFSET_S4($a0)
+	sw $s5, __CONTEXT_OFFSET_S5($a0)
+	sw $s6, __CONTEXT_OFFSET_S6($a0)
+	sw $s7, __CONTEXT_OFFSET_S7($a0)
+	sw $s8, __CONTEXT_OFFSET_S8($a0)
+	sw $gp, __CONTEXT_OFFSET_GP($a0)
 
-	sw $k1, CONTEXT_OFFSET_TLS($a0)
+	sw $k1, __CONTEXT_OFFSET_TLS($a0)
 
 #ifdef CONFIG_FPU
 	mfc1 $t0, $20
-	sw $t0, CONTEXT_OFFSET_F20($a0)
+	sw $t0, __CONTEXT_OFFSET_F20($a0)
 
 	mfc1 $t0, $21
-	sw $t0, CONTEXT_OFFSET_F21($a0)
+	sw $t0, __CONTEXT_OFFSET_F21($a0)
 
 	mfc1 $t0, $22
-	sw $t0, CONTEXT_OFFSET_F22($a0)
+	sw $t0, __CONTEXT_OFFSET_F22($a0)
 
 	mfc1 $t0, $23
-	sw $t0, CONTEXT_OFFSET_F23($a0)
+	sw $t0, __CONTEXT_OFFSET_F23($a0)
 
 	mfc1 $t0, $24
-	sw $t0, CONTEXT_OFFSET_F24($a0)
+	sw $t0, __CONTEXT_OFFSET_F24($a0)
 
 	mfc1 $t0, $25
-	sw $t0, CONTEXT_OFFSET_F25($a0)
+	sw $t0, __CONTEXT_OFFSET_F25($a0)
 
 	mfc1 $t0, $26
-	sw $t0, CONTEXT_OFFSET_F26($a0)
+	sw $t0, __CONTEXT_OFFSET_F26($a0)
 
 	mfc1 $t0, $27
-	sw $t0, CONTEXT_OFFSET_F27($a0)
+	sw $t0, __CONTEXT_OFFSET_F27($a0)
 
 	mfc1 $t0, $28
-	sw $t0, CONTEXT_OFFSET_F28($a0)
+	sw $t0, __CONTEXT_OFFSET_F28($a0)
 
 	mfc1 $t0, $29
-	sw $t0, CONTEXT_OFFSET_F29($a0)
+	sw $t0, __CONTEXT_OFFSET_F29($a0)
 
 	mfc1 $t0, $30
-	sw $t0, CONTEXT_OFFSET_F30($a0)
+	sw $t0, __CONTEXT_OFFSET_F30($a0)
 #endif /* CONFIG_FPU */
 
-	sw $ra, CONTEXT_OFFSET_PC($a0)
-	sw $sp, CONTEXT_OFFSET_SP($a0)
+	sw $ra, __CONTEXT_OFFSET_PC($a0)
+	sw $sp, __CONTEXT_OFFSET_SP($a0)
 
-	# __setjmp returns 0
+	# __context_save returns 0
 	j $ra
 	li $v0, 0
-FUNCTION_END(__setjmp)
+FUNCTION_END(__context_save)
 
-FUNCTION_BEGIN(__longjmp)
-	lw $s0, CONTEXT_OFFSET_S0($a0)
-	lw $s1, CONTEXT_OFFSET_S1($a0)
-	lw $s2, CONTEXT_OFFSET_S2($a0)
-	lw $s3, CONTEXT_OFFSET_S3($a0)
-	lw $s4, CONTEXT_OFFSET_S4($a0)
-	lw $s5, CONTEXT_OFFSET_S5($a0)
-	lw $s6, CONTEXT_OFFSET_S6($a0)
-	lw $s7, CONTEXT_OFFSET_S7($a0)
-	lw $s8, CONTEXT_OFFSET_S8($a0)
-	lw $gp, CONTEXT_OFFSET_GP($a0)
-	lw $k1, CONTEXT_OFFSET_TLS($a0)
+FUNCTION_BEGIN(__context_restore)
+	lw $s0, __CONTEXT_OFFSET_S0($a0)
+	lw $s1, __CONTEXT_OFFSET_S1($a0)
+	lw $s2, __CONTEXT_OFFSET_S2($a0)
+	lw $s3, __CONTEXT_OFFSET_S3($a0)
+	lw $s4, __CONTEXT_OFFSET_S4($a0)
+	lw $s5, __CONTEXT_OFFSET_S5($a0)
+	lw $s6, __CONTEXT_OFFSET_S6($a0)
+	lw $s7, __CONTEXT_OFFSET_S7($a0)
+	lw $s8, __CONTEXT_OFFSET_S8($a0)
+	lw $gp, __CONTEXT_OFFSET_GP($a0)
+	lw $k1, __CONTEXT_OFFSET_TLS($a0)
 
 #ifdef CONFIG_FPU
-	lw $t0, CONTEXT_OFFSET_F20($a0)
+	lw $t0, __CONTEXT_OFFSET_F20($a0)
 	mtc1 $t0, $20
 
-	lw $t0, CONTEXT_OFFSET_F21($a0)
+	lw $t0, __CONTEXT_OFFSET_F21($a0)
 	mtc1 $t0, $21
 
-	lw $t0, CONTEXT_OFFSET_F22($a0)
+	lw $t0, __CONTEXT_OFFSET_F22($a0)
 	mtc1 $t0, $22
 
-	lw $t0, CONTEXT_OFFSET_F23($a0)
+	lw $t0, __CONTEXT_OFFSET_F23($a0)
 	mtc1 $t0, $23
 
-	lw $t0, CONTEXT_OFFSET_F24($a0)
+	lw $t0, __CONTEXT_OFFSET_F24($a0)
 	mtc1 $t0, $24
 
-	lw $t0, CONTEXT_OFFSET_F25($a0)
+	lw $t0, __CONTEXT_OFFSET_F25($a0)
 	mtc1 $t0, $25
 
-	lw $t0, CONTEXT_OFFSET_F26($a0)
+	lw $t0, __CONTEXT_OFFSET_F26($a0)
 	mtc1 $t0, $26
 
-	lw $t0, CONTEXT_OFFSET_F27($a0)
+	lw $t0, __CONTEXT_OFFSET_F27($a0)
 	mtc1 $t0, $27
 
-	lw $t0, CONTEXT_OFFSET_F28($a0)
+	lw $t0, __CONTEXT_OFFSET_F28($a0)
 	mtc1 $t0, $28
 
-	lw $t0, CONTEXT_OFFSET_F29($a0)
+	lw $t0, __CONTEXT_OFFSET_F29($a0)
 	mtc1 $t0, $29
 
-	lw $t0, CONTEXT_OFFSET_F30($a0)
+	lw $t0, __CONTEXT_OFFSET_F30($a0)
 	mtc1 $t0, $30
 #endif /* CONFIG_FPU */
 
-	lw $ra, CONTEXT_OFFSET_PC($a0)
-	lw $sp, CONTEXT_OFFSET_SP($a0)
+	lw $ra, __CONTEXT_OFFSET_PC($a0)
+	lw $sp, __CONTEXT_OFFSET_SP($a0)
 
 	# Just for the jump into first function,
@@ -147,6 +147,6 @@
 	move $t9, $ra
 
-	# __longjmp returns second argument
+	# __context_restore returns second argument
 	j $ra
 	move $v0, $a1
-FUNCTION_END(__longjmp)
+FUNCTION_END(__context_restore)
Index: uspace/lib/c/arch/mips32/src/syscall.c
===================================================================
--- uspace/lib/c/arch/mips32/src/syscall.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/src/syscall.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -57,9 +57,15 @@
 	      "r" (__mips_reg_t1),
 	      "r" (__mips_reg_v0)
+	    :
 	      /*
 	       * We are a function call, although C
 	       * does not know it.
 	       */
-	    : "%ra"
+	      "%ra",
+	      /*
+	       * Clobber memory too as some arguments might be
+	       * actually pointers.
+	       */
+	      "memory"
 	);
 
Index: uspace/lib/c/arch/ppc32/Makefile.common
===================================================================
--- uspace/lib/c/arch/ppc32/Makefile.common	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/Makefile.common	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,5 +33,5 @@
 endif
 
-COMMON_CFLAGS += -mcpu=powerpc -m$(FLOATS)-float -m32
+COMMON_CFLAGS += -mcpu=powerpc -m$(FLOATS)-float -m32 -Wl,-z,max-page-size=0x1000
 AFLAGS += -a32
 LDFLAGS += -Wl,--gc-sections
Index: uspace/lib/c/arch/ppc32/Makefile.inc
===================================================================
--- uspace/lib/c/arch/ppc32/Makefile.inc	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,5 +34,7 @@
 	arch/$(UARCH)/src/tls.c \
 	arch/$(UARCH)/src/stacktrace.c \
-	arch/$(UARCH)/src/stacktrace_asm.S
+	arch/$(UARCH)/src/stacktrace_asm.S \
+	arch/$(UARCH)/src/rtld/dynamic.c \
+	arch/$(UARCH)/src/rtld/reloc.c
 
 ARCH_AUTOCHECK_HEADERS = \
Index: uspace/lib/c/arch/ppc32/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/config.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/include/libarch/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ppc32_CONFIG_H_
-#define LIBC_ppc32_CONFIG_H_
+#ifndef _LIBC_ppc32_CONFIG_H_
+#define _LIBC_ppc32_CONFIG_H_
 
 #define PAGE_WIDTH	12
Index: uspace/lib/c/arch/ppc32/include/libarch/ddi.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/ddi.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/include/libarch/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_ppc32_DDI_H_
-#define LIBC_ppc32_DDI_H_
+#ifndef _LIBC_ppc32_DDI_H_
+#define _LIBC_ppc32_DDI_H_
 
 #include <ddi.h>
Index: uspace/lib/c/arch/ppc32/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/elf_linux.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/include/libarch/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ppc32_ELF_LINUX_H_
-#define LIBC_ppc32_ELF_LINUX_H_
+#ifndef _LIBC_ppc32_ELF_LINUX_H_
+#define _LIBC_ppc32_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/ppc32/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/faddr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/include/libarch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ppc32_FADDR_H_
-#define LIBC_ppc32_FADDR_H_
+#ifndef _LIBC_ppc32_FADDR_H_
+#define _LIBC_ppc32_FADDR_H_
 
 #include <types/common.h>
Index: uspace/lib/c/arch/ppc32/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/fibril.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/include/libarch/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ppc32_FIBRIL_H_
-#define LIBC_ppc32_FIBRIL_H_
+#ifndef _LIBC_ppc32_FIBRIL_H_
+#define _LIBC_ppc32_FIBRIL_H_
 
 #include <stdint.h>
Index: uspace/lib/c/arch/ppc32/include/libarch/fibril_context.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/fibril_context.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/include/libarch/fibril_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,31 +27,31 @@
  */
 
-#ifndef LIBC_ARCH_FIBRIL_CONTEXT_H_
-#define LIBC_ARCH_FIBRIL_CONTEXT_H_
+#ifndef _LIBC_ARCH_FIBRIL_CONTEXT_H_
+#define _LIBC_ARCH_FIBRIL_CONTEXT_H_
 
-#define CONTEXT_OFFSET_SP   0x00
-#define CONTEXT_OFFSET_PC   0x04
-#define CONTEXT_OFFSET_TLS  0x08
-#define CONTEXT_OFFSET_R13  0x0c
-#define CONTEXT_OFFSET_R14  0x10
-#define CONTEXT_OFFSET_R15  0x14
-#define CONTEXT_OFFSET_R16  0x18
-#define CONTEXT_OFFSET_R17  0x1c
-#define CONTEXT_OFFSET_R18  0x20
-#define CONTEXT_OFFSET_R19  0x24
-#define CONTEXT_OFFSET_R20  0x28
-#define CONTEXT_OFFSET_R21  0x2c
-#define CONTEXT_OFFSET_R22  0x30
-#define CONTEXT_OFFSET_R23  0x34
-#define CONTEXT_OFFSET_R24  0x38
-#define CONTEXT_OFFSET_R25  0x3c
-#define CONTEXT_OFFSET_R26  0x40
-#define CONTEXT_OFFSET_R27  0x44
-#define CONTEXT_OFFSET_R28  0x48
-#define CONTEXT_OFFSET_R29  0x4c
-#define CONTEXT_OFFSET_R30  0x50
-#define CONTEXT_OFFSET_R31  0x54
-#define CONTEXT_OFFSET_CR   0x58
-#define CONTEXT_SIZE        0x5c
+#define __CONTEXT_OFFSET_SP   0x00
+#define __CONTEXT_OFFSET_PC   0x04
+#define __CONTEXT_OFFSET_TLS  0x08
+#define __CONTEXT_OFFSET_R13  0x0c
+#define __CONTEXT_OFFSET_R14  0x10
+#define __CONTEXT_OFFSET_R15  0x14
+#define __CONTEXT_OFFSET_R16  0x18
+#define __CONTEXT_OFFSET_R17  0x1c
+#define __CONTEXT_OFFSET_R18  0x20
+#define __CONTEXT_OFFSET_R19  0x24
+#define __CONTEXT_OFFSET_R20  0x28
+#define __CONTEXT_OFFSET_R21  0x2c
+#define __CONTEXT_OFFSET_R22  0x30
+#define __CONTEXT_OFFSET_R23  0x34
+#define __CONTEXT_OFFSET_R24  0x38
+#define __CONTEXT_OFFSET_R25  0x3c
+#define __CONTEXT_OFFSET_R26  0x40
+#define __CONTEXT_OFFSET_R27  0x44
+#define __CONTEXT_OFFSET_R28  0x48
+#define __CONTEXT_OFFSET_R29  0x4c
+#define __CONTEXT_OFFSET_R30  0x50
+#define __CONTEXT_OFFSET_R31  0x54
+#define __CONTEXT_OFFSET_CR   0x58
+#define __CONTEXT_SIZE        0x5c
 
 #ifndef __ASSEMBLER__
@@ -60,5 +60,5 @@
 #include <stdint.h>
 
-typedef struct context {
+typedef struct __context {
 	uint32_t sp;
 	uint32_t pc;
@@ -84,5 +84,5 @@
 	uint32_t r31;
 	uint32_t cr;
-} context_t;
+} __context_t;
 
 #endif
Index: uspace/lib/c/arch/ppc32/include/libarch/regname.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/regname.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/include/libarch/regname.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ppc32_REGNAME_H_
-#define LIBC_ppc32_REGNAME_H_
+#ifndef _LIBC_ppc32_REGNAME_H_
+#define _LIBC_ppc32_REGNAME_H_
 
 /* Condition Register Bit Fields */
Index: uspace/lib/c/arch/ppc32/include/libarch/rtld/dynamic.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/rtld/dynamic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/ppc32/include/libarch/rtld/dynamic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2019 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_ppc32_RTLD_DYNAMIC_H_
+#define _LIBC_ppc32_RTLD_DYNAMIC_H_
+
+typedef struct {
+	/* Empty. */
+} dyn_info_arch_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/ppc32/include/libarch/rtld/elf_dyn.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/rtld/elf_dyn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/ppc32/include/libarch/rtld/elf_dyn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2019 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_ppc32_RTLD_ELF_DYN_H_
+#define _LIBC_ppc32_RTLD_ELF_DYN_H_
+
+/*
+ * ppc32 dynamic relocation types
+ */
+
+#define R_PPC_ADDR32   1
+#define R_PPC_REL24    10
+#define R_PPC_COPY     19
+#define R_PPC_JMP_SLOT 21
+#define R_PPC_RELATIVE 22
+
+#define R_PPC_DTPMOD32 68
+#define R_PPC_DTPREL32 78
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/ppc32/include/libarch/rtld/module.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/ppc32/include/libarch/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_ppc32_RTLD_MODULE_H_
+#define _LIBC_ppc32_RTLD_MODULE_H_
+
+#include <elf/elf_mod.h>
+
+/** ELF module load flags */
+#define RTLD_MODULE_LDF 0
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/ppc32/include/libarch/stackarg.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/stackarg.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/include/libarch/stackarg.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_STACKARG_H_
-#define LIBC_STACKARG_H_
+#ifndef _LIBC_STACKARG_H_
+#define _LIBC_STACKARG_H_
 
 #endif
Index: uspace/lib/c/arch/ppc32/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/syscall.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/include/libarch/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_ppc32_SYSCALL_H_
-#define LIBC_ppc32_SYSCALL_H_
+#ifndef _LIBC_ppc32_SYSCALL_H_
+#define _LIBC_ppc32_SYSCALL_H_
 
 #define LIBARCH_SYSCALL_GENERIC
Index: uspace/lib/c/arch/ppc32/include/libarch/thread.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/thread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/include/libarch/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ppc32_THREAD_H_
-#define LIBC_ppc32_THREAD_H_
+#ifndef _LIBC_ppc32_THREAD_H_
+#define _LIBC_ppc32_THREAD_H_
 
 #endif
Index: uspace/lib/c/arch/ppc32/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/tls.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/include/libarch/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ppc32_TLS_H_
-#define LIBC_ppc32_TLS_H_
+#ifndef _LIBC_ppc32_TLS_H_
+#define _LIBC_ppc32_TLS_H_
 
 #define CONFIG_TLS_VARIANT_1
@@ -43,4 +43,6 @@
 
 typedef struct {
+	void **dtv;
+	void *pad;
 	void *fibril_data;
 } tcb_t;
Index: uspace/lib/c/arch/ppc32/src/fibril.S
===================================================================
--- uspace/lib/c/arch/ppc32/src/fibril.S	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/src/fibril.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,69 +33,69 @@
 #include <libarch/fibril_context.h>
 
-FUNCTION_BEGIN(__setjmp)
-	stw sp, CONTEXT_OFFSET_SP(r3)
-	stw r2, CONTEXT_OFFSET_TLS(r3)
-	stw r13, CONTEXT_OFFSET_R13(r3)
-	stw r14, CONTEXT_OFFSET_R14(r3)
-	stw r15, CONTEXT_OFFSET_R15(r3)
-	stw r16, CONTEXT_OFFSET_R16(r3)
-	stw r17, CONTEXT_OFFSET_R17(r3)
-	stw r18, CONTEXT_OFFSET_R18(r3)
-	stw r19, CONTEXT_OFFSET_R19(r3)
-	stw r20, CONTEXT_OFFSET_R20(r3)
-	stw r21, CONTEXT_OFFSET_R21(r3)
-	stw r22, CONTEXT_OFFSET_R22(r3)
-	stw r23, CONTEXT_OFFSET_R23(r3)
-	stw r24, CONTEXT_OFFSET_R24(r3)
-	stw r25, CONTEXT_OFFSET_R25(r3)
-	stw r26, CONTEXT_OFFSET_R26(r3)
-	stw r27, CONTEXT_OFFSET_R27(r3)
-	stw r28, CONTEXT_OFFSET_R28(r3)
-	stw r29, CONTEXT_OFFSET_R29(r3)
-	stw r30, CONTEXT_OFFSET_R30(r3)
-	stw r31, CONTEXT_OFFSET_R31(r3)
+FUNCTION_BEGIN(__context_save)
+	stw sp, __CONTEXT_OFFSET_SP(r3)
+	stw r2, __CONTEXT_OFFSET_TLS(r3)
+	stw r13, __CONTEXT_OFFSET_R13(r3)
+	stw r14, __CONTEXT_OFFSET_R14(r3)
+	stw r15, __CONTEXT_OFFSET_R15(r3)
+	stw r16, __CONTEXT_OFFSET_R16(r3)
+	stw r17, __CONTEXT_OFFSET_R17(r3)
+	stw r18, __CONTEXT_OFFSET_R18(r3)
+	stw r19, __CONTEXT_OFFSET_R19(r3)
+	stw r20, __CONTEXT_OFFSET_R20(r3)
+	stw r21, __CONTEXT_OFFSET_R21(r3)
+	stw r22, __CONTEXT_OFFSET_R22(r3)
+	stw r23, __CONTEXT_OFFSET_R23(r3)
+	stw r24, __CONTEXT_OFFSET_R24(r3)
+	stw r25, __CONTEXT_OFFSET_R25(r3)
+	stw r26, __CONTEXT_OFFSET_R26(r3)
+	stw r27, __CONTEXT_OFFSET_R27(r3)
+	stw r28, __CONTEXT_OFFSET_R28(r3)
+	stw r29, __CONTEXT_OFFSET_R29(r3)
+	stw r30, __CONTEXT_OFFSET_R30(r3)
+	stw r31, __CONTEXT_OFFSET_R31(r3)
 
 	mflr r4
-	stw r4, CONTEXT_OFFSET_PC(r3)
+	stw r4, __CONTEXT_OFFSET_PC(r3)
 
 	mfcr r4
-	stw r4, CONTEXT_OFFSET_CR(r3)
+	stw r4, __CONTEXT_OFFSET_CR(r3)
 
-	# __setjmp returns 0
+	# __context_save returns 0
 	li r3, 0
 	blr
-FUNCTION_END(__setjmp)
+FUNCTION_END(__context_save)
 
-FUNCTION_BEGIN(__longjmp)
-	lwz sp, CONTEXT_OFFSET_SP(r3)
-	lwz r2, CONTEXT_OFFSET_TLS(r3)
-	lwz r13, CONTEXT_OFFSET_R13(r3)
-	lwz r14, CONTEXT_OFFSET_R14(r3)
-	lwz r15, CONTEXT_OFFSET_R15(r3)
-	lwz r16, CONTEXT_OFFSET_R16(r3)
-	lwz r17, CONTEXT_OFFSET_R17(r3)
-	lwz r18, CONTEXT_OFFSET_R18(r3)
-	lwz r19, CONTEXT_OFFSET_R19(r3)
-	lwz r20, CONTEXT_OFFSET_R20(r3)
-	lwz r21, CONTEXT_OFFSET_R21(r3)
-	lwz r22, CONTEXT_OFFSET_R22(r3)
-	lwz r23, CONTEXT_OFFSET_R23(r3)
-	lwz r24, CONTEXT_OFFSET_R24(r3)
-	lwz r25, CONTEXT_OFFSET_R25(r3)
-	lwz r26, CONTEXT_OFFSET_R26(r3)
-	lwz r27, CONTEXT_OFFSET_R27(r3)
-	lwz r28, CONTEXT_OFFSET_R28(r3)
-	lwz r29, CONTEXT_OFFSET_R29(r3)
-	lwz r30, CONTEXT_OFFSET_R30(r3)
-	lwz r31, CONTEXT_OFFSET_R31(r3)
+FUNCTION_BEGIN(__context_restore)
+	lwz sp, __CONTEXT_OFFSET_SP(r3)
+	lwz r2, __CONTEXT_OFFSET_TLS(r3)
+	lwz r13, __CONTEXT_OFFSET_R13(r3)
+	lwz r14, __CONTEXT_OFFSET_R14(r3)
+	lwz r15, __CONTEXT_OFFSET_R15(r3)
+	lwz r16, __CONTEXT_OFFSET_R16(r3)
+	lwz r17, __CONTEXT_OFFSET_R17(r3)
+	lwz r18, __CONTEXT_OFFSET_R18(r3)
+	lwz r19, __CONTEXT_OFFSET_R19(r3)
+	lwz r20, __CONTEXT_OFFSET_R20(r3)
+	lwz r21, __CONTEXT_OFFSET_R21(r3)
+	lwz r22, __CONTEXT_OFFSET_R22(r3)
+	lwz r23, __CONTEXT_OFFSET_R23(r3)
+	lwz r24, __CONTEXT_OFFSET_R24(r3)
+	lwz r25, __CONTEXT_OFFSET_R25(r3)
+	lwz r26, __CONTEXT_OFFSET_R26(r3)
+	lwz r27, __CONTEXT_OFFSET_R27(r3)
+	lwz r28, __CONTEXT_OFFSET_R28(r3)
+	lwz r29, __CONTEXT_OFFSET_R29(r3)
+	lwz r30, __CONTEXT_OFFSET_R30(r3)
+	lwz r31, __CONTEXT_OFFSET_R31(r3)
 
-	lwz r5, CONTEXT_OFFSET_CR(r3)
+	lwz r5, __CONTEXT_OFFSET_CR(r3)
 	mtcr r5
 
-	lwz r5, CONTEXT_OFFSET_PC(r3)
+	lwz r5, __CONTEXT_OFFSET_PC(r3)
 	mtlr r5
 
-	# __longjmp returns second argument
+	# __context_restore returns second argument
 	mr r3, r4
 	blr
-FUNCTION_END(__longjmp)
+FUNCTION_END(__context_restore)
Index: uspace/lib/c/arch/ppc32/src/rtld/dynamic.c
===================================================================
--- uspace/lib/c/arch/ppc32/src/rtld/dynamic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/ppc32/src/rtld/dynamic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019 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 libcppc32
+ * @brief
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <rtld/elf_dyn.h>
+#include <rtld/dynamic.h>
+
+void dyn_parse_arch(elf_dyn_t *dp, size_t bias, dyn_info_t *info)
+{
+	(void) dp;
+	(void) bias;
+	(void) info;
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/ppc32/src/rtld/reloc.c
===================================================================
--- uspace/lib/c/arch/ppc32/src/rtld/reloc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/ppc32/src/rtld/reloc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,421 @@
+/*
+ * Copyright (c) 2019 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 libcppc32
+ * @brief
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <bitops.h>
+#include <smc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <str.h>
+
+#include <libarch/rtld/elf_dyn.h>
+#include <rtld/symbol.h>
+#include <rtld/rtld.h>
+#include <rtld/rtld_debug.h>
+#include <rtld/rtld_arch.h>
+
+static void plt_farcall_init(uint32_t *plt, uint32_t *);
+static void plt_entry_init(uint32_t *, uint32_t *, uint32_t *, uintptr_t);
+static uint32_t *plt_entry_ptr(uint32_t *, size_t);
+static size_t plt_entry_index(size_t);
+static uint16_t addr_ha(uint32_t);
+static uint16_t addr_l(uint32_t);
+
+void module_process_pre_arch(module_t *m)
+{
+	/* Unused */
+}
+
+/**
+ * Process (fixup) all relocations in a relocation table.
+ */
+void rel_table_process(module_t *m, elf_rel_t *rt, size_t rt_size)
+{
+	/* Unused */
+	(void)m;
+	(void)rt;
+	(void)rt_size;
+}
+
+/**
+ * Process (fixup) all relocations in a relocation table with explicit addends.
+ */
+void rela_table_process(module_t *m, elf_rela_t *rt, size_t rt_size)
+{
+	unsigned i;
+
+	size_t rt_entries;
+	size_t r_offset;
+	size_t r_addend;
+	elf_xword r_info;
+	unsigned rel_type;
+	elf_word sym_idx;
+	uintptr_t sym_addr;
+
+	elf_symbol_t *sym_table;
+	elf_symbol_t *sym;
+	uintptr_t *r_ptr;
+	uintptr_t sym_size;
+	char *str_tab;
+
+	elf_symbol_t *sym_def;
+	module_t *dest;
+	uint32_t *plt;
+	uint32_t *plt_datawords;
+	size_t jmp_slots;
+
+	DPRINTF("Count jump slots.\n");
+
+	rt_entries = rt_size / sizeof(elf_rela_t);
+
+	jmp_slots = 0;
+	for (i = 0; i < rt_entries; ++i) {
+		r_info = rt[i].r_info;
+		rel_type = ELF32_R_TYPE(r_info);
+
+		if (rel_type == R_PPC_JMP_SLOT)
+			++jmp_slots;
+	}
+
+	DPRINTF("Init farcall section\n");
+
+	plt = (uint32_t *)m->dyn.plt_got;
+
+	/* Table with addresses starts just after last PLT entry */
+	plt_datawords = plt_entry_ptr(plt, jmp_slots);
+
+	/* Init farcall section with reference to datawords table */
+	plt_farcall_init(plt, plt_datawords);
+
+	DPRINTF("parse relocation table\n");
+
+	sym_table = m->dyn.sym_tab;
+	str_tab = m->dyn.str_tab;
+
+	DPRINTF("rel table address: 0x%zx, entries: %zd\n", (uintptr_t)rt, rt_entries);
+
+	for (i = 0; i < rt_entries; ++i) {
+#if 0
+		DPRINTF("symbol %d: ", i);
+#endif
+		r_offset = rt[i].r_offset;
+		r_info = rt[i].r_info;
+		r_addend = rt[i].r_addend;
+
+		sym_idx = ELF32_R_SYM(r_info);
+		sym = &sym_table[sym_idx];
+
+#if 0
+		DPRINTF("name '%s', value 0x%x, size 0x%x\n",
+		    str_tab + sym->st_name,
+		    sym->st_value,
+		    sym->st_size);
+#endif
+		rel_type = ELF32_R_TYPE(r_info);
+		r_ptr = (uintptr_t *)(r_offset + m->bias);
+
+		if (sym->st_name != 0) {
+			DPRINTF("rel_type: %x, rel_offset: 0x%zx\n", rel_type, r_offset);
+			sym_def = symbol_def_find(str_tab + sym->st_name,
+			    m, ssf_none, &dest);
+			DPRINTF("dest name: '%s'\n", dest->dyn.soname);
+			DPRINTF("dest bias: 0x%zx\n", dest->bias);
+			if (sym_def) {
+				sym_addr = (uintptr_t)
+				    symbol_get_addr(sym_def, dest, NULL);
+				DPRINTF("symbol definition found, value=0x%zx addr=0x%zx\n", sym_def->st_value, sym_addr);
+			} else {
+				printf("Definition of '%s' not found.\n",
+				    str_tab + sym->st_name);
+				continue;
+			}
+		} else {
+			sym_addr = 0;
+			sym_def = NULL;
+
+			/*
+			 * DTPMOD with null st_name should return the index
+			 * of the current module.
+			 */
+			dest = m;
+		}
+
+		switch (rel_type) {
+		case R_PPC_ADDR32:
+			DPRINTF("fixup R_PPC_ADDR32 (S+A)\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, sym_addr);
+			*r_ptr = sym_addr + r_addend;
+			DPRINTF("OK\n");
+			break;
+		case R_PPC_REL24:
+			DPRINTF("fixup R_PPC_REL24 ((S+A-P) >> 2)\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr,
+			    (sym_addr + r_addend - (uintptr_t)r_ptr) >> 2);
+			*r_ptr = (sym_addr + r_addend - (uintptr_t)r_ptr) >> 2;
+			DPRINTF("OK\n");
+			break;
+		case R_PPC_COPY:
+			/*
+			 * Copy symbol data from shared object to specified
+			 * location. Need to find the 'source', i.e. the
+			 * other instance of the object than the one in the
+			 * executable program.
+			 */
+			DPRINTF("fixup R_PPC_COPY (s)\n");
+
+			sym_def = symbol_def_find(str_tab + sym->st_name,
+			    m, ssf_noexec, &dest);
+
+			if (sym_def) {
+				sym_addr = (uintptr_t)
+				    symbol_get_addr(sym_def, dest, NULL);
+			} else {
+				printf("Source definition of '%s' not found.\n",
+				    str_tab + sym->st_name);
+				continue;
+			}
+
+			sym_size = sym->st_size;
+			if (sym_size != sym_def->st_size) {
+#if 0
+				printf("Warning: Mismatched symbol sizes.\n");
+#endif
+				/* Take the lower value. */
+				if (sym_size > sym_def->st_size)
+					sym_size = sym_def->st_size;
+			}
+
+			memcpy(r_ptr, (const void *)sym_addr, sym_size);
+			DPRINTF("OK\n");
+			break;
+
+		case R_PPC_JMP_SLOT:
+			DPRINTF("fixup R_PPC_JMP_SLOT (S)\n");
+			DPRINTF("r_offset=0x%zx r_addend=0x%zx\n",
+			    r_offset, r_addend);
+
+			sym_def = symbol_def_find(str_tab + sym->st_name,
+			    m, ssf_noexec, &dest);
+
+			if (sym_def) {
+				sym_addr = (uintptr_t)
+				    symbol_get_addr(sym_def, dest, NULL);
+			} else {
+				printf("Source definition of '%s' not found.\n",
+				    str_tab + sym->st_name);
+				continue;
+			}
+
+			DPRINTF("sym_addr = 0x%zx\n", sym_addr);
+			DPRINTF("r_offset=0x%zx\n", r_offset);
+
+			/*
+			 * Fill PLT entry with jump to symbol address.
+			 */
+			plt_entry_init(plt, (uint32_t *)r_ptr, plt_datawords,
+			    sym_addr);
+
+			DPRINTF("OK\n");
+			break;
+
+		case R_PPC_RELATIVE:
+			DPRINTF("fixup R_PPC_RELATIVE (B+A)\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, m->bias + r_addend);
+			*r_ptr = m->bias + r_addend;
+			DPRINTF("OK\n");
+			break;
+
+		case R_PPC_DTPMOD32:
+			DPRINTF("fixup R_PPC_DTPMOD32\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, (size_t)dest->id);
+			*r_ptr = dest->id;
+			DPRINTF("OK\n");
+			break;
+
+		case R_PPC_DTPREL32:
+			DPRINTF("fixup R_PPC_DTPREL32\n"); /* XXXXX */
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, sym_def->st_value);
+			*r_ptr = sym_def->st_value + r_addend;
+			DPRINTF("OK\n");
+			break;
+
+		default:
+			printf("Error: Unknown relocation type %d\n",
+			    rel_type);
+			exit(1);
+		}
+
+	}
+}
+
+/** Init PLT farcall section. */
+static void plt_farcall_init(uint32_t *plt, uint32_t *plt_datawords)
+{
+	uint16_t hi;
+	uint16_t lo;
+	int i;
+
+	hi = addr_ha((uintptr_t)plt_datawords);
+	lo = addr_l((uintptr_t)plt_datawords);
+
+	plt[0] = 0x3d6b0000 | hi; /* addis %r11,% r11,. plt_datawords@ha */
+	plt[1] = 0x816b0000 | lo; /* lwz %r11, .plt_datawords@l(%r11) */
+	plt[2] = 0x7d6903a6;      /* mtctr %r11 */
+	plt[3] = 0x4e800420;      /* bctr */
+	plt[4] = 0x60000000;      /* nop */
+	plt[5] = 0x60000000;      /* nop */
+
+	smc_coherence(plt, 4 * 6);
+
+	for (i = 0; i < 6; i++)
+		DPRINTF("%p: farcall[%d] = %08zx\n", &plt[i], i, plt[i]);
+}
+
+/** Fill in PLT entry.
+ *
+ * Fill a PLT entry with PowerPC instructions to set table index and
+ * jump to the farcall section. Fill table entry with target address.
+ *
+ * @param plt Pointer to PLT
+ * @param plte Pointer to PLT entry to fill in
+ * @param datawords Address table
+ * @param ta Target address of the jump
+ */
+static void plt_entry_init(uint32_t *plt, uint32_t *plte, uint32_t *datawords,
+    uintptr_t ta)
+{
+	size_t index;
+	size_t woffset;
+	uint16_t i4index;
+	uint32_t btgt;
+
+	DPRINTF("plt_entry_init(plt=%p, plte=%p, datawords=%p, ta=0z%zx\n",
+	    plt, plte, datawords, ta);
+
+	/* Entry offset in words */
+	woffset = plte - plt;
+
+	/* Entry index */
+	index = plt_entry_index(woffset);
+
+	/* This only works for the first 2048 entries */
+	assert(index * 4 < 0x8000);
+	i4index = 4 * index;
+
+	/* Relative branch offset */
+	btgt = ((uint8_t *)plt - (uint8_t *)&plte[1]) & 0x03ffffff;
+
+	/* Write target address to table */
+	datawords[index] = ta;
+	DPRINTF("%p: datawords[%zu] = %08x\n", &datawords[index], index, ta);
+
+	plte[0] = 0x39600000 | i4index; /* li %r11, 4 * index */
+	plte[1] = 0x48000000 | btgt;    /* b .plt_farcall */
+
+	DPRINTF("%p: plte[0] = %08zx\n", &plte[0], plte[0]);
+	DPRINTF("%p: plte[1] = %08zx\n", &plte[1], plte[1]);
+
+	smc_coherence(plte, 4 * 2);
+}
+
+/** Determine PLT entry address.
+ *
+ * @param plt Start of PLT
+ * @param index PLT entry index
+ * @return Pointer to PLT entry
+ */
+static uint32_t *plt_entry_ptr(uint32_t *plt, size_t index)
+{
+	if (index < 8192)
+		return plt + 18 + 2 * index;
+	else
+		return plt + 18 + 2 * 8192 + 4 * (index - 8192);
+}
+
+/** Determine index of PLT entry from its word offset.
+ *
+ * @param woffset Offset of PLT entry in words
+ * @return PLT entry index
+ */
+static size_t plt_entry_index(size_t woffset)
+{
+	assert(woffset >= 18);
+	woffset -= 18;
+
+	if (woffset < 2 * 8192) {
+		assert((woffset & 0x1) == 0);
+		return woffset / 2;
+	} else {
+		assert((woffset & 0x3) == 0);
+		return (woffset - 2 * 8192) / 4;
+	}
+}
+
+/** Determine high bits of address.
+ *
+ * The lower bits are determined by @c addr_l function. The lower bits
+ * are considered to be a 16-bit signed integer.
+ *
+ * @param addr Address
+ * @return Higher bits of address
+ */
+static uint16_t addr_ha(uint32_t addr)
+{
+	int32_t la;
+
+	/* The lower part of the address is a signed 16-bit integer */
+	la = (int16_t)(addr & 0xffff);
+
+	/* Compute higher bits while compensating for the sign extension */
+	return (addr - la) >> 16;
+}
+
+/** Determine lower bits of address.
+ *
+ * The lower bits are considered to be 16-bit signed integer/immediate
+ * operand by the ISA, but we return them here as unsigned unmber so
+ * it can be easily incorporated into an instruction opcode.
+ *
+ * @param addr Address
+ * @return Lower bits of address cast as unsigned 16-bit integer
+ */
+static uint16_t addr_l(uint32_t addr)
+{
+	return (uint16_t) (addr & 0x0000ffff);
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/ppc32/src/syscall.c
===================================================================
--- uspace/lib/c/arch/ppc32/src/syscall.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/src/syscall.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -58,4 +58,10 @@
 	      "r" (__ppc32_reg_r8),
 	      "r" (__ppc32_reg_r9)
+	    :
+	      /*
+	       * Clobber memory too as some arguments might be
+	       * actually pointers.
+	       */
+	      "memory"
 	);
 
Index: uspace/lib/c/arch/ppc32/src/tls.c
===================================================================
--- uspace/lib/c/arch/ppc32/src/tls.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/src/tls.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,3 +1,4 @@
 /*
+ * Copyright (c) 2019 Jiri Svoboda
  * Copyright (c) 2006 Ondrej Palkovsky
  * All rights reserved.
@@ -36,4 +37,8 @@
 #include <stddef.h>
 
+#ifdef CONFIG_RTLD
+#include <rtld/rtld.h>
+#endif
+
 tcb_t *tls_alloc_arch(size_t size, size_t align)
 {
@@ -46,4 +51,32 @@
 }
 
+/*
+ * Rtld TLS support
+ */
+
+typedef struct {
+	unsigned long int ti_module;
+	unsigned long int ti_offset;
+} tls_index;
+
+int __tls_debug = 0;
+
+void *__tls_get_addr(tls_index *ti);
+
+void *__tls_get_addr(tls_index *ti)
+{
+	uint8_t *tls;
+
+#ifdef CONFIG_RTLD
+	if (runtime_env != NULL) {
+		return rtld_tls_get_addr(runtime_env, __tcb_get(),
+		    ti->ti_module, ti->ti_offset) + 0x8000;
+	}
+#endif
+	/* Get address of static TLS block */
+	tls = tls_get();
+	return tls + ti->ti_offset + 0x8000;
+}
+
 /** @}
  */
Index: uspace/lib/c/arch/riscv64/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/config.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/riscv64/include/libarch/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_riscv64_CONFIG_H_
-#define LIBC_riscv64_CONFIG_H_
+#ifndef _LIBC_riscv64_CONFIG_H_
+#define _LIBC_riscv64_CONFIG_H_
 
 #define PAGE_WIDTH  12
Index: uspace/lib/c/arch/riscv64/include/libarch/ddi.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/ddi.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/riscv64/include/libarch/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,6 +30,6 @@
  */
 
-#ifndef LIBC_riscv64_DDI_H_
-#define LIBC_riscv64_DDI_H_
+#ifndef _LIBC_riscv64_DDI_H_
+#define _LIBC_riscv64_DDI_H_
 
 #include <ddi.h>
Index: uspace/lib/c/arch/riscv64/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/elf_linux.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/riscv64/include/libarch/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_riscv64_ELF_LINUX_H_
-#define LIBC_riscv64_ELF_LINUX_H_
+#ifndef _LIBC_riscv64_ELF_LINUX_H_
+#define _LIBC_riscv64_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/riscv64/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/faddr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/riscv64/include/libarch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_riscv64_FADDR_H_
-#define LIBC_riscv64_FADDR_H_
+#ifndef _LIBC_riscv64_FADDR_H_
+#define _LIBC_riscv64_FADDR_H_
 
 #include <types/common.h>
Index: uspace/lib/c/arch/riscv64/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/fibril.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/riscv64/include/libarch/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_riscv64_FIBRIL_H_
-#define LIBC_riscv64_FIBRIL_H_
+#ifndef _LIBC_riscv64_FIBRIL_H_
+#define _LIBC_riscv64_FIBRIL_H_
 
 #include <stdint.h>
Index: uspace/lib/c/arch/riscv64/include/libarch/fibril_context.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/fibril_context.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/riscv64/include/libarch/fibril_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,41 +27,41 @@
  */
 
-#ifndef LIBC_ARCH_FIBRIL_CONTEXT_H_
-#define LIBC_ARCH_FIBRIL_CONTEXT_H_
+#ifndef _LIBC_ARCH_FIBRIL_CONTEXT_H_
+#define _LIBC_ARCH_FIBRIL_CONTEXT_H_
 
-#define CONTEXT_OFFSET_SP   0x00
-#define CONTEXT_OFFSET_PC   0x08
-#define CONTEXT_OFFSET_ZERO 0x10
-#define CONTEXT_OFFSET_RA   0x18
-#define CONTEXT_OFFSET_X3   0x20
-#define CONTEXT_OFFSET_X4   0x28
-#define CONTEXT_OFFSET_X5   0x30
-#define CONTEXT_OFFSET_X6   0x38
-#define CONTEXT_OFFSET_X7   0x40
-#define CONTEXT_OFFSET_X8   0x48
-#define CONTEXT_OFFSET_X9   0x50
-#define CONTEXT_OFFSET_X10  0x58
-#define CONTEXT_OFFSET_X11  0x60
-#define CONTEXT_OFFSET_X12  0x68
-#define CONTEXT_OFFSET_X13  0x70
-#define CONTEXT_OFFSET_X14  0x78
-#define CONTEXT_OFFSET_X15  0x80
-#define CONTEXT_OFFSET_X16  0x88
-#define CONTEXT_OFFSET_X17  0x90
-#define CONTEXT_OFFSET_X18  0x98
-#define CONTEXT_OFFSET_X19  0xa0
-#define CONTEXT_OFFSET_X20  0xa8
-#define CONTEXT_OFFSET_X21  0xb0
-#define CONTEXT_OFFSET_X22  0xb8
-#define CONTEXT_OFFSET_X23  0xc0
-#define CONTEXT_OFFSET_X24  0xc8
-#define CONTEXT_OFFSET_X25  0xd0
-#define CONTEXT_OFFSET_X26  0xd8
-#define CONTEXT_OFFSET_X27  0xe0
-#define CONTEXT_OFFSET_X28  0xe8
-#define CONTEXT_OFFSET_X29  0xf0
-#define CONTEXT_OFFSET_X30  0xf8
-#define CONTEXT_OFFSET_X31  0x100
-#define CONTEXT_SIZE        0x108
+#define __CONTEXT_OFFSET_SP   0x00
+#define __CONTEXT_OFFSET_PC   0x08
+#define __CONTEXT_OFFSET_ZERO 0x10
+#define __CONTEXT_OFFSET_RA   0x18
+#define __CONTEXT_OFFSET_X3   0x20
+#define __CONTEXT_OFFSET_X4   0x28
+#define __CONTEXT_OFFSET_X5   0x30
+#define __CONTEXT_OFFSET_X6   0x38
+#define __CONTEXT_OFFSET_X7   0x40
+#define __CONTEXT_OFFSET_X8   0x48
+#define __CONTEXT_OFFSET_X9   0x50
+#define __CONTEXT_OFFSET_X10  0x58
+#define __CONTEXT_OFFSET_X11  0x60
+#define __CONTEXT_OFFSET_X12  0x68
+#define __CONTEXT_OFFSET_X13  0x70
+#define __CONTEXT_OFFSET_X14  0x78
+#define __CONTEXT_OFFSET_X15  0x80
+#define __CONTEXT_OFFSET_X16  0x88
+#define __CONTEXT_OFFSET_X17  0x90
+#define __CONTEXT_OFFSET_X18  0x98
+#define __CONTEXT_OFFSET_X19  0xa0
+#define __CONTEXT_OFFSET_X20  0xa8
+#define __CONTEXT_OFFSET_X21  0xb0
+#define __CONTEXT_OFFSET_X22  0xb8
+#define __CONTEXT_OFFSET_X23  0xc0
+#define __CONTEXT_OFFSET_X24  0xc8
+#define __CONTEXT_OFFSET_X25  0xd0
+#define __CONTEXT_OFFSET_X26  0xd8
+#define __CONTEXT_OFFSET_X27  0xe0
+#define __CONTEXT_OFFSET_X28  0xe8
+#define __CONTEXT_OFFSET_X29  0xf0
+#define __CONTEXT_OFFSET_X30  0xf8
+#define __CONTEXT_OFFSET_X31  0x100
+#define __CONTEXT_SIZE        0x108
 
 #ifndef __ASSEMBLER__
@@ -75,5 +75,5 @@
  */
 
-typedef struct context {
+typedef struct __context {
 	uint64_t sp;
 	uint64_t pc;
@@ -109,5 +109,5 @@
 	uint64_t x30;
 	uint64_t x31;
-} context_t;
+} __context_t;
 
 #endif
Index: uspace/lib/c/arch/riscv64/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/syscall.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/riscv64/include/libarch/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_riscv64_SYSCALL_H_
-#define LIBC_riscv64_SYSCALL_H_
+#ifndef _LIBC_riscv64_SYSCALL_H_
+#define _LIBC_riscv64_SYSCALL_H_
 
 #include <stdint.h>
Index: uspace/lib/c/arch/riscv64/include/libarch/thread.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/thread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/riscv64/include/libarch/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_riscv64_THREAD_H_
-#define LIBC_riscv64_THREAD_H_
+#ifndef _LIBC_riscv64_THREAD_H_
+#define _LIBC_riscv64_THREAD_H_
 
 #endif
Index: uspace/lib/c/arch/riscv64/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/tls.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/riscv64/include/libarch/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_riscv64_TLS_H_
-#define LIBC_riscv64_TLS_H_
+#ifndef _LIBC_riscv64_TLS_H_
+#define _LIBC_riscv64_TLS_H_
 
 #define CONFIG_TLS_VARIANT_2
Index: uspace/lib/c/arch/riscv64/src/fibril.c
===================================================================
--- uspace/lib/c/arch/riscv64/src/fibril.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/riscv64/src/fibril.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,10 +33,10 @@
 #include <stdbool.h>
 
-int __setjmp(context_t *ctx)
+int __context_save(__context_t *ctx)
 {
 	return 0;
 }
 
-void __longjmp(context_t *ctx, int ret)
+void __context_restore(__context_t *ctx, int ret)
 {
 	while (true)
Index: uspace/lib/c/arch/sparc64/Makefile.common
===================================================================
--- uspace/lib/c/arch/sparc64/Makefile.common	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/Makefile.common	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -52,3 +52,6 @@
 ifeq ($(PROCESSOR),sun4v)
 	DEFS += -DSUN4V
+	COMMON_CFLAGS += -Wl,-z,max-page-size=0x2000
+else
+	COMMON_CFLAGS += -Wl,-z,max-page-size=0x4000
 endif
Index: uspace/lib/c/arch/sparc64/Makefile.inc
===================================================================
--- uspace/lib/c/arch/sparc64/Makefile.inc	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,5 +33,7 @@
 	arch/$(UARCH)/src/tls.c \
 	arch/$(UARCH)/src/stacktrace.c \
-	arch/$(UARCH)/src/stacktrace_asm.S
+	arch/$(UARCH)/src/stacktrace_asm.S \
+	arch/$(UARCH)/src/rtld/dynamic.c \
+	arch/$(UARCH)/src/rtld/reloc.c
 
 ARCH_AUTOCHECK_HEADERS = \
Index: uspace/lib/c/arch/sparc64/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/config.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/include/libarch/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_sparc64_CONFIG_H_
-#define LIBC_sparc64_CONFIG_H_
+#ifndef _LIBC_sparc64_CONFIG_H_
+#define _LIBC_sparc64_CONFIG_H_
 
 #if defined (SUN4U)
Index: uspace/lib/c/arch/sparc64/include/libarch/ddi.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/ddi.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/include/libarch/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_sparc64_DDI_H_
-#define LIBC_sparc64_DDI_H_
+#ifndef _LIBC_sparc64_DDI_H_
+#define _LIBC_sparc64_DDI_H_
 
 #include <barrier.h>
Index: uspace/lib/c/arch/sparc64/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/elf_linux.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/include/libarch/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_sparc64_ELF_LINUX_H_
-#define LIBC_sparc64_ELF_LINUX_H_
+#ifndef _LIBC_sparc64_ELF_LINUX_H_
+#define _LIBC_sparc64_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/sparc64/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/faddr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/include/libarch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_sparc64_FADDR_H_
-#define LIBC_sparc64_FADDR_H_
+#ifndef _LIBC_sparc64_FADDR_H_
+#define _LIBC_sparc64_FADDR_H_
 
 #include <types/common.h>
Index: uspace/lib/c/arch/sparc64/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/fibril.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/include/libarch/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_sparc64_FIBRIL_H_
-#define LIBC_sparc64_FIBRIL_H_
+#ifndef _LIBC_sparc64_FIBRIL_H_
+#define _LIBC_sparc64_FIBRIL_H_
 
 #include <libarch/stack.h>
Index: uspace/lib/c/arch/sparc64/include/libarch/fibril_context.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/fibril_context.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/include/libarch/fibril_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,27 +27,27 @@
  */
 
-#ifndef LIBC_ARCH_FIBRIL_CONTEXT_H_
-#define LIBC_ARCH_FIBRIL_CONTEXT_H_
+#ifndef _LIBC_ARCH_FIBRIL_CONTEXT_H_
+#define _LIBC_ARCH_FIBRIL_CONTEXT_H_
 
-#define CONTEXT_OFFSET_SP  0x00
-#define CONTEXT_OFFSET_PC  0x08
-#define CONTEXT_OFFSET_I0  0x10
-#define CONTEXT_OFFSET_I1  0x18
-#define CONTEXT_OFFSET_I2  0x20
-#define CONTEXT_OFFSET_I3  0x28
-#define CONTEXT_OFFSET_I4  0x30
-#define CONTEXT_OFFSET_I5  0x38
-#define CONTEXT_OFFSET_FP  0x40
-#define CONTEXT_OFFSET_I7  0x48
-#define CONTEXT_OFFSET_L0  0x50
-#define CONTEXT_OFFSET_L1  0x58
-#define CONTEXT_OFFSET_L2  0x60
-#define CONTEXT_OFFSET_L3  0x68
-#define CONTEXT_OFFSET_L4  0x70
-#define CONTEXT_OFFSET_L5  0x78
-#define CONTEXT_OFFSET_L6  0x80
-#define CONTEXT_OFFSET_L7  0x88
-#define CONTEXT_OFFSET_TP  0x90
-#define CONTEXT_SIZE       0x98
+#define __CONTEXT_OFFSET_SP  0x00
+#define __CONTEXT_OFFSET_PC  0x08
+#define __CONTEXT_OFFSET_I0  0x10
+#define __CONTEXT_OFFSET_I1  0x18
+#define __CONTEXT_OFFSET_I2  0x20
+#define __CONTEXT_OFFSET_I3  0x28
+#define __CONTEXT_OFFSET_I4  0x30
+#define __CONTEXT_OFFSET_I5  0x38
+#define __CONTEXT_OFFSET_FP  0x40
+#define __CONTEXT_OFFSET_I7  0x48
+#define __CONTEXT_OFFSET_L0  0x50
+#define __CONTEXT_OFFSET_L1  0x58
+#define __CONTEXT_OFFSET_L2  0x60
+#define __CONTEXT_OFFSET_L3  0x68
+#define __CONTEXT_OFFSET_L4  0x70
+#define __CONTEXT_OFFSET_L5  0x78
+#define __CONTEXT_OFFSET_L6  0x80
+#define __CONTEXT_OFFSET_L7  0x88
+#define __CONTEXT_OFFSET_TP  0x90
+#define __CONTEXT_SIZE       0x98
 
 #ifndef __ASSEMBLER__
@@ -56,5 +56,5 @@
 #include <stdint.h>
 
-typedef struct context {
+typedef struct __context {
 	uintptr_t sp;  // %o6
 	uintptr_t pc;  // %o7
@@ -76,5 +76,5 @@
 	uint64_t l7;
 	uint64_t tp;  // %g7
-} context_t;
+} __context_t;
 
 #endif
Index: uspace/lib/c/arch/sparc64/include/libarch/rtld/dynamic.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/rtld/dynamic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/sparc64/include/libarch/rtld/dynamic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2019 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 generic
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_sparc64_RTLD_DYNAMIC_H_
+#define _LIBC_sparc64_RTLD_DYNAMIC_H_
+
+typedef struct {
+	/* Empty. */
+} dyn_info_arch_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc64/include/libarch/rtld/elf_dyn.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/rtld/elf_dyn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/sparc64/include/libarch/rtld/elf_dyn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019 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 generic
+ * @{
+ */
+/** @file sparc64 dynamic relocation types
+ */
+
+#ifndef _LIBC_sparc64_RTLD_ELF_DYN_H_
+#define _LIBC_sparc64_RTLD_ELF_DYN_H_
+
+#define R_SPARC_COPY		19
+#define R_SPARC_GLOB_DAT	20
+#define R_SPARC_JMP_SLOT	21
+#define R_SPARC_RELATIVE	22
+#define R_SPARC_64		32
+#define R_SPARC_TLS_DTPMOD64	75
+#define R_SPARC_TLS_DTPOFF64	77
+#define R_SPARC_TLS_TPOFF64	79
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc64/include/libarch/rtld/module.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/sparc64/include/libarch/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_sparc64_RTLD_MODULE_H_
+#define _LIBC_sparc64_RTLD_MODULE_H_
+
+#include <elf/elf_mod.h>
+
+/** ELF module load flags */
+#define RTLD_MODULE_LDF 0
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc64/include/libarch/stack.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/stack.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/include/libarch/stack.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_sparc64_STACK_H_
-#define LIBC_sparc64_STACK_H_
+#ifndef _LIBC_sparc64_STACK_H_
+#define _LIBC_sparc64_STACK_H_
 
 #define STACK_ITEM_SIZE			8
Index: uspace/lib/c/arch/sparc64/include/libarch/stackarg.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/stackarg.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/include/libarch/stackarg.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_sparc64_STACKARG_H_
-#define LIBC_sparc64_STACKARG_H_
+#ifndef _LIBC_sparc64_STACKARG_H_
+#define _LIBC_sparc64_STACKARG_H_
 
 #endif
Index: uspace/lib/c/arch/sparc64/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/syscall.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/include/libarch/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_sparc64_SYSCALL_H_
-#define LIBC_sparc64_SYSCALL_H_
+#ifndef _LIBC_sparc64_SYSCALL_H_
+#define _LIBC_sparc64_SYSCALL_H_
 
 #include <stdint.h>
Index: uspace/lib/c/arch/sparc64/include/libarch/thread.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/thread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/include/libarch/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -32,6 +32,6 @@
  */
 
-#ifndef LIBC_sparc64_THREAD_H_
-#define LIBC_sparc64_THREAD_H_
+#ifndef _LIBC_sparc64_THREAD_H_
+#define _LIBC_sparc64_THREAD_H_
 
 #endif
Index: uspace/lib/c/arch/sparc64/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/tls.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/include/libarch/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -36,6 +36,6 @@
  */
 
-#ifndef LIBC_sparc64_TLS_H_
-#define LIBC_sparc64_TLS_H_
+#ifndef _LIBC_sparc64_TLS_H_
+#define _LIBC_sparc64_TLS_H_
 
 #define CONFIG_TLS_VARIANT_2
@@ -46,4 +46,6 @@
 	void *self;
 	void *fibril_data;
+	void **dtv;
+	void *pad;
 } tcb_t;
 
Index: uspace/lib/c/arch/sparc64/src/fibril.S
===================================================================
--- uspace/lib/c/arch/sparc64/src/fibril.S	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/src/fibril.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -32,33 +32,33 @@
 .text
 
-FUNCTION_BEGIN(__setjmp)
+FUNCTION_BEGIN(__context_save)
 	#
 	# We rely on the kernel to flush our active register windows to memory
 	# should a thread switch occur.
 	#
-	stx %sp, [%o0 + CONTEXT_OFFSET_SP]
-	stx %o7, [%o0 + CONTEXT_OFFSET_PC]
-	stx %i0, [%o0 + CONTEXT_OFFSET_I0]
-	stx %i1, [%o0 + CONTEXT_OFFSET_I1]
-	stx %i2, [%o0 + CONTEXT_OFFSET_I2]
-	stx %i3, [%o0 + CONTEXT_OFFSET_I3]
-	stx %i4, [%o0 + CONTEXT_OFFSET_I4]
-	stx %i5, [%o0 + CONTEXT_OFFSET_I5]
-	stx %fp, [%o0 + CONTEXT_OFFSET_FP]
-	stx %i7, [%o0 + CONTEXT_OFFSET_I7]
-	stx %l0, [%o0 + CONTEXT_OFFSET_L0]
-	stx %l1, [%o0 + CONTEXT_OFFSET_L1]
-	stx %l2, [%o0 + CONTEXT_OFFSET_L2]
-	stx %l3, [%o0 + CONTEXT_OFFSET_L3]
-	stx %l4, [%o0 + CONTEXT_OFFSET_L4]
-	stx %l5, [%o0 + CONTEXT_OFFSET_L5]
-	stx %l6, [%o0 + CONTEXT_OFFSET_L6]
-	stx %l7, [%o0 + CONTEXT_OFFSET_L7]
-	stx %g7, [%o0 + CONTEXT_OFFSET_TP]
+	stx %sp, [%o0 + __CONTEXT_OFFSET_SP]
+	stx %o7, [%o0 + __CONTEXT_OFFSET_PC]
+	stx %i0, [%o0 + __CONTEXT_OFFSET_I0]
+	stx %i1, [%o0 + __CONTEXT_OFFSET_I1]
+	stx %i2, [%o0 + __CONTEXT_OFFSET_I2]
+	stx %i3, [%o0 + __CONTEXT_OFFSET_I3]
+	stx %i4, [%o0 + __CONTEXT_OFFSET_I4]
+	stx %i5, [%o0 + __CONTEXT_OFFSET_I5]
+	stx %fp, [%o0 + __CONTEXT_OFFSET_FP]
+	stx %i7, [%o0 + __CONTEXT_OFFSET_I7]
+	stx %l0, [%o0 + __CONTEXT_OFFSET_L0]
+	stx %l1, [%o0 + __CONTEXT_OFFSET_L1]
+	stx %l2, [%o0 + __CONTEXT_OFFSET_L2]
+	stx %l3, [%o0 + __CONTEXT_OFFSET_L3]
+	stx %l4, [%o0 + __CONTEXT_OFFSET_L4]
+	stx %l5, [%o0 + __CONTEXT_OFFSET_L5]
+	stx %l6, [%o0 + __CONTEXT_OFFSET_L6]
+	stx %l7, [%o0 + __CONTEXT_OFFSET_L7]
+	stx %g7, [%o0 + __CONTEXT_OFFSET_TP]
 	retl
-	mov 0, %o0		! __setjmp returns 0
-FUNCTION_END(__setjmp)
+	mov 0, %o0		! __context_save returns 0
+FUNCTION_END(__context_save)
 
-FUNCTION_BEGIN(__longjmp)
+FUNCTION_BEGIN(__context_restore)
 	#
 	# Flush all active windows.
@@ -69,24 +69,24 @@
 	flushw
 
-	ldx [%o0 + CONTEXT_OFFSET_SP], %sp
-	ldx [%o0 + CONTEXT_OFFSET_PC], %o7
-	ldx [%o0 + CONTEXT_OFFSET_I0], %i0
-	ldx [%o0 + CONTEXT_OFFSET_I1], %i1
-	ldx [%o0 + CONTEXT_OFFSET_I2], %i2
-	ldx [%o0 + CONTEXT_OFFSET_I3], %i3
-	ldx [%o0 + CONTEXT_OFFSET_I4], %i4
-	ldx [%o0 + CONTEXT_OFFSET_I5], %i5
-	ldx [%o0 + CONTEXT_OFFSET_FP], %fp
-	ldx [%o0 + CONTEXT_OFFSET_I7], %i7
-	ldx [%o0 + CONTEXT_OFFSET_L0], %l0
-	ldx [%o0 + CONTEXT_OFFSET_L1], %l1
-	ldx [%o0 + CONTEXT_OFFSET_L2], %l2
-	ldx [%o0 + CONTEXT_OFFSET_L3], %l3
-	ldx [%o0 + CONTEXT_OFFSET_L4], %l4
-	ldx [%o0 + CONTEXT_OFFSET_L5], %l5
-	ldx [%o0 + CONTEXT_OFFSET_L6], %l6
-	ldx [%o0 + CONTEXT_OFFSET_L7], %l7
-	ldx [%o0 + CONTEXT_OFFSET_TP], %g7
+	ldx [%o0 + __CONTEXT_OFFSET_SP], %sp
+	ldx [%o0 + __CONTEXT_OFFSET_PC], %o7
+	ldx [%o0 + __CONTEXT_OFFSET_I0], %i0
+	ldx [%o0 + __CONTEXT_OFFSET_I1], %i1
+	ldx [%o0 + __CONTEXT_OFFSET_I2], %i2
+	ldx [%o0 + __CONTEXT_OFFSET_I3], %i3
+	ldx [%o0 + __CONTEXT_OFFSET_I4], %i4
+	ldx [%o0 + __CONTEXT_OFFSET_I5], %i5
+	ldx [%o0 + __CONTEXT_OFFSET_FP], %fp
+	ldx [%o0 + __CONTEXT_OFFSET_I7], %i7
+	ldx [%o0 + __CONTEXT_OFFSET_L0], %l0
+	ldx [%o0 + __CONTEXT_OFFSET_L1], %l1
+	ldx [%o0 + __CONTEXT_OFFSET_L2], %l2
+	ldx [%o0 + __CONTEXT_OFFSET_L3], %l3
+	ldx [%o0 + __CONTEXT_OFFSET_L4], %l4
+	ldx [%o0 + __CONTEXT_OFFSET_L5], %l5
+	ldx [%o0 + __CONTEXT_OFFSET_L6], %l6
+	ldx [%o0 + __CONTEXT_OFFSET_L7], %l7
+	ldx [%o0 + __CONTEXT_OFFSET_TP], %g7
 	retl
-	mov %o1, %o0	! __longjmp returns second argument
-FUNCTION_END(__longjmp)
+	mov %o1, %o0	! __context_restore returns second argument
+FUNCTION_END(__context_restore)
Index: uspace/lib/c/arch/sparc64/src/rtld/dynamic.c
===================================================================
--- uspace/lib/c/arch/sparc64/src/rtld/dynamic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/sparc64/src/rtld/dynamic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019 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 libcsparc64
+ * @brief
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <rtld/elf_dyn.h>
+#include <rtld/dynamic.h>
+
+void dyn_parse_arch(elf_dyn_t *dp, size_t bias, dyn_info_t *info)
+{
+	(void) dp;
+	(void) bias;
+	(void) info;
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc64/src/rtld/reloc.c
===================================================================
--- uspace/lib/c/arch/sparc64/src/rtld/reloc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/sparc64/src/rtld/reloc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2019 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 libcsparc64
+ * @brief
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <bitops.h>
+#include <mem.h>
+#include <smc.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <libarch/rtld/elf_dyn.h>
+#include <rtld/symbol.h>
+#include <rtld/rtld.h>
+#include <rtld/rtld_debug.h>
+#include <rtld/rtld_arch.h>
+
+static void fill_plt_entry_generic(uint32_t *, uintptr_t);
+
+void module_process_pre_arch(module_t *m)
+{
+	/* Unused */
+}
+
+/**
+ * Process (fixup) all relocations in a relocation table with implicit addends.
+ */
+void rel_table_process(module_t *m, elf_rel_t *rt, size_t rt_size)
+{
+
+	DPRINTF("rel table address: 0x%zx, size: %zd\n", (uintptr_t)rt, rt_size);
+	/* Unused */
+	(void)m;
+	(void)rt;
+	(void)rt_size;
+}
+
+/**
+ * Process (fixup) all relocations in a relocation table with explicit addends.
+ */
+void rela_table_process(module_t *m, elf_rela_t *rt, size_t rt_size)
+{
+	unsigned i;
+
+	size_t rt_entries;
+	size_t r_offset;
+	size_t r_addend;
+	elf_xword r_info;
+	unsigned rel_type;
+	elf_word sym_idx;
+	uintptr_t sym_addr;
+
+	elf_symbol_t *sym_table;
+	elf_symbol_t *sym;
+	uintptr_t *r_ptr;
+	uintptr_t sym_size;
+	char *str_tab;
+
+	elf_symbol_t *sym_def;
+	module_t *dest;
+	uint32_t *plt;
+
+	DPRINTF("parse relocation table\n");
+
+	sym_table = m->dyn.sym_tab;
+	rt_entries = rt_size / sizeof(elf_rela_t);
+	str_tab = m->dyn.str_tab;
+
+	plt = (uint32_t *)m->dyn.plt_got;
+
+	DPRINTF("rel table address: 0x%zx, entries: %zd\n", (uintptr_t)rt, rt_entries);
+
+	for (i = 0; i < rt_entries; ++i) {
+#if 0
+		DPRINTF("symbol %d: ", i);
+#endif
+		r_offset = rt[i].r_offset;
+		r_info = rt[i].r_info;
+		r_addend = rt[i].r_addend;
+
+		sym_idx = ELF64_R_SYM(r_info);
+		sym = &sym_table[sym_idx];
+
+#if 0
+		DPRINTF("name '%s', value 0x%x, size 0x%x\n",
+		    str_tab + sym->st_name,
+		    sym->st_value,
+		    sym->st_size);
+#endif
+		rel_type = ELF64_R_TYPE(r_info);
+		r_ptr = (uintptr_t *)(r_offset + m->bias);
+
+		if (sym->st_name != 0) {
+			DPRINTF("rel_type: %x, rel_offset: 0x%zx\n", rel_type, r_offset);
+			sym_def = symbol_def_find(str_tab + sym->st_name,
+			    m, ssf_none, &dest);
+			DPRINTF("dest name: '%s'\n", dest->dyn.soname);
+			DPRINTF("dest bias: 0x%zx\n", dest->bias);
+			if (sym_def) {
+				sym_addr = (uintptr_t)
+				    symbol_get_addr(sym_def, dest, NULL);
+				DPRINTF("symbol definition found, value=0x%zx addr=0x%zx\n", sym_def->st_value, sym_addr);
+			} else {
+				printf("Definition of '%s' not found.\n",
+				    str_tab + sym->st_name);
+				continue;
+			}
+		} else {
+			sym_addr = 0;
+			sym_def = NULL;
+
+			/*
+			 * DTPMOD with null st_name should return the index
+			 * of the current module.
+			 */
+			dest = m;
+		}
+
+		switch (rel_type) {
+		case R_SPARC_COPY:
+			/*
+			 * Copy symbol data from shared object to specified
+			 * location. Need to find the 'source', i.e. the
+			 * other instance of the object than the one in the
+			 * executable program.
+			 */
+			DPRINTF("fixup R_SPARC_COPY (s)\n");
+
+			sym_def = symbol_def_find(str_tab + sym->st_name,
+			    m, ssf_noexec, &dest);
+
+			if (sym_def) {
+				sym_addr = (uintptr_t)
+				    symbol_get_addr(sym_def, dest, NULL);
+			} else {
+				printf("Source definition of '%s' not found.\n",
+				    str_tab + sym->st_name);
+				continue;
+			}
+
+			sym_size = sym->st_size;
+			if (sym_size != sym_def->st_size) {
+				printf("Warning: Mismatched symbol sizes.\n");
+				/* Take the lower value. */
+				if (sym_size > sym_def->st_size)
+					sym_size = sym_def->st_size;
+			}
+
+			memcpy(r_ptr, (const void *)sym_addr, sym_size);
+			DPRINTF("OK\n");
+			break;
+
+		case R_SPARC_GLOB_DAT:
+			DPRINTF("fixup R_SPARC_GLOB_DAT (S+A)\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, sym_addr);
+			*r_ptr = sym_addr + r_addend;
+			DPRINTF("OK\n");
+			break;
+
+		case R_SPARC_JMP_SLOT:
+			DPRINTF("fixup R_SPARC_JMP_SLOT (S)\n");
+			DPRINTF("r_offset=0x%zx r_addend=0x%zx\n",
+			    r_offset, r_addend);
+
+			sym_def = symbol_def_find(str_tab + sym->st_name,
+			    m, ssf_noexec, &dest);
+
+			if (sym_def) {
+				sym_addr = (uintptr_t)
+				    symbol_get_addr(sym_def, dest, NULL);
+			} else {
+				printf("Source definition of '%s' not found.\n",
+				    str_tab + sym->st_name);
+				continue;
+			}
+
+			DPRINTF("sym_addr = 0x%zx\n", sym_addr);
+			DPRINTF("r_offset=0x%zx\n", r_offset);
+
+			/*
+			 * Fill PLT entry with jump to symbol address.
+			 * r_ptr points to the PLT entry, sym_addr contains
+			 * address of the symbol.
+			 *
+			 * XXX This only works for the first 32768 entries.
+			 * If there are more, the layout is more complex.
+			 */
+			assert((uint32_t *)r_ptr - plt < 32768 * 8);
+			fill_plt_entry_generic((uint32_t *)r_ptr, sym_addr);
+			smc_coherence(r_ptr, 32);
+
+			DPRINTF("OK\n");
+			break;
+
+		case R_SPARC_RELATIVE:
+			DPRINTF("fixup R_SPARC_RELATIVE (B+A)\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, m->bias + r_addend);
+			*r_ptr = m->bias + r_addend;
+			DPRINTF("OK\n");
+			break;
+
+		case R_SPARC_64:
+			DPRINTF("fixup R_SPARC_64 (S+A)\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, sym_addr);
+			*r_ptr = sym_addr + r_addend;
+			DPRINTF("OK\n");
+			break;
+
+		case R_SPARC_TLS_DTPMOD64:
+			DPRINTF("fixup R_SPARC_TLS_DTPMOD64\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, (size_t)dest->id);
+			*r_ptr = dest->id;
+			DPRINTF("OK\n");
+			break;
+
+		case R_SPARC_TLS_DTPOFF64:
+			DPRINTF("fixup R_SPARC_TLS_DTPOFF64\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, sym_def->st_value);
+			*r_ptr = sym_def->st_value;
+			DPRINTF("OK\n");
+			break;
+
+		case R_SPARC_TLS_TPOFF64:
+			DPRINTF("fixup R_SPARC_TLS_TPOFF64\n");
+			*r_ptr = sym_def->st_value + dest->tpoff;
+			break;
+
+		default:
+			printf("Error: Unknown relocation type %d\n",
+			    rel_type);
+			exit(1);
+		}
+
+	}
+}
+
+/** Fill in generic PLT entry.
+ *
+ * Fill a PLT entry with SPARC instructions to jump to the specified
+ * address.
+ *
+ * @param plte Pointer to PLT entry to fill in
+ * @param ta Target address of the jump
+ */
+static void fill_plt_entry_generic(uint32_t *plte, uintptr_t ta)
+{
+	uint32_t hh, lm, hm, lo;
+
+	hh = BIT_RANGE_EXTRACT(uintptr_t, 63, 42, ta);
+	hm = BIT_RANGE_EXTRACT(uintptr_t, 41, 32, ta);
+	lm = BIT_RANGE_EXTRACT(uintptr_t, 31, 10, ta);
+	lo = BIT_RANGE_EXTRACT(uintptr_t, 9, 0, ta);
+
+	plte[0] = 0x01000000;      /* nop */
+	plte[1] = 0x03000000 | hh; /* sethi %hh(target), %g1 */
+	plte[2] = 0x0b000000 | lm; /* sethi %lm(target), %g5 */
+	plte[3] = 0x82106000 | hm; /* or %g1, %hm(target), %g1 */
+	plte[4] = 0x83287020;      /* sllx %g1, 32, %g1 */
+	plte[5] = 0x8a104005;      /* or %g1, %g5, %g5 */
+	plte[6] = 0x81c16000 | lo; /* jmpl %g5+lo(target),%g0 */
+	plte[7] = 0x01000000;      /* nop */
+
+	DPRINTF("Fill PTL entry at %p (target=0x%zx)\n",
+	    plte, ta);
+	for (unsigned i = 0; i < 8; i++) {
+		DPRINTF(" - [%d] = 0x%08x\n", i, plte[i]);
+	}
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc64/src/tls.c
===================================================================
--- uspace/lib/c/arch/sparc64/src/tls.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/src/tls.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,4 +38,8 @@
 #include <stddef.h>
 
+#ifdef CONFIG_RTLD
+#include <rtld/rtld.h>
+#endif
+
 tcb_t *tls_alloc_arch(size_t size, size_t align)
 {
@@ -48,4 +52,30 @@
 }
 
+/*
+ * Rtld TLS support
+ */
+
+typedef struct {
+	unsigned long int ti_module;
+	unsigned long int ti_offset;
+} tls_index;
+
+void *__tls_get_addr(tls_index *ti);
+
+void *__tls_get_addr(tls_index *ti)
+{
+	uint8_t *tls;
+
+#ifdef CONFIG_RTLD
+	if (runtime_env != NULL) {
+		return rtld_tls_get_addr(runtime_env, __tcb_get(),
+		    ti->ti_module, ti->ti_offset);
+	}
+#endif
+	/* Get address of static TLS block */
+	tls = tls_get();
+	return tls + ti->ti_offset;
+}
+
 /** @}
  */
Index: uspace/lib/c/doc/doxygroups.h
===================================================================
--- uspace/lib/c/doc/doxygroups.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/doc/doxygroups.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -17,4 +17,9 @@
 /**
  * @addtogroup libcarm32 arm32
+ * @ingroup libc
+ */
+
+/**
+ * @addtogroup libcarm64 arm64
  * @ingroup libc
  */
Index: uspace/lib/c/generic/adt/hash_table.c
===================================================================
--- uspace/lib/c/generic/adt/hash_table.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/adt/hash_table.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -245,5 +245,5 @@
  *
  */
-ht_link_t *hash_table_find(const hash_table_t *h, void *key)
+ht_link_t *hash_table_find(const hash_table_t *h, const void *key)
 {
 	assert(h && h->bucket);
@@ -303,9 +303,8 @@
  * @param key  Array of keys that will be compared against items of
  *             the hash table.
- * @param keys Number of keys in the 'key' array.
  *
  * @return Returns the number of removed items.
  */
-size_t hash_table_remove(hash_table_t *h, void *key)
+size_t hash_table_remove(hash_table_t *h, const void *key)
 {
 	assert(h && h->bucket);
Index: uspace/lib/c/generic/as.c
===================================================================
--- uspace/lib/c/generic/as.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/as.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -126,5 +126,5 @@
  *
  * @param      virt Virtual address to find mapping for.
- * @param[out] phys Physical adress.
+ * @param[out] phys Physical address.
  *
  * @return EOK on no error.
Index: uspace/lib/c/generic/async/client.c
===================================================================
--- uspace/lib/c/generic/async/client.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/async/client.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -95,10 +95,10 @@
  */
 
-#define LIBC_ASYNC_C_
+#define _LIBC_ASYNC_C_
 #include <ipc/ipc.h>
 #include <async.h>
 #include "../private/async.h"
 #include "../private/ns.h"
-#undef LIBC_ASYNC_C_
+#undef _LIBC_ASYNC_C_
 
 #include <ipc/irq.h>
@@ -216,5 +216,5 @@
 	fibril_rmutex_lock(&message_mutex);
 
-	msg->retval = IPC_GET_RETVAL(*data);
+	msg->retval = ipc_get_retval(data);
 
 	/* Copy data inside lock, just in case the call was detached */
@@ -249,5 +249,5 @@
  *
  */
-aid_t async_send_fast(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
+static aid_t async_send_fast(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
 {
@@ -289,5 +289,5 @@
  *
  */
-aid_t async_send_slow(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
+static aid_t async_send_slow(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
     ipc_call_t *dataptr)
@@ -310,4 +310,41 @@
 
 	return (aid_t) msg;
+}
+
+aid_t async_send_0(async_exch_t *exch, sysarg_t imethod, ipc_call_t *dataptr)
+{
+	return async_send_fast(exch, imethod, 0, 0, 0, 0, dataptr);
+}
+
+aid_t async_send_1(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
+    ipc_call_t *dataptr)
+{
+	return async_send_fast(exch, imethod, arg1, 0, 0, 0, dataptr);
+}
+
+aid_t async_send_2(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
+    sysarg_t arg2, ipc_call_t *dataptr)
+{
+	return async_send_fast(exch, imethod, arg1, arg2, 0, 0, dataptr);
+}
+
+aid_t async_send_3(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
+    sysarg_t arg2, sysarg_t arg3, ipc_call_t *dataptr)
+{
+	return async_send_fast(exch, imethod, arg1, arg2, arg3, 0, dataptr);
+}
+
+aid_t async_send_4(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
+    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
+{
+	return async_send_fast(exch, imethod, arg1, arg2, arg3, arg4, dataptr);
+}
+
+aid_t async_send_5(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
+    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
+    ipc_call_t *dataptr)
+{
+	return async_send_slow(exch, imethod, arg1, arg2, arg3, arg4, arg5,
+	    dataptr);
 }
 
@@ -434,7 +471,7 @@
  *
  */
-errno_t async_req_fast(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
-    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1, sysarg_t *r2,
-    sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
+static errno_t async_req_fast(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4,
+    sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
 {
 	if (exch == NULL)
@@ -449,17 +486,17 @@
 
 	if (r1)
-		*r1 = IPC_GET_ARG1(result);
+		*r1 = ipc_get_arg1(&result);
 
 	if (r2)
-		*r2 = IPC_GET_ARG2(result);
+		*r2 = ipc_get_arg2(&result);
 
 	if (r3)
-		*r3 = IPC_GET_ARG3(result);
+		*r3 = ipc_get_arg3(&result);
 
 	if (r4)
-		*r4 = IPC_GET_ARG4(result);
+		*r4 = ipc_get_arg4(&result);
 
 	if (r5)
-		*r5 = IPC_GET_ARG5(result);
+		*r5 = ipc_get_arg5(&result);
 
 	return rc;
@@ -486,7 +523,7 @@
  *
  */
-errno_t async_req_slow(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
-    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1,
-    sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
+static errno_t async_req_slow(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
+    sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
 {
 	if (exch == NULL)
@@ -501,19 +538,199 @@
 
 	if (r1)
-		*r1 = IPC_GET_ARG1(result);
+		*r1 = ipc_get_arg1(&result);
 
 	if (r2)
-		*r2 = IPC_GET_ARG2(result);
+		*r2 = ipc_get_arg2(&result);
 
 	if (r3)
-		*r3 = IPC_GET_ARG3(result);
+		*r3 = ipc_get_arg3(&result);
 
 	if (r4)
-		*r4 = IPC_GET_ARG4(result);
+		*r4 = ipc_get_arg4(&result);
 
 	if (r5)
-		*r5 = IPC_GET_ARG5(result);
+		*r5 = ipc_get_arg5(&result);
 
 	return rc;
+}
+
+errno_t async_req_0_0(async_exch_t *exch, sysarg_t imethod)
+{
+	return async_req_fast(exch, imethod, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_0_1(async_exch_t *exch, sysarg_t imethod, sysarg_t *r1)
+{
+	return async_req_fast(exch, imethod, 0, 0, 0, 0, r1, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_0_2(async_exch_t *exch, sysarg_t imethod, sysarg_t *r1, sysarg_t *r2)
+{
+	return async_req_fast(exch, imethod, 0, 0, 0, 0, r1, r2, NULL, NULL, NULL);
+}
+
+errno_t async_req_0_3(async_exch_t *exch, sysarg_t imethod, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3)
+{
+	return async_req_fast(exch, imethod, 0, 0, 0, 0, r1, r2, r3, NULL, NULL);
+}
+
+errno_t async_req_0_4(async_exch_t *exch, sysarg_t imethod, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4)
+{
+	return async_req_fast(exch, imethod, 0, 0, 0, 0, r1, r2, r3, r4, NULL);
+}
+
+errno_t async_req_0_5(async_exch_t *exch, sysarg_t imethod, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
+{
+	return async_req_fast(exch, imethod, 0, 0, 0, 0, r1, r2, r3, r4, r5);
+}
+
+errno_t async_req_1_0(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1)
+{
+	return async_req_fast(exch, imethod, arg1, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_1_1(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t *r1)
+{
+	return async_req_fast(exch, imethod, arg1, 0, 0, 0, r1, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_1_2(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t *r1, sysarg_t *r2)
+{
+	return async_req_fast(exch, imethod, arg1, 0, 0, 0, r1, r2, NULL, NULL, NULL);
+}
+
+errno_t async_req_1_3(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3)
+{
+	return async_req_fast(exch, imethod, arg1, 0, 0, 0, r1, r2, r3, NULL, NULL);
+}
+
+errno_t async_req_1_4(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4)
+{
+	return async_req_fast(exch, imethod, arg1, 0, 0, 0, r1, r2, r3, r4, NULL);
+}
+
+errno_t async_req_1_5(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
+{
+	return async_req_fast(exch, imethod, arg1, 0, 0, 0, r1, r2, r3, r4, r5);
+}
+
+errno_t async_req_2_0(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, 0, 0, NULL, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_2_1(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t *r1)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, 0, 0, r1, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_2_2(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t *r1, sysarg_t *r2)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, 0, 0, r1, r2, NULL, NULL, NULL);
+}
+
+errno_t async_req_2_3(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, 0, 0, r1, r2, r3, NULL, NULL);
+}
+
+errno_t async_req_2_4(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, 0, 0, r1, r2, r3, r4, NULL);
+}
+
+errno_t async_req_2_5(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, 0, 0, r1, r2, r3, r4, r5);
+}
+
+errno_t async_req_3_0(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, 0, NULL, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_3_1(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t *r1)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, 0, r1, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_3_2(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t *r1, sysarg_t *r2)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, 0, r1, r2, NULL, NULL, NULL);
+}
+
+errno_t async_req_3_3(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, 0, r1, r2, r3, NULL, NULL);
+}
+
+errno_t async_req_3_4(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, 0, r1, r2, r3, r4, NULL);
+}
+
+errno_t async_req_3_5(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, 0, r1, r2, r3, r4, r5);
+}
+
+errno_t async_req_4_0(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, arg4, NULL, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_4_1(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, arg4, r1, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_4_2(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1, sysarg_t *r2)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, arg4, r1, r2, NULL, NULL, NULL);
+}
+
+errno_t async_req_4_3(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, arg4, r1, r2, r3, NULL, NULL);
+}
+
+errno_t async_req_4_4(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, arg4, r1, r2, r3, r4, NULL);
+}
+
+errno_t async_req_4_5(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, arg4, r1, r2, r3, r4, r5);
+}
+
+errno_t async_req_5_0(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5)
+{
+	return async_req_slow(exch, imethod, arg1, arg2, arg3, arg4, arg5, NULL, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_5_1(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1)
+{
+	return async_req_slow(exch, imethod, arg1, arg2, arg3, arg4, arg5, r1, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_5_2(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1, sysarg_t *r2)
+{
+	return async_req_slow(exch, imethod, arg1, arg2, arg3, arg4, arg5, r1, r2, NULL, NULL, NULL);
+}
+
+errno_t async_req_5_3(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3)
+{
+	return async_req_slow(exch, imethod, arg1, arg2, arg3, arg4, arg5, r1, r2, r3, NULL, NULL);
+}
+
+errno_t async_req_5_4(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4)
+{
+	return async_req_slow(exch, imethod, arg1, arg2, arg3, arg4, arg5, r1, r2, r3, r4, NULL);
+}
+
+errno_t async_req_5_5(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
+{
+	return async_req_slow(exch, imethod, arg1, arg2, arg3, arg4, arg5, r1, r2, r3, r4, r5);
 }
 
@@ -588,5 +805,5 @@
 		return rc;
 
-	*out_phone = (cap_phone_handle_t) IPC_GET_ARG5(result);
+	*out_phone = (cap_phone_handle_t) ipc_get_arg5(&result);
 	return EOK;
 }
@@ -926,6 +1143,6 @@
  *
  */
-errno_t async_share_in_start(async_exch_t *exch, size_t size, sysarg_t arg,
-    unsigned int *flags, void **dst)
+static errno_t async_share_in_start(async_exch_t *exch, size_t size,
+    sysarg_t arg, unsigned int *flags, void **dst)
 {
 	if (exch == NULL)
@@ -945,4 +1162,27 @@
 }
 
+errno_t async_share_in_start_0_0(async_exch_t *exch, size_t size, void **dst)
+{
+	return async_share_in_start(exch, size, 0, NULL, dst);
+}
+
+errno_t async_share_in_start_0_1(async_exch_t *exch, size_t size,
+    unsigned int *flags, void **dst)
+{
+	return async_share_in_start(exch, size, 0, flags, dst);
+}
+
+errno_t async_share_in_start_1_0(async_exch_t *exch, size_t size, sysarg_t arg,
+    void **dst)
+{
+	return async_share_in_start(exch, size, arg, NULL, dst);
+}
+
+errno_t async_share_in_start_1_1(async_exch_t *exch, size_t size, sysarg_t arg,
+    unsigned int *flags, void **dst)
+{
+	return async_share_in_start(exch, size, arg, flags, dst);
+}
+
 /** Wrapper for IPC_M_SHARE_OUT calls using the async framework.
  *
@@ -1020,5 +1260,5 @@
 {
 	return async_req_5_0(exch, IPC_M_STATE_CHANGE_AUTHORIZE,
-	    arg1, arg2, arg3, 0, CAP_HANDLE_RAW(other_exch->phone));
+	    arg1, arg2, arg3, 0, cap_handle_raw(other_exch->phone));
 }
 
Index: uspace/lib/c/generic/async/ports.c
===================================================================
--- uspace/lib/c/generic/async/ports.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/async/ports.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,9 +27,9 @@
  */
 
-#define LIBC_ASYNC_C_
+#define _LIBC_ASYNC_C_
 #include <ipc/ipc.h>
 #include <async.h>
 #include "../private/async.h"
-#undef LIBC_ASYNC_C_
+#undef _LIBC_ASYNC_C_
 
 #include <ipc/irq.h>
@@ -103,8 +103,8 @@
 static hash_table_t interface_hash_table;
 
-static size_t interface_key_hash(void *key)
-{
-	iface_t iface = *(iface_t *) key;
-	return iface;
+static size_t interface_key_hash(const void *key)
+{
+	const iface_t *iface = key;
+	return *iface;
 }
 
@@ -115,9 +115,9 @@
 }
 
-static bool interface_key_equal(void *key, const ht_link_t *item)
-{
-	iface_t iface = *(iface_t *) key;
+static bool interface_key_equal(const void *key, const ht_link_t *item)
+{
+	const iface_t *iface = key;
 	interface_t *interface = hash_table_get_inst(item, interface_t, link);
-	return iface == interface->iface;
+	return *iface == interface->iface;
 }
 
@@ -131,8 +131,8 @@
 };
 
-static size_t port_key_hash(void *key)
-{
-	port_id_t port_id = *(port_id_t *) key;
-	return port_id;
+static size_t port_key_hash(const void *key)
+{
+	const port_id_t *port_id = key;
+	return *port_id;
 }
 
@@ -143,9 +143,9 @@
 }
 
-static bool port_key_equal(void *key, const ht_link_t *item)
-{
-	port_id_t port_id = *(port_id_t *) key;
+static bool port_key_equal(const void *key, const ht_link_t *item)
+{
+	const port_id_t *port_id = key;
 	port_t *port = hash_table_get_inst(item, port_t, link);
-	return port_id == port->id;
+	return *port_id == port->id;
 }
 
Index: uspace/lib/c/generic/async/server.c
===================================================================
--- uspace/lib/c/generic/async/server.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/async/server.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -96,9 +96,9 @@
  */
 
-#define LIBC_ASYNC_C_
+#define _LIBC_ASYNC_C_
 #include <ipc/ipc.h>
 #include <async.h>
 #include "../private/async.h"
-#undef LIBC_ASYNC_C_
+#undef _LIBC_ASYNC_C_
 
 #include <ipc/irq.h>
@@ -231,8 +231,8 @@
 static sysarg_t notification_avail = 0;
 
-static size_t client_key_hash(void *key)
-{
-	task_id_t in_task_id = *(task_id_t *) key;
-	return in_task_id;
+static size_t client_key_hash(const void *key)
+{
+	const task_id_t *in_task_id = key;
+	return *in_task_id;
 }
 
@@ -243,9 +243,9 @@
 }
 
-static bool client_key_equal(void *key, const ht_link_t *item)
-{
-	task_id_t in_task_id = *(task_id_t *) key;
+static bool client_key_equal(const void *key, const ht_link_t *item)
+{
+	const task_id_t *in_task_id = key;
 	client_t *client = hash_table_get_inst(item, client_t, link);
-	return in_task_id == client->in_task_id;
+	return *in_task_id == client->in_task_id;
 }
 
@@ -490,8 +490,8 @@
 }
 
-static size_t notification_key_hash(void *key)
-{
-	sysarg_t id = *(sysarg_t *) key;
-	return id;
+static size_t notification_key_hash(const void *key)
+{
+	const sysarg_t *id = key;
+	return *id;
 }
 
@@ -503,10 +503,10 @@
 }
 
-static bool notification_key_equal(void *key, const ht_link_t *item)
-{
-	sysarg_t id = *(sysarg_t *) key;
+static bool notification_key_equal(const void *key, const ht_link_t *item)
+{
+	const sysarg_t *id = key;
 	notification_t *notification =
 	    hash_table_get_inst(item, notification_t, htlink);
-	return id == notification->imethod;
+	return *id == notification->imethod;
 }
 
@@ -546,5 +546,5 @@
 	errno_t rc = mpsc_send(conn->msg_channel, call);
 
-	if (IPC_GET_IMETHOD(*call) == IPC_M_PHONE_HUNGUP) {
+	if (ipc_get_imethod(call) == IPC_M_PHONE_HUNGUP) {
 		/* Close the channel, but let the connection fibril answer. */
 		mpsc_close(conn->msg_channel);
@@ -656,6 +656,6 @@
 	}
 
-	ht_link_t *link = hash_table_find(&notification_hash_table,
-	    &IPC_GET_IMETHOD(*call));
+	sysarg_t imethod = ipc_get_imethod(call);
+	ht_link_t *link = hash_table_find(&notification_hash_table, &imethod);
 	if (!link) {
 		/* Invalid notification. */
@@ -871,7 +871,14 @@
 
 		memset(call, 0, sizeof(ipc_call_t));
+		ipc_set_imethod(call, IPC_M_PHONE_HUNGUP);
+		call->cap_handle = CAP_NIL;
 	}
 
 	return true;
+}
+
+bool async_get_call(ipc_call_t *call)
+{
+	return async_get_call_timeout(call, 0);
 }
 
@@ -937,5 +944,5 @@
 
 	/* New connection */
-	if (IPC_GET_IMETHOD(*call) == IPC_M_CONNECT_ME_TO) {
+	if (ipc_get_imethod(call) == IPC_M_CONNECT_ME_TO) {
 		connection_t *conn = calloc(1, sizeof(*conn));
 		if (!conn) {
@@ -944,5 +951,5 @@
 		}
 
-		iface_t iface = (iface_t) IPC_GET_ARG1(*call);
+		iface_t iface = (iface_t) ipc_get_arg1(call);
 
 		// TODO: Currently ignores all ports but the first one.
@@ -1001,5 +1008,5 @@
 
 /** Add one manager to manager list. */
-fid_t async_create_manager(void)
+static fid_t async_create_manager(void)
 {
 	fid_t fid = fibril_create_generic(async_manager_fibril, NULL, PAGE_SIZE);
@@ -1094,5 +1101,5 @@
 }
 
-errno_t async_forward_fast(ipc_call_t *call, async_exch_t *exch,
+static errno_t async_forward_fast(ipc_call_t *call, async_exch_t *exch,
     sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, unsigned int mode)
 {
@@ -1110,5 +1117,5 @@
 }
 
-errno_t async_forward_slow(ipc_call_t *call, async_exch_t *exch,
+static errno_t async_forward_slow(ipc_call_t *call, async_exch_t *exch,
     sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
     sysarg_t arg4, sysarg_t arg5, unsigned int mode)
@@ -1125,4 +1132,45 @@
 	return ipc_forward_slow(chandle, exch->phone, imethod, arg1, arg2, arg3,
 	    arg4, arg5, mode);
+}
+
+errno_t async_forward_0(ipc_call_t *call, async_exch_t *exch, sysarg_t imethod,
+    unsigned int mode)
+{
+	return async_forward_fast(call, exch, imethod, 0, 0, mode);
+}
+
+errno_t async_forward_1(ipc_call_t *call, async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, unsigned int mode)
+{
+	return async_forward_fast(call, exch, imethod, arg1, 0, mode);
+}
+
+errno_t async_forward_2(ipc_call_t *call, async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, unsigned int mode)
+{
+	return async_forward_fast(call, exch, imethod, arg1, arg2, mode);
+}
+
+errno_t async_forward_3(ipc_call_t *call, async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, unsigned int mode)
+{
+	return async_forward_slow(call, exch, imethod, arg1, arg2, arg3, 0, 0,
+	    mode);
+}
+
+errno_t async_forward_4(ipc_call_t *call, async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4,
+    unsigned int mode)
+{
+	return async_forward_slow(call, exch, imethod, arg1, arg2, arg3, arg4,
+	    0, mode);
+}
+
+errno_t async_forward_5(ipc_call_t *call, async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
+    unsigned int mode)
+{
+	return async_forward_slow(call, exch, imethod, arg1, arg2, arg3, arg4,
+	    arg5, mode);
 }
 
@@ -1173,8 +1221,8 @@
 	async_get_call(call);
 
-	if (IPC_GET_IMETHOD(*call) != IPC_M_SHARE_IN)
+	if (ipc_get_imethod(call) != IPC_M_SHARE_IN)
 		return false;
 
-	*size = (size_t) IPC_GET_ARG1(*call);
+	*size = (size_t) ipc_get_arg1(call);
 	return true;
 }
@@ -1228,9 +1276,9 @@
 	async_get_call(call);
 
-	if (IPC_GET_IMETHOD(*call) != IPC_M_SHARE_OUT)
+	if (ipc_get_imethod(call) != IPC_M_SHARE_OUT)
 		return false;
 
-	*size = (size_t) IPC_GET_ARG2(*call);
-	*flags = (unsigned int) IPC_GET_ARG3(*call);
+	*size = (size_t) ipc_get_arg2(call);
+	*flags = (unsigned int) ipc_get_arg3(call);
 	return true;
 }
@@ -1281,9 +1329,9 @@
 	async_get_call(call);
 
-	if (IPC_GET_IMETHOD(*call) != IPC_M_DATA_READ)
+	if (ipc_get_imethod(call) != IPC_M_DATA_READ)
 		return false;
 
 	if (size)
-		*size = (size_t) IPC_GET_ARG2(*call);
+		*size = (size_t) ipc_get_arg2(call);
 
 	return true;
@@ -1318,5 +1366,5 @@
  *
  */
-errno_t async_data_read_forward_fast(async_exch_t *exch, sysarg_t imethod,
+static errno_t async_data_read_forward_fast(async_exch_t *exch, sysarg_t imethod,
     sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4,
     ipc_call_t *dataptr)
@@ -1331,5 +1379,5 @@
 	}
 
-	aid_t msg = async_send_fast(exch, imethod, arg1, arg2, arg3, arg4,
+	aid_t msg = async_send_4(exch, imethod, arg1, arg2, arg3, arg4,
 	    dataptr);
 	if (msg == 0) {
@@ -1352,4 +1400,72 @@
 }
 
+errno_t async_data_read_forward_0_0(async_exch_t *exch, sysarg_t imethod)
+{
+	return async_data_read_forward_fast(exch, imethod, 0, 0, 0, 0, NULL);
+}
+
+errno_t async_data_read_forward_1_0(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1)
+{
+	return async_data_read_forward_fast(exch, imethod, arg1, 0, 0, 0, NULL);
+}
+
+errno_t async_data_read_forward_2_0(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2)
+{
+	return async_data_read_forward_fast(exch, imethod, arg1, arg2, 0,
+	    0, NULL);
+}
+
+errno_t async_data_read_forward_3_0(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
+{
+	return async_data_read_forward_fast(exch, imethod, arg1, arg2, arg3,
+	    0, NULL);
+}
+
+errno_t async_data_read_forward_4_0(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
+{
+	return async_data_read_forward_fast(exch, imethod, arg1, arg2, arg3,
+	    arg4, NULL);
+}
+
+errno_t async_data_read_forward_0_1(async_exch_t *exch, sysarg_t imethod,
+    ipc_call_t *dataptr)
+{
+	return async_data_read_forward_fast(exch, imethod, 0, 0, 0,
+	    0, dataptr);
+}
+
+errno_t async_data_read_forward_1_1(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, ipc_call_t *dataptr)
+{
+	return async_data_read_forward_fast(exch, imethod, arg1, 0, 0,
+	    0, dataptr);
+}
+
+errno_t async_data_read_forward_2_1(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, ipc_call_t *dataptr)
+{
+	return async_data_read_forward_fast(exch, imethod, arg1, arg2, 0,
+	    0, dataptr);
+}
+
+errno_t async_data_read_forward_3_1(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, ipc_call_t *dataptr)
+{
+	return async_data_read_forward_fast(exch, imethod, arg1, arg2, arg3,
+	    0, dataptr);
+}
+
+errno_t async_data_read_forward_4_1(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4,
+    ipc_call_t *dataptr)
+{
+	return async_data_read_forward_fast(exch, imethod, arg1, arg2, arg3,
+	    arg4, dataptr);
+}
+
 /** Wrapper for receiving the IPC_M_DATA_WRITE calls using the async framework.
  *
@@ -1372,9 +1488,9 @@
 	async_get_call(call);
 
-	if (IPC_GET_IMETHOD(*call) != IPC_M_DATA_WRITE)
+	if (ipc_get_imethod(call) != IPC_M_DATA_WRITE)
 		return false;
 
 	if (size)
-		*size = (size_t) IPC_GET_ARG2(*call);
+		*size = (size_t) ipc_get_arg2(call);
 
 	return true;
@@ -1495,7 +1611,7 @@
  *
  */
-errno_t async_data_write_forward_fast(async_exch_t *exch, sysarg_t imethod,
-    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4,
-    ipc_call_t *dataptr)
+static errno_t async_data_write_forward_fast(async_exch_t *exch,
+    sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
+    sysarg_t arg4, ipc_call_t *dataptr)
 {
 	if (exch == NULL)
@@ -1508,5 +1624,5 @@
 	}
 
-	aid_t msg = async_send_fast(exch, imethod, arg1, arg2, arg3, arg4,
+	aid_t msg = async_send_4(exch, imethod, arg1, arg2, arg3, arg4,
 	    dataptr);
 	if (msg == 0) {
@@ -1529,4 +1645,74 @@
 }
 
+errno_t async_data_write_forward_0_0(async_exch_t *exch, sysarg_t imethod)
+{
+	return async_data_write_forward_fast(exch, imethod, 0, 0, 0,
+	    0, NULL);
+}
+
+errno_t async_data_write_forward_1_0(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1)
+{
+	return async_data_write_forward_fast(exch, imethod, arg1, 0, 0,
+	    0, NULL);
+}
+
+errno_t async_data_write_forward_2_0(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2)
+{
+	return async_data_write_forward_fast(exch, imethod, arg1, arg2, 0,
+	    0, NULL);
+}
+
+errno_t async_data_write_forward_3_0(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
+{
+	return async_data_write_forward_fast(exch, imethod, arg1, arg2, arg3,
+	    0, NULL);
+}
+
+errno_t async_data_write_forward_4_0(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
+{
+	return async_data_write_forward_fast(exch, imethod, arg1, arg2, arg3,
+	    arg4, NULL);
+}
+
+errno_t async_data_write_forward_0_1(async_exch_t *exch, sysarg_t imethod,
+    ipc_call_t *dataptr)
+{
+	return async_data_write_forward_fast(exch, imethod, 0, 0, 0,
+	    0, dataptr);
+}
+
+errno_t async_data_write_forward_1_1(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, ipc_call_t *dataptr)
+{
+	return async_data_write_forward_fast(exch, imethod, arg1, 0, 0,
+	    0, dataptr);
+}
+
+errno_t async_data_write_forward_2_1(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, ipc_call_t *dataptr)
+{
+	return async_data_write_forward_fast(exch, imethod, arg1, arg2, 0,
+	    0, dataptr);
+}
+
+errno_t async_data_write_forward_3_1(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, ipc_call_t *dataptr)
+{
+	return async_data_write_forward_fast(exch, imethod, arg1, arg2, arg3,
+	    0, dataptr);
+}
+
+errno_t async_data_write_forward_4_1(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4,
+    ipc_call_t *dataptr)
+{
+	return async_data_write_forward_fast(exch, imethod, arg1, arg2, arg3,
+	    arg4, dataptr);
+}
+
 /** Wrapper for receiving the IPC_M_CONNECT_TO_ME calls.
  *
@@ -1546,8 +1732,8 @@
 	async_get_call(&call);
 
-	cap_phone_handle_t phandle = (cap_handle_t) IPC_GET_ARG5(call);
-
-	if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) ||
-	    !CAP_HANDLE_VALID((phandle))) {
+	cap_phone_handle_t phandle = (cap_handle_t) ipc_get_arg5(&call);
+
+	if ((ipc_get_imethod(&call) != IPC_M_CONNECT_TO_ME) ||
+	    !cap_handle_valid((phandle))) {
 		async_answer_0(&call, EINVAL);
 		return NULL;
@@ -1590,8 +1776,8 @@
 async_sess_t *async_callback_receive_start(exch_mgmt_t mgmt, ipc_call_t *call)
 {
-	cap_phone_handle_t phandle = (cap_handle_t) IPC_GET_ARG5(*call);
-
-	if ((IPC_GET_IMETHOD(*call) != IPC_M_CONNECT_TO_ME) ||
-	    !CAP_HANDLE_VALID((phandle)))
+	cap_phone_handle_t phandle = (cap_handle_t) ipc_get_arg5(call);
+
+	if ((ipc_get_imethod(call) != IPC_M_CONNECT_TO_ME) ||
+	    !cap_handle_valid((phandle)))
 		return NULL;
 
@@ -1617,5 +1803,5 @@
 	async_get_call(call);
 
-	if (IPC_GET_IMETHOD(*call) != IPC_M_STATE_CHANGE_AUTHORIZE)
+	if (ipc_get_imethod(call) != IPC_M_STATE_CHANGE_AUTHORIZE)
 		return false;
 
@@ -1627,5 +1813,5 @@
 	assert(call);
 
-	return async_answer_1(call, EOK, CAP_HANDLE_RAW(other_exch->phone));
+	return async_answer_1(call, EOK, cap_handle_raw(other_exch->phone));
 }
 
Index: uspace/lib/c/generic/bd.c
===================================================================
--- uspace/lib/c/generic/bd.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/bd.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -206,10 +206,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			return;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		default:
 			async_answer_0(&call, ENOTSUP);
Index: uspace/lib/c/generic/bd_srv.c
===================================================================
--- uspace/lib/c/generic/bd_srv.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/bd_srv.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -51,6 +51,6 @@
 	errno_t rc;
 
-	ba = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
-	cnt = IPC_GET_ARG3(*call);
+	ba = MERGE_LOUP32(ipc_get_arg1(call), ipc_get_arg2(call));
+	cnt = ipc_get_arg3(call);
 
 	ipc_call_t rcall;
@@ -95,5 +95,5 @@
 	errno_t rc;
 
-	session = IPC_GET_ARG1(*call);
+	session = ipc_get_arg1(call);
 
 	ipc_call_t rcall;
@@ -137,6 +137,6 @@
 	errno_t rc;
 
-	ba = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
-	cnt = IPC_GET_ARG3(*call);
+	ba = MERGE_LOUP32(ipc_get_arg1(call), ipc_get_arg2(call));
+	cnt = ipc_get_arg3(call);
 
 	if (srv->srvs->ops->sync_cache == NULL) {
@@ -157,6 +157,6 @@
 	errno_t rc;
 
-	ba = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
-	cnt = IPC_GET_ARG3(*call);
+	ba = MERGE_LOUP32(ipc_get_arg1(call), ipc_get_arg2(call));
+	cnt = ipc_get_arg3(call);
 
 	rc = async_data_write_accept(&data, false, 0, 0, 0, &size);
@@ -247,5 +247,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: uspace/lib/c/generic/context.c
===================================================================
--- uspace/lib/c/generic/context.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/context.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -43,11 +43,11 @@
 void context_swap(context_t *self, context_t *other)
 {
-	if (!__setjmp(self))
-		__longjmp(other, 1);
+	if (!__context_save(self))
+		__context_restore(other, 1);
 }
 
 void context_create(context_t *context, const context_create_t *arg)
 {
-	__setjmp(context);
+	__context_save(context);
 	context_set(context, FADDR(arg->fn), arg->stack_base,
 	    arg->stack_size, arg->tls);
Index: uspace/lib/c/generic/ctype.c
===================================================================
--- uspace/lib/c/generic/ctype.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/generic/ctype.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,127 @@
+/*
+ * 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#include <ctype.h>
+
+int islower(int c)
+{
+	return ((c >= 'a') && (c <= 'z'));
+}
+
+int isupper(int c)
+{
+	return ((c >= 'A') && (c <= 'Z'));
+}
+
+int isalpha(int c)
+{
+	return (islower(c) || isupper(c));
+}
+
+int isdigit(int c)
+{
+	return ((c >= '0') && (c <= '9'));
+}
+
+int isalnum(int c)
+{
+	return (isalpha(c) || isdigit(c));
+}
+
+int isblank(int c)
+{
+	return c == ' ' || c == '\t';
+}
+
+int iscntrl(int c)
+{
+	return (c >= 0 && c < 0x20) || c == 0x7E;
+}
+
+int isprint(int c)
+{
+	return c >= 0 && c < 0x80 && !iscntrl(c);
+}
+
+int isgraph(int c)
+{
+	return isprint(c) && c != ' ';
+}
+
+int isspace(int c)
+{
+	switch (c) {
+	case ' ':
+	case '\n':
+	case '\t':
+	case '\f':
+	case '\r':
+	case '\v':
+		return 1;
+		break;
+	default:
+		return 0;
+	}
+}
+
+int ispunct(int c)
+{
+	return !isspace(c) && !isalnum(c) && isprint(c);
+}
+
+int isxdigit(int c)
+{
+	return isdigit(c) ||
+	    (c >= 'a' && c <= 'f') ||
+	    (c >= 'A' && c <= 'F');
+}
+
+int tolower(int c)
+{
+	if (isupper(c))
+		return (c + ('a' - 'A'));
+	else
+		return c;
+}
+
+int toupper(int c)
+{
+	if (islower(c))
+		return (c + ('A' - 'a'));
+	else
+		return c;
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/devman.c
===================================================================
--- uspace/lib/c/generic/devman.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/devman.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -255,5 +255,5 @@
 	if (retval == EOK) {
 		if (funh != NULL)
-			*funh = (int) IPC_GET_ARG1(answer);
+			*funh = (int) ipc_get_arg1(&answer);
 	} else {
 		if (funh != NULL)
@@ -394,5 +394,5 @@
 
 	if (handle != NULL)
-		*handle = (devman_handle_t) IPC_GET_ARG1(answer);
+		*handle = (devman_handle_t) ipc_get_arg1(&answer);
 
 	return retval;
@@ -429,6 +429,6 @@
 
 	if (r1 != NULL)
-		*r1 = IPC_GET_ARG1(answer);
-	act_size = IPC_GET_ARG2(dreply);
+		*r1 = ipc_get_arg1(&answer);
+	act_size = ipc_get_arg2(&dreply);
 	assert(act_size <= buf_size - 1);
 	buf[act_size] = '\0';
@@ -517,5 +517,5 @@
 	}
 
-	*act_size = IPC_GET_ARG1(answer);
+	*act_size = ipc_get_arg1(&answer);
 	return EOK;
 }
@@ -663,5 +663,5 @@
 
 	if (handle != NULL)
-		*handle = (devman_handle_t) IPC_GET_ARG1(answer);
+		*handle = (devman_handle_t) ipc_get_arg1(&answer);
 
 	return retval;
Index: uspace/lib/c/generic/dirent.c
===================================================================
--- uspace/lib/c/generic/dirent.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/dirent.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,4 +39,11 @@
 #include <errno.h>
 #include <assert.h>
+#include <string.h>
+
+struct __dirstream {
+	int fd;
+	struct dirent res;
+	aoff64_t pos;
+};
 
 /** Open directory.
@@ -86,10 +93,12 @@
 	ssize_t len = 0;
 
-	rc = vfs_read_short(dirp->fd, dirp->pos, &dirp->res.d_name[0],
-	    NAME_MAX + 1, &len);
+	rc = vfs_read_short(dirp->fd, dirp->pos, dirp->res.d_name,
+	    sizeof(dirp->res.d_name), &len);
 	if (rc != EOK) {
 		errno = rc;
 		return NULL;
 	}
+
+	assert(strnlen(dirp->res.d_name, sizeof(dirp->res.d_name)) < sizeof(dirp->res.d_name));
 
 	dirp->pos += len;
Index: uspace/lib/c/generic/dlfcn.c
===================================================================
--- uspace/lib/c/generic/dlfcn.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/dlfcn.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,4 +35,5 @@
  */
 
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -53,5 +54,12 @@
 	if (m == NULL) {
 		m = module_load(runtime_env, path, mlf_local);
-		module_load_deps(m, mlf_local);
+		if (m == NULL) {
+			return NULL;
+		}
+
+		if (module_load_deps(m, mlf_local) != EOK) {
+			return NULL;
+		}
+
 		/* Now relocate. */
 		module_process_relocs(m);
Index: uspace/lib/c/generic/dnsr.c
===================================================================
--- uspace/lib/c/generic/dnsr.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/dnsr.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -125,5 +125,5 @@
 	}
 
-	size_t act_size = IPC_GET_ARG2(answer_cname);
+	size_t act_size = ipc_get_arg2(&answer_cname);
 	assert(act_size <= DNSR_NAME_MAX_SIZE);
 
Index: uspace/lib/c/generic/double_to_str.c
===================================================================
--- uspace/lib/c/generic/double_to_str.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/double_to_str.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -503,5 +503,5 @@
 {
 	/* The whole computation assumes 64bit significand. */
-	static_assert(sizeof(ieee_val.pos_val.significand) == sizeof(uint64_t));
+	static_assert(sizeof(ieee_val.pos_val.significand) == sizeof(uint64_t), "");
 
 	if (ieee_val.is_special) {
@@ -754,5 +754,5 @@
 {
 	/* The whole computation assumes 64bit significand. */
-	static_assert(sizeof(ieee_val.pos_val.significand) == sizeof(uint64_t));
+	static_assert(sizeof(ieee_val.pos_val.significand) == sizeof(uint64_t), "");
 
 	if (ieee_val.is_special) {
Index: uspace/lib/c/generic/elf/elf_load.c
===================================================================
--- uspace/lib/c/generic/elf/elf_load.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/elf/elf_load.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -53,15 +53,15 @@
  * @param file File handle
  * @param info Place to store ELF program information
- * @return EE_OK on success or an EE_x error code
+ * @return EOK on success or an error code
  */
-int elf_load(int file, elf_info_t *info)
+errno_t elf_load(int file, elf_info_t *info)
 {
 #ifdef CONFIG_RTLD
 	rtld_t *env;
 #endif
-	int rc;
+	errno_t rc;
 
 	rc = elf_load_file(file, 0, &info->finfo);
-	if (rc != EE_OK) {
+	if (rc != EOK) {
 		DPRINTF("Failed to load executable '%s'.\n", file_name);
 		return rc;
@@ -72,5 +72,5 @@
 		DPRINTF("Binary is statically linked.\n");
 		info->env = NULL;
-		return EE_OK;
+		return EOK;
 	}
 
@@ -79,20 +79,8 @@
 	DPRINTF("- prog dynamic: %p\n", info->finfo.dynamic);
 
-	errno_t rc2 = rtld_prog_process(&info->finfo, &env);
-	switch (rc2) {
-	case EOK:
-		rc = EE_OK;
-		break;
-	case ENOMEM:
-		rc = EE_MEMORY;
-		break;
-	default:
-		DPRINTF("Unexpected error code from rtld_prog_process(): %s\n", str_error_name(rc2));
-		rc = EE_INVALID;
-	}
-
+	rc = rtld_prog_process(&info->finfo, &env);
 	info->env = env;
 #else
-	rc = EE_UNSUPPORTED;
+	rc = ENOTSUP;
 #endif
 	return rc;
Index: uspace/lib/c/generic/elf/elf_mod.c
===================================================================
--- uspace/lib/c/generic/elf/elf_mod.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/elf/elf_mod.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -64,17 +64,7 @@
 #define DPRINTF(...)
 
-static const char *error_codes[] = {
-	"no error",
-	"invalid image",
-	"address space error",
-	"incompatible image",
-	"unsupported image type",
-	"irrecoverable error",
-	"file io error"
-};
-
-static unsigned int elf_load_module(elf_ld_t *elf);
-static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry);
-static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry);
+static errno_t elf_load_module(elf_ld_t *elf);
+static errno_t segment_header(elf_ld_t *elf, elf_segment_header_t *entry);
+static errno_t load_segment(elf_ld_t *elf, elf_segment_header_t *entry);
 
 /** Load ELF binary from a file.
@@ -90,8 +80,8 @@
  *                  extracted from the binary.
  *
- * @return EE_OK on success or EE_xx error code.
- *
- */
-int elf_load_file(int file, eld_flags_t flags, elf_finfo_t *info)
+ * @return EOK on success or an error code.
+ *
+ */
+errno_t elf_load_file(int file, eld_flags_t flags, elf_finfo_t *info)
 {
 	elf_ld_t elf;
@@ -103,5 +93,5 @@
 	}
 	if (rc != EOK) {
-		return EE_IO;
+		return rc;
 	}
 
@@ -110,20 +100,20 @@
 	elf.flags = flags;
 
-	int ret = elf_load_module(&elf);
+	rc = elf_load_module(&elf);
 
 	vfs_put(ofile);
-	return ret;
-}
-
-int elf_load_file_name(const char *path, eld_flags_t flags, elf_finfo_t *info)
+	return rc;
+}
+
+errno_t elf_load_file_name(const char *path, eld_flags_t flags, elf_finfo_t *info)
 {
 	int file;
 	errno_t rc = vfs_lookup(path, 0, &file);
 	if (rc == EOK) {
-		int ret = elf_load_file(file, flags, info);
+		rc = elf_load_file(file, flags, info);
 		vfs_put(file);
-		return ret;
+		return rc;
 	} else {
-		return EE_IO;
+		return EIO;
 	}
 }
@@ -136,7 +126,7 @@
  *
  * @param elf		Pointer to loader state buffer.
- * @return EE_OK on success or EE_xx error code.
- */
-static unsigned int elf_load_module(elf_ld_t *elf)
+ * @return EOK on success or an error code.
+ */
+static errno_t elf_load_module(elf_ld_t *elf)
 {
 	elf_header_t header_buf;
@@ -144,5 +134,5 @@
 	aoff64_t pos = 0;
 	size_t nr;
-	int i, ret;
+	int i;
 	errno_t rc;
 
@@ -150,5 +140,5 @@
 	if (rc != EOK || nr != sizeof(elf_header_t)) {
 		DPRINTF("Read error.\n");
-		return EE_IO;
+		return EIO;
 	}
 
@@ -159,5 +149,5 @@
 	    header->e_ident[EI_MAG3] != ELFMAG3) {
 		DPRINTF("Invalid header.\n");
-		return EE_INVALID;
+		return EINVAL;
 	}
 
@@ -169,5 +159,5 @@
 	    header->e_ident[EI_CLASS] != ELF_CLASS) {
 		DPRINTF("Incompatible data/version/class.\n");
-		return EE_INCOMPATIBLE;
+		return EINVAL;
 	}
 
@@ -175,5 +165,5 @@
 		DPRINTF("e_phentsize: %u != %zu\n", header->e_phentsize,
 		    sizeof(elf_segment_header_t));
-		return EE_INCOMPATIBLE;
+		return EINVAL;
 	}
 
@@ -181,10 +171,10 @@
 	if (header->e_type != ET_EXEC && header->e_type != ET_DYN) {
 		DPRINTF("Object type %d is not supported\n", header->e_type);
-		return EE_UNSUPPORTED;
+		return ENOTSUP;
 	}
 
 	if (header->e_phoff == 0) {
 		DPRINTF("Program header table is not present!\n");
-		return EE_UNSUPPORTED;
+		return ENOTSUP;
 	}
 
@@ -203,5 +193,5 @@
 	if (phdr_len > sizeof(phdr)) {
 		DPRINTF("more than %d program headers\n", phdr_cap);
-		return EE_UNSUPPORTED;
+		return ENOTSUP;
 	}
 
@@ -210,5 +200,5 @@
 	if (rc != EOK || nr != phdr_len) {
 		DPRINTF("Read error.\n");
-		return EE_IO;
+		return EIO;
 	}
 
@@ -231,5 +221,5 @@
 	if (base_offset != 0) {
 		DPRINTF("ELF headers not present in the text segment.\n");
-		return EE_INVALID;
+		return EINVAL;
 	}
 
@@ -240,5 +230,5 @@
 		if (module_base != 0) {
 			DPRINTF("Unexpected shared object format.\n");
-			return EE_INVALID;
+			return EINVAL;
 		}
 
@@ -258,5 +248,5 @@
 		if (area == AS_MAP_FAILED) {
 			DPRINTF("Can't find suitable memory area.\n");
-			return EE_MEMORY;
+			return ENOMEM;
 		}
 
@@ -270,7 +260,7 @@
 			continue;
 
-		ret = load_segment(elf, &phdr[i]);
-		if (ret != EE_OK)
-			return ret;
+		rc = load_segment(elf, &phdr[i]);
+		if (rc != EOK)
+			return rc;
 	}
 
@@ -292,7 +282,7 @@
 			continue;
 
-		ret = segment_header(elf, &phdr[i]);
-		if (ret != EE_OK)
-			return ret;
+		rc = segment_header(elf, &phdr[i]);
+		if (rc != EOK)
+			return rc;
 	}
 
@@ -302,18 +292,5 @@
 	DPRINTF("Done.\n");
 
-	return EE_OK;
-}
-
-/** Print error message according to error code.
- *
- * @param rc Return code returned by elf_load().
- *
- * @return NULL terminated description of error.
- */
-const char *elf_error(unsigned int rc)
-{
-	assert(rc < sizeof(error_codes) / sizeof(char *));
-
-	return error_codes[rc];
+	return EOK;
 }
 
@@ -338,7 +315,7 @@
  * @param entry	Segment header.
  *
- * @return EE_OK on success, error code otherwise.
- */
-static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry)
+ * @return EOK on success, error code otherwise.
+ */
+static errno_t segment_header(elf_ld_t *elf, elf_segment_header_t *entry)
 {
 	switch (entry->p_type) {
@@ -358,9 +335,9 @@
 		if (entry->p_filesz == 0) {
 			DPRINTF("Zero-sized ELF interp string.\n");
-			return EE_INVALID;
+			return EINVAL;
 		}
 		if (elf->info->interp[entry->p_filesz - 1] != '\0') {
 			DPRINTF("Unterminated ELF interp string.\n");
-			return EE_INVALID;
+			return EINVAL;
 		}
 		DPRINTF("interpreter: \"%s\"\n", elf->info->interp);
@@ -389,8 +366,8 @@
 	default:
 		DPRINTF("Segment p_type %d unknown.\n", entry->p_type);
-		return EE_UNSUPPORTED;
-		break;
-	}
-	return EE_OK;
+		return ENOTSUP;
+		break;
+	}
+	return EOK;
 }
 
@@ -400,7 +377,7 @@
  * @param entry Program header entry describing segment to be loaded.
  *
- * @return EE_OK on success, error code otherwise.
- */
-int load_segment(elf_ld_t *elf, elf_segment_header_t *entry)
+ * @return EOK on success, error code otherwise.
+ */
+errno_t load_segment(elf_ld_t *elf, elf_segment_header_t *entry)
 {
 	void *a;
@@ -420,6 +397,11 @@
 	seg_ptr = (void *) seg_addr;
 
-	DPRINTF("Load segment at addr %p, size 0x%zx\n", (void *) seg_addr,
-	    entry->p_memsz);
+	DPRINTF("Load segment v_addr=0x%zx at addr %p, size 0x%zx, flags %c%c%c\n",
+	    entry->p_vaddr,
+	    (void *) seg_addr,
+	    entry->p_memsz,
+	    (entry->p_flags & PF_R) ? 'r' : '-',
+	    (entry->p_flags & PF_W) ? 'w' : '-',
+	    (entry->p_flags & PF_X) ? 'x' : '-');
 
 	if (entry->p_align > 1) {
@@ -427,8 +409,8 @@
 		    (seg_addr % entry->p_align)) {
 			DPRINTF("Align check 1 failed offset%%align=0x%zx, "
-			    "vaddr%%align=0x%zx\n",
+			    "vaddr%%align=0x%zx align=0x%zx\n",
 			    entry->p_offset % entry->p_align,
-			    seg_addr % entry->p_align);
-			return EE_INVALID;
+			    seg_addr % entry->p_align, entry->p_align);
+			return EINVAL;
 		}
 	}
@@ -461,5 +443,5 @@
 		DPRINTF("memory mapping failed (%p, %zu)\n",
 		    (void *) (base + bias), mem_sz);
-		return EE_MEMORY;
+		return ENOMEM;
 	}
 
@@ -474,5 +456,5 @@
 	if (rc != EOK || nr != entry->p_filesz) {
 		DPRINTF("read error\n");
-		return EE_IO;
+		return EIO;
 	}
 
@@ -482,10 +464,12 @@
 	 */
 	if ((elf->flags & ELDF_RW) != 0)
-		return EE_OK;
-
-	rc = as_area_change_flags(seg_ptr, flags);
+		return EOK;
+
+	DPRINTF("as_area_change_flags(%p, %x)\n",
+	    (uint8_t *) base + bias, flags);
+	rc = as_area_change_flags((uint8_t *) base + bias, flags);
 	if (rc != EOK) {
 		DPRINTF("Failed to set memory area flags.\n");
-		return EE_MEMORY;
+		return ENOMEM;
 	}
 
@@ -493,8 +477,8 @@
 		/* Enforce SMC coherence for the segment */
 		if (smc_coherence(seg_ptr, entry->p_filesz))
-			return EE_MEMORY;
-	}
-
-	return EE_OK;
+			return ENOMEM;
+	}
+
+	return EOK;
 }
 
Index: uspace/lib/c/generic/gsort.c
===================================================================
--- uspace/lib/c/generic/gsort.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/gsort.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,8 +33,7 @@
 /**
  * @file
- * @brief Sorting functions.
+ * @brief Gnome Sort.
  *
- * This files contains functions implementing several sorting
- * algorithms (e.g. quick sort and gnome sort).
+ * This file contains an implementation of gnome sort
  *
  */
@@ -80,5 +79,5 @@
 		if ((i != 0) &&
 		    (cmp(INDEX(data, i, elem_size),
-		    INDEX(data, i - 1, elem_size), arg) == -1)) {
+		    INDEX(data, i - 1, elem_size), arg) < 0)) {
 			memcpy(slot, INDEX(data, i, elem_size), elem_size);
 			memcpy(INDEX(data, i, elem_size), INDEX(data, i - 1, elem_size),
Index: uspace/lib/c/generic/ieee_double.c
===================================================================
--- uspace/lib/c/generic/ieee_double.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/ieee_double.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -45,5 +45,5 @@
 	const int exponent_bias = 1075;
 
-	static_assert(sizeof(val) == sizeof(uint64_t));
+	static_assert(sizeof(val) == sizeof(uint64_t), "");
 
 	union {
Index: uspace/lib/c/generic/imath.c
===================================================================
--- uspace/lib/c/generic/imath.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/imath.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -50,5 +50,5 @@
 errno_t ipow10_u64(unsigned exp, uint64_t *res)
 {
-	unsigned a;
+	uint64_t a;
 	uint64_t r;
 
Index: uspace/lib/c/generic/inet.c
===================================================================
--- uspace/lib/c/generic/inet.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/inet.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -180,6 +180,6 @@
 	inet_dgram_t dgram;
 
-	dgram.tos = IPC_GET_ARG1(*icall);
-	dgram.iplink = IPC_GET_ARG2(*icall);
+	dgram.tos = ipc_get_arg1(icall);
+	dgram.iplink = ipc_get_arg2(icall);
 
 	ipc_call_t call;
@@ -240,10 +240,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			return;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case INET_EV_RECV:
 			inet_ev_recv(&call);
Index: uspace/lib/c/generic/inet/tcp.c
===================================================================
--- uspace/lib/c/generic/inet/tcp.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/inet/tcp.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -232,5 +232,5 @@
 		goto error;
 
-	conn_id = IPC_GET_ARG1(answer);
+	conn_id = ipc_get_arg1(&answer);
 
 	rc = tcp_conn_new(tcp, conn_id, cb, arg, rconn);
@@ -348,5 +348,5 @@
 
 	lst->tcp = tcp;
-	lst->id = IPC_GET_ARG1(answer);
+	lst->id = ipc_get_arg1(&answer);
 	lst->lcb = lcb;
 	lst->lcb_arg = larg;
@@ -569,5 +569,5 @@
 	}
 
-	*nrecv = IPC_GET_ARG1(answer);
+	*nrecv = ipc_get_arg1(&answer);
 	fibril_mutex_unlock(&conn->lock);
 	return EOK;
@@ -626,5 +626,5 @@
 	}
 
-	*nrecv = IPC_GET_ARG1(answer);
+	*nrecv = ipc_get_arg1(&answer);
 	fibril_mutex_unlock(&conn->lock);
 	return EOK;
@@ -643,5 +643,5 @@
 	errno_t rc;
 
-	conn_id = IPC_GET_ARG1(*icall);
+	conn_id = ipc_get_arg1(icall);
 
 	rc = tcp_conn_get(tcp, conn_id, &conn);
@@ -671,5 +671,5 @@
 	errno_t rc;
 
-	conn_id = IPC_GET_ARG1(*icall);
+	conn_id = ipc_get_arg1(icall);
 
 	rc = tcp_conn_get(tcp, conn_id, &conn);
@@ -699,5 +699,5 @@
 	errno_t rc;
 
-	conn_id = IPC_GET_ARG1(*icall);
+	conn_id = ipc_get_arg1(icall);
 
 	rc = tcp_conn_get(tcp, conn_id, &conn);
@@ -727,5 +727,5 @@
 	errno_t rc;
 
-	conn_id = IPC_GET_ARG1(*icall);
+	conn_id = ipc_get_arg1(icall);
 
 	rc = tcp_conn_get(tcp, conn_id, &conn);
@@ -771,6 +771,6 @@
 	errno_t rc;
 
-	lst_id = IPC_GET_ARG1(*icall);
-	conn_id = IPC_GET_ARG2(*icall);
+	lst_id = ipc_get_arg1(icall);
+	conn_id = ipc_get_arg2(icall);
 
 	rc = tcp_listener_get(tcp, lst_id, &lst);
@@ -821,5 +821,5 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			/* Hangup*/
 			async_answer_0(&call, EOK);
@@ -827,5 +827,5 @@
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case TCP_EV_CONNECTED:
 			tcp_ev_connected(tcp, &call);
Index: uspace/lib/c/generic/inet/udp.c
===================================================================
--- uspace/lib/c/generic/inet/udp.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/inet/udp.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -190,5 +190,5 @@
 
 	assoc->udp = udp;
-	assoc->id = IPC_GET_ARG1(answer);
+	assoc->id = ipc_get_arg1(&answer);
 	assoc->cb = cb;
 	assoc->cb_arg = arg;
@@ -404,6 +404,6 @@
 
 	rmsg->udp = udp;
-	rmsg->assoc_id = IPC_GET_ARG1(answer);
-	rmsg->size = IPC_GET_ARG2(answer);
+	rmsg->assoc_id = ipc_get_arg1(&answer);
+	rmsg->size = ipc_get_arg2(&answer);
 	rmsg->remote_ep = ep;
 	return EOK;
@@ -498,5 +498,5 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			/* Hangup */
 			async_answer_0(&call, EOK);
@@ -504,5 +504,5 @@
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case UDP_EV_DATA:
 			udp_ev_data(udp, &call);
Index: uspace/lib/c/generic/inetcfg.c
===================================================================
--- uspace/lib/c/generic/inetcfg.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/inetcfg.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -62,5 +62,5 @@
 	}
 
-	*act_size = IPC_GET_ARG1(answer);
+	*act_size = ipc_get_arg1(&answer);
 	return EOK;
 }
@@ -161,5 +161,5 @@
 	async_wait_for(req, &retval);
 
-	*addr_id = IPC_GET_ARG1(answer);
+	*addr_id = ipc_get_arg1(&answer);
 
 	return retval;
@@ -217,10 +217,10 @@
 		return retval;
 
-	size_t act_size = IPC_GET_ARG2(answer_name);
+	size_t act_size = ipc_get_arg2(&answer_name);
 	assert(act_size <= LOC_NAME_MAXLEN);
 
 	name_buf[act_size] = '\0';
 
-	ainfo->ilink = IPC_GET_ARG1(answer);
+	ainfo->ilink = ipc_get_arg1(&answer);
 	ainfo->name = str_dup(name_buf);
 
@@ -244,5 +244,5 @@
 
 	async_wait_for(req, &retval);
-	*addr_id = IPC_GET_ARG1(answer);
+	*addr_id = ipc_get_arg1(&answer);
 
 	return retval;
@@ -305,10 +305,10 @@
 		return retval;
 
-	act_size = IPC_GET_ARG2(dreply);
+	act_size = ipc_get_arg2(&dreply);
 	assert(act_size <= LOC_NAME_MAXLEN);
 	name_buf[act_size] = '\0';
 
 	linfo->name = str_dup(name_buf);
-	linfo->def_mtu = IPC_GET_ARG1(answer);
+	linfo->def_mtu = ipc_get_arg1(&answer);
 
 	return EOK;
@@ -359,5 +359,5 @@
 	async_wait_for(req, &retval);
 
-	*sroute_id = IPC_GET_ARG1(answer);
+	*sroute_id = ipc_get_arg1(&answer);
 
 	return retval;
@@ -428,5 +428,5 @@
 		return retval;
 
-	size_t act_size = IPC_GET_ARG2(answer_name);
+	size_t act_size = ipc_get_arg2(&answer_name);
 	assert(act_size <= LOC_NAME_MAXLEN);
 
@@ -454,5 +454,5 @@
 
 	async_wait_for(req, &retval);
-	*sroute_id = IPC_GET_ARG1(answer);
+	*sroute_id = ipc_get_arg1(&answer);
 
 	return retval;
Index: uspace/lib/c/generic/inetping.c
===================================================================
--- uspace/lib/c/generic/inetping.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/inetping.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -154,5 +154,5 @@
 	inetping_sdu_t sdu;
 
-	sdu.seq_no = IPC_GET_ARG1(*icall);
+	sdu.seq_no = ipc_get_arg1(icall);
 
 	ipc_call_t call;
@@ -213,10 +213,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			return;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case INETPING_EV_RECV:
 			inetping_ev_recv(&call);
Index: uspace/lib/c/generic/io/asprintf.c
===================================================================
--- uspace/lib/c/generic/io/asprintf.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/io/asprintf.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -51,5 +51,5 @@
 }
 
-int vprintf_size(const char *fmt, va_list args)
+int vprintf_length(const char *fmt, va_list args)
 {
 	printf_spec_t ps = {
@@ -62,9 +62,9 @@
 }
 
-int printf_size(const char *fmt, ...)
+int printf_length(const char *fmt, ...)
 {
 	va_list args;
 	va_start(args, fmt);
-	int ret = vprintf_size(fmt, args);
+	int ret = vprintf_length(fmt, args);
 	va_end(args);
 
@@ -86,13 +86,13 @@
 	va_list args2;
 	va_copy(args2, args);
-	int ret = vprintf_size(fmt, args2);
+	int ret = vsnprintf(NULL, 0, fmt, args2);
 	va_end(args2);
 
 	if (ret > 0) {
-		*strp = malloc(STR_BOUNDS(ret) + 1);
+		*strp = malloc(ret + 1);
 		if (*strp == NULL)
 			return -1;
 
-		vsnprintf(*strp, STR_BOUNDS(ret) + 1, fmt, args);
+		vsnprintf(*strp, ret + 1, fmt, args);
 	}
 
Index: uspace/lib/c/generic/io/chardev.c
===================================================================
--- uspace/lib/c/generic/io/chardev.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/io/chardev.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -91,8 +91,11 @@
  * @param size Maximum number of bytes to read
  * @param nread Place to store actual number of bytes read
+ * @param flags @c chardev_f_nonblock to return immediately even if no
+ *              bytes are available
  *
  * @return EOK on success or non-zero error code
  */
-errno_t chardev_read(chardev_t *chardev, void *buf, size_t size, size_t *nread)
+errno_t chardev_read(chardev_t *chardev, void *buf, size_t size, size_t *nread,
+    chardev_flags_t flags)
 {
 	async_exch_t *exch = async_exchange_begin(chardev->sess);
@@ -104,5 +107,5 @@
 
 	ipc_call_t answer;
-	aid_t req = async_send_0(exch, CHARDEV_READ, &answer);
+	aid_t req = async_send_1(exch, CHARDEV_READ, flags, &answer);
 	errno_t rc = async_data_read_start(exch, buf, size);
 	async_exchange_end(exch);
@@ -122,7 +125,7 @@
 	}
 
-	*nread = IPC_GET_ARG2(answer);
+	*nread = ipc_get_arg2(&answer);
 	/* In case of partial success, ARG1 contains the error code */
-	return (errno_t) IPC_GET_ARG1(answer);
+	return (errno_t) ipc_get_arg1(&answer);
 
 }
@@ -173,7 +176,7 @@
 	}
 
-	*nwritten = IPC_GET_ARG2(answer);
+	*nwritten = ipc_get_arg2(&answer);
 	/* In case of partial success, ARG1 contains the error code */
-	return (errno_t) IPC_GET_ARG1(answer);
+	return (errno_t) ipc_get_arg1(&answer);
 }
 
Index: uspace/lib/c/generic/io/chardev_srv.c
===================================================================
--- uspace/lib/c/generic/io/chardev_srv.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/io/chardev_srv.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -48,5 +48,8 @@
 	size_t size;
 	size_t nread;
+	chardev_flags_t flags;
 	errno_t rc;
+
+	flags = ipc_get_arg1(icall);
 
 	ipc_call_t call;
@@ -70,5 +73,5 @@
 	}
 
-	rc = srv->srvs->ops->read(srv, buf, size, &nread);
+	rc = srv->srvs->ops->read(srv, buf, size, &nread, flags);
 	if (rc != EOK && nread == 0) {
 		async_answer_0(&call, rc);
@@ -151,5 +154,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: uspace/lib/c/generic/io/chargrid.c
===================================================================
--- uspace/lib/c/generic/io/chargrid.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/io/chargrid.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -263,4 +263,7 @@
 void chargrid_set_cursor(chargrid_t *scrbuf, sysarg_t col, sysarg_t row)
 {
+	if (col >= scrbuf->cols || row >= scrbuf->rows)
+		return;
+
 	scrbuf->col = col;
 	scrbuf->row = row;
Index: uspace/lib/c/generic/io/con_srv.c
===================================================================
--- uspace/lib/c/generic/io/con_srv.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/io/con_srv.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -44,18 +44,18 @@
 static errno_t console_ev_encode(cons_event_t *event, ipc_call_t *icall)
 {
-	IPC_SET_ARG1(*icall, event->type);
+	ipc_set_arg1(icall, event->type);
 
 	switch (event->type) {
 	case CEV_KEY:
-		IPC_SET_ARG2(*icall, event->ev.key.type);
-		IPC_SET_ARG3(*icall, event->ev.key.key);
-		IPC_SET_ARG4(*icall, event->ev.key.mods);
-		IPC_SET_ARG5(*icall, event->ev.key.c);
+		ipc_set_arg2(icall, event->ev.key.type);
+		ipc_set_arg3(icall, event->ev.key.key);
+		ipc_set_arg4(icall, event->ev.key.mods);
+		ipc_set_arg5(icall, event->ev.key.c);
 		break;
 	case CEV_POS:
-		IPC_SET_ARG2(*icall, (event->ev.pos.pos_id << 16) | (event->ev.pos.type & 0xffff));
-		IPC_SET_ARG3(*icall, event->ev.pos.btn_num);
-		IPC_SET_ARG4(*icall, event->ev.pos.hpos);
-		IPC_SET_ARG5(*icall, event->ev.pos.vpos);
+		ipc_set_arg2(icall, (event->ev.pos.pos_id << 16) | (event->ev.pos.type & 0xffff));
+		ipc_set_arg3(icall, event->ev.pos.btn_num);
+		ipc_set_arg4(icall, event->ev.pos.hpos);
+		ipc_set_arg5(icall, event->ev.pos.vpos);
 		break;
 	default:
@@ -158,6 +158,6 @@
 	sysarg_t row;
 
-	col = IPC_GET_ARG1(*icall);
-	row = IPC_GET_ARG2(*icall);
+	col = ipc_get_arg1(icall);
+	row = ipc_get_arg2(icall);
 
 	if (srv->srvs->ops->set_pos == NULL) {
@@ -218,5 +218,5 @@
 	console_style_t style;
 
-	style = IPC_GET_ARG1(*icall);
+	style = ipc_get_arg1(icall);
 
 	if (srv->srvs->ops->set_style == NULL) {
@@ -235,7 +235,7 @@
 	console_color_attr_t flags;
 
-	bgcolor = IPC_GET_ARG1(*icall);
-	fgcolor = IPC_GET_ARG2(*icall);
-	flags = IPC_GET_ARG3(*icall);
+	bgcolor = ipc_get_arg1(icall);
+	fgcolor = ipc_get_arg2(icall);
+	flags = ipc_get_arg3(icall);
 
 	if (srv->srvs->ops->set_color == NULL) {
@@ -253,6 +253,6 @@
 	pixel_t fgcolor;
 
-	bgcolor = IPC_GET_ARG1(*icall);
-	fgcolor = IPC_GET_ARG2(*icall);
+	bgcolor = ipc_get_arg1(icall);
+	fgcolor = ipc_get_arg2(icall);
 
 	if (srv->srvs->ops->set_rgb_color == NULL) {
@@ -269,5 +269,5 @@
 	bool show;
 
-	show = IPC_GET_ARG1(*icall);
+	show = ipc_get_arg1(icall);
 
 	if (srv->srvs->ops->set_cursor_visibility == NULL) {
@@ -303,6 +303,6 @@
 	}
 
-	async_answer_5(icall, rc, IPC_GET_ARG1(result), IPC_GET_ARG2(result),
-	    IPC_GET_ARG3(result), IPC_GET_ARG4(result), IPC_GET_ARG5(result));
+	async_answer_5(icall, rc, ipc_get_arg1(&result), ipc_get_arg2(&result),
+	    ipc_get_arg3(&result), ipc_get_arg4(&result), ipc_get_arg5(&result));
 }
 
@@ -364,5 +364,5 @@
 			break;
 
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: uspace/lib/c/generic/io/console.c
===================================================================
--- uspace/lib/c/generic/io/console.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/io/console.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -156,19 +156,19 @@
 static errno_t console_ev_decode(ipc_call_t *call, cons_event_t *event)
 {
-	event->type = IPC_GET_ARG1(*call);
+	event->type = ipc_get_arg1(call);
 
 	switch (event->type) {
 	case CEV_KEY:
-		event->ev.key.type = IPC_GET_ARG2(*call);
-		event->ev.key.key = IPC_GET_ARG3(*call);
-		event->ev.key.mods = IPC_GET_ARG4(*call);
-		event->ev.key.c = IPC_GET_ARG5(*call);
+		event->ev.key.type = ipc_get_arg2(call);
+		event->ev.key.key = ipc_get_arg3(call);
+		event->ev.key.mods = ipc_get_arg4(call);
+		event->ev.key.c = ipc_get_arg5(call);
 		break;
 	case CEV_POS:
-		event->ev.pos.pos_id = IPC_GET_ARG2(*call) >> 16;
-		event->ev.pos.type = IPC_GET_ARG2(*call) & 0xffff;
-		event->ev.pos.btn_num = IPC_GET_ARG3(*call);
-		event->ev.pos.hpos = IPC_GET_ARG4(*call);
-		event->ev.pos.vpos = IPC_GET_ARG5(*call);
+		event->ev.pos.pos_id = ipc_get_arg2(call) >> 16;
+		event->ev.pos.type = ipc_get_arg2(call) & 0xffff;
+		event->ev.pos.btn_num = ipc_get_arg3(call);
+		event->ev.pos.hpos = ipc_get_arg4(call);
+		event->ev.pos.vpos = ipc_get_arg5(call);
 		break;
 	default:
Index: uspace/lib/c/generic/io/input.c
===================================================================
--- uspace/lib/c/generic/io/input.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/io/input.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -112,8 +112,8 @@
 	errno_t rc;
 
-	type = IPC_GET_ARG1(*call);
-	key = IPC_GET_ARG2(*call);
-	mods = IPC_GET_ARG3(*call);
-	c = IPC_GET_ARG4(*call);
+	type = ipc_get_arg1(call);
+	key = ipc_get_arg2(call);
+	mods = ipc_get_arg3(call);
+	c = ipc_get_arg4(call);
 
 	rc = input->ev_ops->key(input, type, key, mods, c);
@@ -127,6 +127,6 @@
 	errno_t rc;
 
-	dx = IPC_GET_ARG1(*call);
-	dy = IPC_GET_ARG2(*call);
+	dx = ipc_get_arg1(call);
+	dy = ipc_get_arg2(call);
 
 	rc = input->ev_ops->move(input, dx, dy);
@@ -142,8 +142,8 @@
 	errno_t rc;
 
-	x = IPC_GET_ARG1(*call);
-	y = IPC_GET_ARG2(*call);
-	max_x = IPC_GET_ARG3(*call);
-	max_y = IPC_GET_ARG4(*call);
+	x = ipc_get_arg1(call);
+	y = ipc_get_arg2(call);
+	max_x = ipc_get_arg3(call);
+	max_y = ipc_get_arg4(call);
 
 	rc = input->ev_ops->abs_move(input, x, y, max_x, max_y);
@@ -157,6 +157,6 @@
 	errno_t rc;
 
-	bnum = IPC_GET_ARG1(*call);
-	press = IPC_GET_ARG2(*call);
+	bnum = ipc_get_arg1(call);
+	press = ipc_get_arg2(call);
 
 	rc = input->ev_ops->button(input, bnum, press);
@@ -172,10 +172,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			return;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case INPUT_EVENT_ACTIVE:
 			input_ev_active(input, &call);
Index: uspace/lib/c/generic/io/log.c
===================================================================
--- uspace/lib/c/generic/io/log.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/io/log.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -208,5 +208,5 @@
 		return parent;
 
-	return IPC_GET_ARG1(answer);
+	return ipc_get_arg1(&answer);
 }
 
Index: uspace/lib/c/generic/io/output.c
===================================================================
--- uspace/lib/c/generic/io/output.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/io/output.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -100,5 +100,5 @@
 		return 0;
 
-	return (frontbuf_handle_t) IPC_GET_ARG1(answer);
+	return (frontbuf_handle_t) ipc_get_arg1(&answer);
 }
 
Index: uspace/lib/c/generic/ipc.c
===================================================================
--- uspace/lib/c/generic/ipc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/ipc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -71,5 +71,5 @@
 {
 	return __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST,
-	    CAP_HANDLE_RAW(phandle), imethod, arg1, arg2, arg3,
+	    cap_handle_raw(phandle), imethod, arg1, arg2, arg3,
 	    (sysarg_t) label);
 }
@@ -98,13 +98,13 @@
 	ipc_call_t data;
 
-	IPC_SET_IMETHOD(data, imethod);
-	IPC_SET_ARG1(data, arg1);
-	IPC_SET_ARG2(data, arg2);
-	IPC_SET_ARG3(data, arg3);
-	IPC_SET_ARG4(data, arg4);
-	IPC_SET_ARG5(data, arg5);
+	ipc_set_imethod(&data, imethod);
+	ipc_set_arg1(&data, arg1);
+	ipc_set_arg2(&data, arg2);
+	ipc_set_arg3(&data, arg3);
+	ipc_set_arg4(&data, arg4);
+	ipc_set_arg5(&data, arg5);
 
 	return __SYSCALL3(SYS_IPC_CALL_ASYNC_SLOW,
-	    CAP_HANDLE_RAW(phandle), (sysarg_t) &data,
+	    cap_handle_raw(phandle), (sysarg_t) &data,
 	    (sysarg_t) label);
 }
@@ -130,5 +130,5 @@
 {
 	return (errno_t) __SYSCALL6(SYS_IPC_ANSWER_FAST,
-	    CAP_HANDLE_RAW(chandle), (sysarg_t) retval, arg1, arg2, arg3, arg4);
+	    cap_handle_raw(chandle), (sysarg_t) retval, arg1, arg2, arg3, arg4);
 }
 
@@ -152,13 +152,13 @@
 	ipc_call_t data;
 
-	IPC_SET_RETVAL(data, retval);
-	IPC_SET_ARG1(data, arg1);
-	IPC_SET_ARG2(data, arg2);
-	IPC_SET_ARG3(data, arg3);
-	IPC_SET_ARG4(data, arg4);
-	IPC_SET_ARG5(data, arg5);
+	ipc_set_retval(&data, retval);
+	ipc_set_arg1(&data, arg1);
+	ipc_set_arg2(&data, arg2);
+	ipc_set_arg3(&data, arg3);
+	ipc_set_arg4(&data, arg4);
+	ipc_set_arg5(&data, arg5);
 
 	return (errno_t) __SYSCALL2(SYS_IPC_ANSWER_SLOW,
-	    CAP_HANDLE_RAW(chandle), (sysarg_t) &data);
+	    cap_handle_raw(chandle), (sysarg_t) &data);
 }
 
@@ -186,5 +186,5 @@
 errno_t ipc_hangup(cap_phone_handle_t phandle)
 {
-	return (errno_t) __SYSCALL1(SYS_IPC_HANGUP, CAP_HANDLE_RAW(phandle));
+	return (errno_t) __SYSCALL1(SYS_IPC_HANGUP, cap_handle_raw(phandle));
 }
 
@@ -210,5 +210,5 @@
 {
 	return (errno_t) __SYSCALL6(SYS_IPC_FORWARD_FAST,
-	    CAP_HANDLE_RAW(chandle), CAP_HANDLE_RAW(phandle), imethod, arg1,
+	    cap_handle_raw(chandle), cap_handle_raw(phandle), imethod, arg1,
 	    arg2, mode);
 }
@@ -220,13 +220,13 @@
 	ipc_call_t data;
 
-	IPC_SET_IMETHOD(data, imethod);
-	IPC_SET_ARG1(data, arg1);
-	IPC_SET_ARG2(data, arg2);
-	IPC_SET_ARG3(data, arg3);
-	IPC_SET_ARG4(data, arg4);
-	IPC_SET_ARG5(data, arg5);
+	ipc_set_imethod(&data, imethod);
+	ipc_set_arg1(&data, arg1);
+	ipc_set_arg2(&data, arg2);
+	ipc_set_arg3(&data, arg3);
+	ipc_set_arg4(&data, arg4);
+	ipc_set_arg5(&data, arg5);
 
 	return (errno_t) __SYSCALL4(SYS_IPC_FORWARD_SLOW,
-	    CAP_HANDLE_RAW(chandle), CAP_HANDLE_RAW(phandle), (sysarg_t) &data,
+	    cap_handle_raw(chandle), cap_handle_raw(phandle), (sysarg_t) &data,
 	    mode);
 }
Index: uspace/lib/c/generic/iplink.c
===================================================================
--- uspace/lib/c/generic/iplink.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/iplink.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -248,5 +248,5 @@
 	iplink_recv_sdu_t sdu;
 
-	ip_ver_t ver = IPC_GET_ARG1(*icall);
+	ip_ver_t ver = ipc_get_arg1(icall);
 
 	errno_t rc = async_data_write_accept(&sdu.data, false, 0, 0, 0,
@@ -287,10 +287,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			return;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case IPLINK_EV_RECV:
 			iplink_ev_recv(iplink, &call);
Index: uspace/lib/c/generic/iplink_srv.c
===================================================================
--- uspace/lib/c/generic/iplink_srv.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/iplink_srv.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -162,6 +162,6 @@
 	iplink_sdu_t sdu;
 
-	sdu.src = IPC_GET_ARG1(*icall);
-	sdu.dest = IPC_GET_ARG2(*icall);
+	sdu.src = ipc_get_arg1(icall);
+	sdu.dest = ipc_get_arg2(icall);
 
 	errno_t rc = async_data_write_accept(&sdu.data, false, 0, 0, 0,
@@ -253,5 +253,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: uspace/lib/c/generic/irc.c
===================================================================
--- uspace/lib/c/generic/irc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/irc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -36,4 +36,5 @@
 #include <async.h>
 #include <errno.h>
+#include <fibril.h>
 #include <ipc/irc.h>
 #include <ipc/services.h>
Index: uspace/lib/c/generic/irq.c
===================================================================
--- uspace/lib/c/generic/irq.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/irq.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -83,5 +83,5 @@
 {
 	return (errno_t) __SYSCALL1(SYS_IPC_IRQ_UNSUBSCRIBE,
-	    CAP_HANDLE_RAW(cap));
+	    cap_handle_raw(cap));
 }
 
Index: uspace/lib/c/generic/loc.c
===================================================================
--- uspace/lib/c/generic/loc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/loc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -62,10 +62,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			return;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case LOC_EVENT_CAT_CHANGE:
 			fibril_mutex_lock(&loc_callback_mutex);
@@ -239,5 +239,5 @@
 }
 
-/** Register new driver with loc. */
+/** Register new server with loc. */
 errno_t loc_server_register(const char *name)
 {
@@ -303,5 +303,5 @@
 
 	if (sid != NULL)
-		*sid = (service_id_t) IPC_GET_ARG1(answer);
+		*sid = (service_id_t) ipc_get_arg1(&answer);
 
 	return retval;
@@ -359,5 +359,5 @@
 
 	if (handle != NULL)
-		*handle = (service_id_t) IPC_GET_ARG1(answer);
+		*handle = (service_id_t) ipc_get_arg1(&answer);
 
 	return retval;
@@ -404,5 +404,5 @@
 		return retval;
 
-	act_size = IPC_GET_ARG2(dreply);
+	act_size = ipc_get_arg2(&dreply);
 	assert(act_size <= LOC_NAME_MAXLEN);
 	name_buf[act_size] = '\0';
@@ -492,5 +492,5 @@
 
 	if (handle != NULL)
-		*handle = (service_id_t) IPC_GET_ARG1(answer);
+		*handle = (service_id_t) ipc_get_arg1(&answer);
 
 	return retval;
@@ -541,5 +541,5 @@
 
 	if (cat_id != NULL)
-		*cat_id = (category_id_t) IPC_GET_ARG1(answer);
+		*cat_id = (category_id_t) ipc_get_arg1(&answer);
 
 	return retval;
@@ -778,5 +778,5 @@
 	}
 
-	*act_size = IPC_GET_ARG1(answer);
+	*act_size = ipc_get_arg1(&answer);
 	return EOK;
 }
Index: uspace/lib/c/generic/mem.c
===================================================================
--- uspace/lib/c/generic/mem.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/mem.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,7 +38,9 @@
 #include <stddef.h>
 #include <stdint.h>
+#include "private/cc.h"
 
 /** Fill memory block with a constant value. */
-void *memset(void *dest, int b, size_t n)
+ATTRIBUTE_OPTIMIZE_NO_TLDP
+    void *memset(void *dest, int b, size_t n)
 {
 	char *pb;
@@ -114,5 +116,6 @@
 
 /** Copy memory block. */
-void *memcpy(void *dst, const void *src, size_t n)
+ATTRIBUTE_OPTIMIZE_NO_TLDP
+    void *memcpy(void *dst, const void *src, size_t n)
 {
 	size_t i;
Index: uspace/lib/c/generic/pci.c
===================================================================
--- uspace/lib/c/generic/pci.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/generic/pci.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2019 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 libc
+ * @{
+ */
+/** @file PCI control service API
+ */
+
+#include <abi/ipc/interfaces.h>
+#include <errno.h>
+#include <ipc/devman.h>
+#include <ipc/services.h>
+#include <ipc/pci.h>
+#include <loc.h>
+#include <pci.h>
+#include <stdlib.h>
+#include <types/pci.h>
+
+/** Open PCI service.
+ *
+ * @param svc_id PCI sevice ID
+ * @param rpci   Place to store pointer to PCI service object.
+ *
+ * @return EOK on success, ENOMEM if out of memory, EIO if service
+ *         cannot be contacted.
+ */
+errno_t pci_open(service_id_t svc_id, pci_t **rpci)
+{
+	pci_t *pci;
+	errno_t rc;
+
+	pci = calloc(1, sizeof(pci_t));
+	if (pci == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+
+	pci->sess = loc_service_connect(svc_id, INTERFACE_PCI, 0);
+	if (pci->sess == NULL) {
+		rc = EIO;
+		goto error;
+	}
+
+	*rpci = pci;
+	return EOK;
+error:
+	free(pci);
+	return rc;
+}
+
+/** Close PCI service.
+ *
+ * @param pci PCI service object or @c NULL
+ */
+void pci_close(pci_t *pci)
+{
+	if (pci == NULL)
+		return;
+
+	async_hangup(pci->sess);
+	free(pci);
+}
+
+/** Get list of IDs into a buffer of fixed size.
+ *
+ * @param pci      PCI service
+ * @param method   IPC method
+ * @param arg1     First argument
+ * @param id_buf   Buffer to store IDs
+ * @param buf_size Buffer size
+ * @param act_size Place to store actual size of complete data.
+ *
+ * @return EOK on success or an error code.
+ */
+static errno_t pci_get_ids_once(pci_t *pci, sysarg_t method, sysarg_t arg1,
+    sysarg_t *id_buf, size_t buf_size, size_t *act_size)
+{
+	async_exch_t *exch = async_exchange_begin(pci->sess);
+
+	ipc_call_t answer;
+	aid_t req = async_send_1(exch, method, arg1, &answer);
+	errno_t rc = async_data_read_start(exch, id_buf, buf_size);
+
+	async_exchange_end(exch);
+
+	if (rc != EOK) {
+		async_forget(req);
+		return rc;
+	}
+
+	errno_t retval;
+	async_wait_for(req, &retval);
+
+	if (retval != EOK) {
+		return retval;
+	}
+
+	*act_size = ipc_get_arg1(&answer);
+	return EOK;
+}
+
+/** Get list of IDs.
+ *
+ * Returns an allocated array of service IDs.
+ *
+ * @param pci    PCI service
+ * @param method IPC method
+ * @param arg1   IPC argument 1
+ * @param data   Place to store pointer to array of IDs
+ * @param count  Place to store number of IDs
+ * @return       EOK on success or an error code
+ */
+static errno_t pci_get_ids_internal(pci_t *pci, sysarg_t method, sysarg_t arg1,
+    sysarg_t **data, size_t *count)
+{
+	*data = NULL;
+	*count = 0;
+
+	size_t act_size = 0;
+	errno_t rc = pci_get_ids_once(pci, method, arg1, NULL, 0, &act_size);
+	if (rc != EOK)
+		return rc;
+
+	size_t alloc_size = act_size;
+	service_id_t *ids = malloc(alloc_size);
+	if (ids == NULL)
+		return ENOMEM;
+
+	while (true) {
+		rc = pci_get_ids_once(pci, method, arg1, ids, alloc_size,
+		    &act_size);
+		if (rc != EOK)
+			return rc;
+
+		if (act_size <= alloc_size)
+			break;
+
+		alloc_size = act_size;
+		ids = realloc(ids, alloc_size);
+		if (ids == NULL)
+			return ENOMEM;
+	}
+
+	*count = act_size / sizeof(service_id_t);
+	*data = ids;
+	return EOK;
+}
+
+/** Get list of PCI devices as array of devman handles.
+ *
+ * @param pci PCI service
+ * @param data Place to store pointer to array
+ * @param count Place to store length of array (number of entries)
+ *
+ * @return EOK on success or an error code
+ */
+errno_t pci_get_devices(pci_t *pci, devman_handle_t **data, size_t *count)
+{
+	return pci_get_ids_internal(pci, PCI_GET_DEVICES, 0, data, count);
+}
+
+extern errno_t pci_dev_get_info(pci_t *, devman_handle_t, pci_dev_info_t *);
+
+/** Get PCI device information.
+ *
+ * @param pci PCI service
+ * @param dev_handle Device handle
+ * @param info Place to store device information
+ * @return EOK on success or an error code
+ */
+errno_t pci_dev_get_info(pci_t *pci, devman_handle_t dev_handle,
+    pci_dev_info_t *info)
+{
+	async_exch_t *exch;
+	errno_t retval;
+	ipc_call_t answer;
+
+	exch = async_exchange_begin(pci->sess);
+	aid_t req = async_send_1(exch, PCI_DEV_GET_INFO, dev_handle, &answer);
+
+	errno_t rc = async_data_read_start(exch, info, sizeof(pci_dev_info_t));
+	async_exchange_end(exch);
+	if (rc != EOK) {
+		async_forget(req);
+		return EIO;
+	}
+
+	async_wait_for(req, &retval);
+	if (retval != EOK)
+		return EIO;
+
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/pio_trace.c
===================================================================
--- uspace/lib/c/generic/pio_trace.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/pio_trace.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -81,7 +81,5 @@
 {
 	static pio_regions_t regions = {
-		.list = {
-			.head = { &regions.list.head, &regions.list.head },
-		},
+		.list = LIST_INITIALIZER(regions.list),
 		.guard = FIBRIL_RWLOCK_INITIALIZER(regions.guard),
 	};
Index: uspace/lib/c/generic/private/async.h
===================================================================
--- uspace/lib/c/generic/private/async.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/async.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRIVATE_ASYNC_H_
-#define LIBC_PRIVATE_ASYNC_H_
+#ifndef _LIBC_PRIVATE_ASYNC_H_
+#define _LIBC_PRIVATE_ASYNC_H_
 
 #include <async.h>
Index: uspace/lib/c/generic/private/cc.h
===================================================================
--- uspace/lib/c/generic/private/cc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/generic/private/cc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,52 @@
+/*
+ * 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
+ * Macros related to used compiler (such as GCC-specific attributes).
+ */
+
+#ifndef _LIBC_CC_H_
+#define _LIBC_CC_H_
+
+#ifndef __clang__
+#define ATTRIBUTE_OPTIMIZE(opt) \
+    __attribute__ ((optimize(opt)))
+#else
+#define ATTRIBUTE_OPTIMIZE(opt)
+#endif
+
+#define ATTRIBUTE_OPTIMIZE_NO_TLDP \
+    ATTRIBUTE_OPTIMIZE("-fno-tree-loop-distribute-patterns")
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/generic/private/fibril.h
===================================================================
--- uspace/lib/c/generic/private/fibril.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,6 +27,6 @@
  */
 
-#ifndef LIBC_PRIVATE_FIBRIL_H_
-#define LIBC_PRIVATE_FIBRIL_H_
+#ifndef _LIBC_PRIVATE_FIBRIL_H_
+#define _LIBC_PRIVATE_FIBRIL_H_
 
 #include <adt/list.h>
@@ -35,4 +35,5 @@
 #include <abi/proc/uarg.h>
 #include <fibril.h>
+#include <ipc/common.h>
 
 #include "./futex.h"
Index: uspace/lib/c/generic/private/futex.h
===================================================================
--- uspace/lib/c/generic/private/futex.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/futex.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_FUTEX_H_
-#define LIBC_FUTEX_H_
+#ifndef _LIBC_FUTEX_H_
+#define _LIBC_FUTEX_H_
 
 #include <assert.h>
Index: uspace/lib/c/generic/private/io.h
===================================================================
--- uspace/lib/c/generic/private/io.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/io.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRIVATE_IO_H_
-#define LIBC_PRIVATE_IO_H_
+#ifndef _LIBC_PRIVATE_IO_H_
+#define _LIBC_PRIVATE_IO_H_
 
 #include <loader/pcb.h>
Index: uspace/lib/c/generic/private/libc.h
===================================================================
--- uspace/lib/c/generic/private/libc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/libc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRIVATE_LIBC_H_
-#define LIBC_PRIVATE_LIBC_H_
+#ifndef _LIBC_PRIVATE_LIBC_H_
+#define _LIBC_PRIVATE_LIBC_H_
 
 #include <types/common.h>
Index: uspace/lib/c/generic/private/loader.h
===================================================================
--- uspace/lib/c/generic/private/loader.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/loader.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRIVATE_LOADER_H_
-#define LIBC_PRIVATE_LOADER_H_
+#ifndef _LIBC_PRIVATE_LOADER_H_
+#define _LIBC_PRIVATE_LOADER_H_
 
 #include <loader/loader.h>
Index: uspace/lib/c/generic/private/malloc.h
===================================================================
--- uspace/lib/c/generic/private/malloc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/malloc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRIVATE_MALLOC_H_
-#define LIBC_PRIVATE_MALLOC_H_
+#ifndef _LIBC_PRIVATE_MALLOC_H_
+#define _LIBC_PRIVATE_MALLOC_H_
 
 extern void __malloc_init(void);
Index: uspace/lib/c/generic/private/ns.h
===================================================================
--- uspace/lib/c/generic/private/ns.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/ns.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRIVATE_NS_H_
-#define LIBC_PRIVATE_NS_H_
+#ifndef _LIBC_PRIVATE_NS_H_
+#define _LIBC_PRIVATE_NS_H_
 
 #include <async.h>
Index: uspace/lib/c/generic/private/scanf.h
===================================================================
--- uspace/lib/c/generic/private/scanf.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/scanf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRIVATE_SCANF_H_
-#define LIBC_PRIVATE_SCANF_H_
+#ifndef _LIBC_PRIVATE_SCANF_H_
+#define _LIBC_PRIVATE_SCANF_H_
 
 #include <stddef.h>
Index: uspace/lib/c/generic/private/sstream.h
===================================================================
--- uspace/lib/c/generic/private/sstream.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/sstream.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRIVATE_SSTREAM_H_
-#define LIBC_PRIVATE_SSTREAM_H_
+#ifndef _LIBC_PRIVATE_SSTREAM_H_
+#define _LIBC_PRIVATE_SSTREAM_H_
 
 #include <stdio.h>
Index: uspace/lib/c/generic/private/stdio.h
===================================================================
--- uspace/lib/c/generic/private/stdio.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/stdio.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRIVATE_STDIO_H_
-#define LIBC_PRIVATE_STDIO_H_
+#ifndef _LIBC_PRIVATE_STDIO_H_
+#define _LIBC_PRIVATE_STDIO_H_
 
 #include <adt/list.h>
@@ -40,4 +40,5 @@
 #include <async.h>
 #include <stddef.h>
+#include <offset.h>
 
 /** Maximum characters that can be pushed back by ungetc() */
@@ -54,4 +55,15 @@
 	int (*flush)(FILE *stream);
 } __stream_ops_t;
+
+enum __buffer_state {
+	/** Buffer is empty */
+	_bs_empty,
+
+	/** Buffer contains data to be written */
+	_bs_write,
+
+	/** Buffer contains prefetched data for reading */
+	_bs_read
+};
 
 struct _IO_FILE {
@@ -87,5 +99,5 @@
 
 	/** Buffering type */
-	enum _buffer_type btype;
+	enum __buffer_type btype;
 
 	/** Buffer */
@@ -96,5 +108,5 @@
 
 	/** Buffer state */
-	enum _buffer_state buf_state;
+	enum __buffer_state buf_state;
 
 	/** Buffer I/O pointer */
Index: uspace/lib/c/generic/private/stdlib.h
===================================================================
--- uspace/lib/c/generic/private/stdlib.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/stdlib.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRIVATE_STDLIB_H_
-#define LIBC_PRIVATE_STDLIB_H_
+#ifndef _LIBC_PRIVATE_STDLIB_H_
+#define _LIBC_PRIVATE_STDLIB_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/generic/private/thread.h
===================================================================
--- uspace/lib/c/generic/private/thread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRIVATE_THREAD_H_
-#define LIBC_PRIVATE_THREAD_H_
+#ifndef _LIBC_PRIVATE_THREAD_H_
+#define _LIBC_PRIVATE_THREAD_H_
 
 #include <time.h>
Index: uspace/lib/c/generic/rtld/dynamic.c
===================================================================
--- uspace/lib/c/generic/rtld/dynamic.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/rtld/dynamic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -64,6 +64,6 @@
 		d_ptr = (void *)((uint8_t *)dp->d_un.d_ptr + bias);
 		d_val = dp->d_un.d_val;
-		DPRINTF("tag=%u ptr=0x%x val=%u\n", (unsigned)dp->d_tag,
-		    (unsigned)d_ptr, (unsigned)d_val);
+		DPRINTF("tag=%u ptr=0x%zx val=%zu\n", (unsigned)dp->d_tag,
+		    (uintptr_t)d_ptr, (uintptr_t)d_val);
 
 		switch (dp->d_tag) {
Index: uspace/lib/c/generic/rtld/module.c
===================================================================
--- uspace/lib/c/generic/rtld/module.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/rtld/module.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -50,4 +50,5 @@
 #include <rtld/rtld_arch.h>
 #include <rtld/module.h>
+#include <libarch/rtld/module.h>
 
 #include "../private/libc.h"
@@ -64,6 +65,8 @@
 
 	module = calloc(1, sizeof(module_t));
-	if (module == NULL)
+	if (module == NULL) {
+		DPRINTF("malloc failed\n");
 		return ENOMEM;
+	}
 
 	module->id = rtld_get_next_id(rtld);
@@ -181,10 +184,10 @@
 	char name_buf[NAME_BUF_SIZE];
 	module_t *m;
-	int rc;
+	errno_t rc;
 
 	m = calloc(1, sizeof(module_t));
 	if (m == NULL) {
-		printf("malloc failed\n");
-		exit(1);
+		DPRINTF("malloc failed\n");
+		goto error;
 	}
 
@@ -196,6 +199,6 @@
 
 	if (str_size(name) > NAME_BUF_SIZE - 2) {
-		printf("soname too long. increase NAME_BUF_SIZE\n");
-		exit(1);
+		DPRINTF("soname too long. increase NAME_BUF_SIZE\n");
+		goto error;
 	}
 
@@ -206,8 +209,8 @@
 	DPRINTF("filename:'%s'\n", name_buf);
 
-	rc = elf_load_file_name(name_buf, ELDF_RW, &info);
-	if (rc != EE_OK) {
-		printf("Failed to load '%s'\n", name_buf);
-		exit(1);
+	rc = elf_load_file_name(name_buf, RTLD_MODULE_LDF, &info);
+	if (rc != EOK) {
+		DPRINTF("Failed to load '%s'\n", name_buf);
+		goto error;
 	}
 
@@ -217,7 +220,7 @@
 
 	if (info.dynamic == NULL) {
-		printf("Error: '%s' is not a dynamically-linked object.\n",
+		DPRINTF("Error: '%s' is not a dynamically-linked object.\n",
 		    name_buf);
-		exit(1);
+		goto error;
 	}
 
@@ -242,9 +245,15 @@
 
 	return m;
+
+error:
+	if (m)
+		free(m);
+
+	return NULL;
 }
 
 /** Load all modules on which m (transitively) depends.
  */
-void module_load_deps(module_t *m, mlflags_t flags)
+errno_t module_load_deps(module_t *m, mlflags_t flags)
 {
 	elf_dyn_t *dp;
@@ -273,11 +282,11 @@
 		/* There are no dependencies, so we are done. */
 		m->deps = NULL;
-		return;
+		return EOK;
 	}
 
 	m->deps = malloc(n * sizeof(module_t *));
 	if (!m->deps) {
-		printf("malloc failed\n");
-		exit(1);
+		DPRINTF("malloc failed\n");
+		return ENOMEM;
 	}
 
@@ -293,5 +302,12 @@
 			if (!dm) {
 				dm = module_load(m->rtld, dep_name, flags);
-				module_load_deps(dm, flags);
+				if (!dm) {
+					return EINVAL;
+				}
+
+				errno_t rc = module_load_deps(dm, flags);
+				if (rc != EOK) {
+					return rc;
+				}
 			}
 
@@ -301,4 +317,6 @@
 		++dp;
 	}
+
+	return EOK;
 }
 
Index: uspace/lib/c/generic/rtld/rtld.c
===================================================================
--- uspace/lib/c/generic/rtld/rtld.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/rtld/rtld.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -125,5 +125,8 @@
 
 	DPRINTF("Load all program dependencies\n");
-	module_load_deps(prog, 0);
+	errno_t rc = module_load_deps(prog, 0);
+	if (rc != EOK) {
+		return rc;
+	}
 
 	/* Compute static TLS size */
Index: uspace/lib/c/generic/rtld/symbol.c
===================================================================
--- uspace/lib/c/generic/rtld/symbol.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/rtld/symbol.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -262,5 +262,5 @@
 void *symbol_get_addr(elf_symbol_t *sym, module_t *m, tcb_t *tcb)
 {
-	if (ELF_ST_TYPE(sym->st_info) == STT_TLS) {
+	if (elf_st_type(sym->st_info) == STT_TLS) {
 		if (tcb == NULL)
 			return NULL;
Index: uspace/lib/c/generic/setjmp.c
===================================================================
--- uspace/lib/c/generic/setjmp.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/setjmp.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,6 +38,9 @@
 void longjmp(jmp_buf env, int val)
 {
-	/* __longjmp defined in assembly doesn't "correct" the value. */
-	__longjmp(env, val == 0 ? 1 : val);
+	/*
+	 * The standard requires that longjmp() ensures that val is not zero.
+	 * __context_restore doesn't do that, so we do it here.
+	 */
+	__context_restore(env, val == 0 ? 1 : val);
 }
 
Index: uspace/lib/c/generic/str.c
===================================================================
--- uspace/lib/c/generic/str.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/str.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,3 +1,4 @@
 /*
+ * Copyright (c) 2001-2004 Jakub Jermar
  * Copyright (c) 2005 Martin Decky
  * Copyright (c) 2008 Jiri Svoboda
@@ -33,17 +34,88 @@
  * @{
  */
-/** @file
+
+/**
+ * @file
+ * @brief String functions.
+ *
+ * Strings and characters use the Universal Character Set (UCS). The standard
+ * strings, called just strings are encoded in UTF-8. Wide strings (encoded
+ * in UTF-32) are supported to a limited degree. A single character is
+ * represented as wchar_t.@n
+ *
+ * Overview of the terminology:@n
+ *
+ *  Term                  Meaning
+ *  --------------------  ----------------------------------------------------
+ *  byte                  8 bits stored in uint8_t (unsigned 8 bit integer)
+ *
+ *  character             UTF-32 encoded Unicode character, stored in wchar_t
+ *                        (signed 32 bit integer), code points 0 .. 1114111
+ *                        are valid
+ *
+ *  ASCII character       7 bit encoded ASCII character, stored in char
+ *                        (usually signed 8 bit integer), code points 0 .. 127
+ *                        are valid
+ *
+ *  string                UTF-8 encoded NULL-terminated Unicode string, char *
+ *
+ *  wide string           UTF-32 encoded NULL-terminated Unicode string,
+ *                        wchar_t *
+ *
+ *  [wide] string size    number of BYTES in a [wide] string (excluding
+ *                        the NULL-terminator), size_t
+ *
+ *  [wide] string length  number of CHARACTERS in a [wide] string (excluding
+ *                        the NULL-terminator), size_t
+ *
+ *  [wide] string width   number of display cells on a monospace display taken
+ *                        by a [wide] string, size_t
+ *
+ *
+ * Overview of string metrics:@n
+ *
+ *  Metric  Abbrev.  Type     Meaning
+ *  ------  ------   ------   -------------------------------------------------
+ *  size    n        size_t   number of BYTES in a string (excluding the
+ *                            NULL-terminator)
+ *
+ *  length  l        size_t   number of CHARACTERS in a string (excluding the
+ *                            null terminator)
+ *
+ *  width  w         size_t   number of display cells on a monospace display
+ *                            taken by a string
+ *
+ *
+ * Function naming prefixes:@n
+ *
+ *  chr_    operate on characters
+ *  ascii_  operate on ASCII characters
+ *  str_    operate on strings
+ *  wstr_   operate on wide strings
+ *
+ *  [w]str_[n|l|w]  operate on a prefix limited by size, length
+ *                  or width
+ *
+ *
+ * A specific character inside a [wide] string can be referred to by:@n
+ *
+ *  pointer (char *, wchar_t *)
+ *  byte offset (size_t)
+ *  character index (size_t)
+ *
  */
 
 #include <str.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
 #include <stdlib.h>
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
+
 #include <align.h>
 #include <mem.h>
-#include <limits.h>
 
 /** Check the condition if wchar_t is signed */
@@ -747,4 +819,5 @@
 	/* There must be space for a null terminator in the buffer. */
 	assert(size > 0);
+	assert(src != NULL);
 
 	size_t src_off = 0;
@@ -1311,7 +1384,7 @@
 {
 	size_t size = str_size(src) + 1;
-	char *dest = (char *) malloc(size);
-	if (dest == NULL)
-		return (char *) NULL;
+	char *dest = malloc(size);
+	if (!dest)
+		return NULL;
 
 	str_cpy(dest, size, src);
@@ -1345,7 +1418,7 @@
 		size = n;
 
-	char *dest = (char *) malloc(size + 1);
-	if (dest == NULL)
-		return (char *) NULL;
+	char *dest = malloc(size + 1);
+	if (!dest)
+		return NULL;
 
 	str_ncpy(dest, size + 1, src, size);
Index: uspace/lib/c/generic/string.c
===================================================================
--- uspace/lib/c/generic/string.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/string.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,11 +33,9 @@
  */
 
-/* Prevent an error from being generated */
-#undef _HELENOS_SOURCE
+#include <errno.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <str_error.h>
 #include <string.h>
-#define _HELENOS_SOURCE
-
-#include <stddef.h>
-#include <str_error.h>
 
 /** Copy string.
@@ -504,4 +502,71 @@
 }
 
+/** Return number of characters in string with length limit.
+ *
+ * @param s String
+ * @param maxlen Maximum number of characters to read
+ * @return Number of characters preceding the null character, at most @a maxlen.
+ */
+size_t strnlen(const char *s, size_t maxlen)
+{
+	size_t n;
+
+	n = 0;
+	while (n < maxlen && *s != '\0') {
+		++s;
+		++n;
+	}
+
+	return n;
+}
+
+/** Allocate a new duplicate of string.
+ *
+ * @param s String to duplicate
+ * @return New string or @c NULL on failure (in which case @c errno is set
+ *         to ENOMEM).
+ */
+char *strdup(const char *s)
+{
+	size_t sz;
+	char *dup;
+
+	sz = strlen(s);
+	dup = malloc(sz + 1);
+	if (dup == NULL) {
+		errno = ENOMEM;
+		return NULL;
+	}
+
+	strcpy(dup, s);
+	return dup;
+}
+
+/** Allocate a new duplicate of string with length limit.
+ *
+ * Creates a new duplicate of @a s. If @a s is longer than @a n characters,
+ * only @a n characters are copied and a null character is appended.
+ *
+ * @param s String to duplicate
+ * @param n Maximum number of characters to copy
+ * @return New string or @c NULL on failure (in which case @c errno is set
+ *         to ENOMEM).
+ */
+char *strndup(const char *s, size_t n)
+{
+	size_t sz;
+	char *dup;
+
+	sz = strnlen(s, n);
+	dup = malloc(sz + 1);
+	if (dup == NULL) {
+		errno = ENOMEM;
+		return NULL;
+	}
+
+	strncpy(dup, s, sz);
+	return dup;
+}
+
 /** @}
  */
Index: uspace/lib/c/generic/task.c
===================================================================
--- uspace/lib/c/generic/task.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/task.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -374,6 +374,6 @@
 
 	if (rc == EOK) {
-		*texit = IPC_GET_ARG1(wait->result);
-		*retval = IPC_GET_ARG2(wait->result);
+		*texit = ipc_get_arg1(&wait->result);
+		*retval = ipc_get_arg2(&wait->result);
 	}
 
Index: uspace/lib/c/generic/thread/fibril.c
===================================================================
--- uspace/lib/c/generic/thread/fibril.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/thread/fibril.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -550,6 +550,5 @@
 		return 0;
 
-	fibril->stack_size = (stksz == FIBRIL_DFLT_STK_SIZE) ?
-	    stack_size_get() : stksz;
+	fibril->stack_size = stksz;
 	fibril->stack = as_area_create(AS_AREA_ANY, fibril->stack_size,
 	    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE | AS_AREA_GUARD |
@@ -572,4 +571,9 @@
 	context_create(&fibril->ctx, &sctx);
 	return (fid_t) fibril;
+}
+
+fid_t fibril_create(errno_t (*func)(void *), void *arg)
+{
+	return fibril_create_generic(func, arg, stack_size_get());
 }
 
Index: uspace/lib/c/generic/time.c
===================================================================
--- uspace/lib/c/generic/time.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/time.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -79,5 +79,5 @@
 clock_t clock(void)
 {
-	static_assert(CLOCKS_PER_SEC == 1000000);
+	static_assert(CLOCKS_PER_SEC == 1000000, "");
 
 	size_t count;
Index: uspace/lib/c/generic/uuid.c
===================================================================
--- uspace/lib/c/generic/uuid.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/uuid.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,4 +39,5 @@
 #include <stddef.h>
 #include <str.h>
+#include <stdio.h>
 
 /** Generate UUID.
@@ -64,8 +65,7 @@
 
 	/* Version 4 UUID from random or pseudo-random numbers */
-	uuid->b[8] = (uuid->b[8] & ~0xc0) | 0x40;
-	uuid->b[6] = (uuid->b[6] & 0xf0) | 0x40;
+	uuid->b[6] = (uuid->b[6] & 0x0f) | 0x40;
+	uuid->b[8] = (uuid->b[8] & 0x3f) | 0x80;
 
-	return EOK;
 error:
 	rndgen_destroy(rndgen);
@@ -139,5 +139,5 @@
 
 	rc = str_uint64_t(str + 24, &eptr, 16, false, &node);
-	if (rc != EOK || eptr != str + 36 || *eptr != '\0')
+	if (rc != EOK || eptr != str + 36)
 		return EINVAL;
 
@@ -176,7 +176,22 @@
  * @return EOK on success, ENOMEM if out of memory
  */
-errno_t uuid_format(uuid_t *uuid, char **rstr)
+errno_t uuid_format(uuid_t *uuid, char **rstr, bool uppercase)
 {
-	return ENOTSUP;
+	size_t size = 37;
+	char *str = malloc(sizeof(char) * size);
+	if (str == NULL)
+		return ENOMEM;
+
+	const char *format = "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x";
+	if (uppercase)
+		format = "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X";
+
+	int ret = snprintf(str, size, format, uuid->b[0], uuid->b[1], uuid->b[2], uuid->b[3], uuid->b[4], uuid->b[5], uuid->b[6], uuid->b[7], uuid->b[8], uuid->b[9], uuid->b[10], uuid->b[11], uuid->b[12], uuid->b[13], uuid->b[14], uuid->b[15]);
+
+	if (ret != 36)
+		return EINVAL;
+
+	*rstr = str;
+	return EOK;
 }
 
Index: uspace/lib/c/generic/vbd.c
===================================================================
--- uspace/lib/c/generic/vbd.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/vbd.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -190,5 +190,5 @@
 	}
 
-	*act_size = IPC_GET_ARG1(answer);
+	*act_size = ipc_get_arg1(&answer);
 	return EOK;
 }
@@ -300,5 +300,5 @@
 		return EIO;
 
-	*rpart = (vbd_part_id_t)IPC_GET_ARG1(answer);
+	*rpart = (vbd_part_id_t)ipc_get_arg1(&answer);
 	return EOK;
 
Index: uspace/lib/c/generic/vfs/vfs.c
===================================================================
--- uspace/lib/c/generic/vfs/vfs.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/vfs/vfs.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -641,5 +641,5 @@
 
 	if (mountedfd)
-		*mountedfd = (int) IPC_GET_ARG1(answer);
+		*mountedfd = (int) ipc_get_arg1(&answer);
 
 	if (rc != EOK)
@@ -903,5 +903,5 @@
 		return rc;
 
-	*nread = (ssize_t) IPC_GET_ARG1(answer);
+	*nread = (ssize_t) ipc_get_arg1(&answer);
 	return EOK;
 }
@@ -1283,5 +1283,5 @@
 		return (errno_t) rc;
 
-	*handle = (int) IPC_GET_ARG1(answer);
+	*handle = (int) ipc_get_arg1(&answer);
 	return EOK;
 }
@@ -1367,5 +1367,5 @@
 		return rc;
 
-	*nwritten = (ssize_t) IPC_GET_ARG1(answer);
+	*nwritten = (ssize_t) ipc_get_arg1(&answer);
 	return EOK;
 }
Index: uspace/lib/c/generic/vol.c
===================================================================
--- uspace/lib/c/generic/vol.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/vol.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -127,5 +127,5 @@
 	}
 
-	*act_size = IPC_GET_ARG1(answer);
+	*act_size = ipc_get_arg1(&answer);
 	return EOK;
 }
@@ -220,5 +220,5 @@
  * @param vol Volume service
  * @param sid Service ID of the partition
- * @param vinfo Place to sore partition information
+ * @param vinfo Place to store partition information
  * @return EOK on success or an error code
  */
@@ -578,5 +578,5 @@
  * @param vol Volume service
  * @param vid Volume ID
- * @param vinfo Place to sore volume configuration information
+ * @param vinfo Place to store volume configuration information
  * @return EOK on success or an error code
  */
Index: uspace/lib/c/include/adt/checksum.h
===================================================================
--- uspace/lib/c/include/adt/checksum.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/adt/checksum.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_CHECKSUM_H_
-#define LIBC_CHECKSUM_H_
+#ifndef _LIBC_CHECKSUM_H_
+#define _LIBC_CHECKSUM_H_
 
 #include <stddef.h>
Index: uspace/lib/c/include/adt/circ_buf.h
===================================================================
--- uspace/lib/c/include/adt/circ_buf.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/adt/circ_buf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_CIRC_BUF_H_
-#define LIBC_CIRC_BUF_H_
+#ifndef _LIBC_CIRC_BUF_H_
+#define _LIBC_CIRC_BUF_H_
 
 #include <errno.h>
Index: uspace/lib/c/include/adt/fifo.h
===================================================================
--- uspace/lib/c/include/adt/fifo.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/adt/fifo.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -43,6 +43,6 @@
  */
 
-#ifndef LIBC_FIFO_H_
-#define LIBC_FIFO_H_
+#ifndef _LIBC_FIFO_H_
+#define _LIBC_FIFO_H_
 
 #include <stdlib.h>
Index: uspace/lib/c/include/adt/gcdlcm.h
===================================================================
--- uspace/lib/c/include/adt/gcdlcm.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/adt/gcdlcm.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_GCDLCM_H_
-#define LIBC_GCDLCM_H_
+#ifndef _LIBC_GCDLCM_H_
+#define _LIBC_GCDLCM_H_
 
 #include <stddef.h>
Index: uspace/lib/c/include/adt/hash.h
===================================================================
--- uspace/lib/c/include/adt/hash.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/adt/hash.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -32,6 +32,6 @@
 /** @file
  */
-#ifndef LIBC_ADT_HASH_H_
-#define LIBC_ADT_HASH_H_
+#ifndef _LIBC_ADT_HASH_H_
+#define _LIBC_ADT_HASH_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/adt/hash_table.h
===================================================================
--- uspace/lib/c/include/adt/hash_table.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/adt/hash_table.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,6 +35,6 @@
  */
 
-#ifndef LIBC_HASH_TABLE_H_
-#define LIBC_HASH_TABLE_H_
+#ifndef _LIBC_HASH_TABLE_H_
+#define _LIBC_HASH_TABLE_H_
 
 #include <adt/list.h>
@@ -53,5 +53,5 @@
 
 	/** Returns the hash of the key. */
-	size_t (*key_hash)(void *key);
+	size_t (*key_hash)(const void *key);
 
 	/** True if the items are equal (have the same lookup keys). */
@@ -59,5 +59,5 @@
 
 	/** Returns true if the key is equal to the item's lookup key. */
-	bool (*key_equal)(void *key, const ht_link_t *item);
+	bool (*key_equal)(const void *key, const ht_link_t *item);
 
 	/** Hash table item removal callback.
@@ -94,8 +94,8 @@
 extern void hash_table_insert(hash_table_t *, ht_link_t *);
 extern bool hash_table_insert_unique(hash_table_t *, ht_link_t *);
-extern ht_link_t *hash_table_find(const hash_table_t *, void *);
+extern ht_link_t *hash_table_find(const hash_table_t *, const void *);
 extern ht_link_t *hash_table_find_next(const hash_table_t *, ht_link_t *,
     ht_link_t *);
-extern size_t hash_table_remove(hash_table_t *, void *);
+extern size_t hash_table_remove(hash_table_t *, const void *);
 extern void hash_table_remove_item(hash_table_t *, ht_link_t *);
 extern void hash_table_apply(hash_table_t *, bool (*)(ht_link_t *, void *),
Index: uspace/lib/c/include/adt/list.h
===================================================================
--- uspace/lib/c/include/adt/list.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/adt/list.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_LIST_H_
-#define LIBC_LIST_H_
+#ifndef _LIBC_LIST_H_
+#define _LIBC_LIST_H_
 
 #include <assert.h>
@@ -42,19 +42,14 @@
 #include <stdint.h>
 #include <trace.h>
-
-/** Doubly linked list link. */
-typedef struct link {
-	struct link *prev;  /**< Pointer to the previous item in the list. */
-	struct link *next;  /**< Pointer to the next item in the list. */
-} link_t;
-
-/** Doubly linked list. */
-typedef struct list {
-	link_t head;  /**< List head. Does not have any data. */
-} list_t;
-
-extern bool list_member(const link_t *, const list_t *);
-extern void list_splice(list_t *, link_t *);
-extern unsigned long list_count(const list_t *);
+#include <_bits/decls.h>
+
+#ifndef __cplusplus
+
+/**
+ * We don't define the macros in C++ to avoid polluting headers with
+ * namespaceless names. We don't actually need them, so this is fine.
+ * We still allow including the rest of the file (in `helenos` namespace)
+ * so that we can expose publicly visible types that have list_t members.
+ */
 
 /** Declare and initialize statically allocated list.
@@ -138,4 +133,27 @@
 	assert(!link_used(link))
 
+#define list_pop(list, type, member) \
+	((type *) list_pop_internal(list, \
+	    (list_link_to_void(&(((type *) NULL)->member)) - NULL)))
+
+#endif  /* !__cplusplus */
+
+__HELENOS_DECLS_BEGIN;
+
+/** Doubly linked list link. */
+typedef struct __adt_list_link {
+	struct __adt_list_link *prev;  /**< Pointer to the previous item in the list. */
+	struct __adt_list_link *next;  /**< Pointer to the next item in the list. */
+} link_t;
+
+/** Doubly linked list. */
+typedef struct {
+	link_t head;  /**< List head. Does not have any data. */
+} list_t;
+
+extern bool list_member(const link_t *, const list_t *);
+extern void list_splice(list_t *, link_t *);
+extern unsigned long list_count(const list_t *);
+
 /** Returns true if the link is definitely part of a list. False if not sure. */
 static inline bool link_in_use(const link_t *link)
@@ -151,5 +169,5 @@
  *
  */
-NO_TRACE static inline void link_initialize(link_t *link)
+_NO_TRACE static inline void link_initialize(link_t *link)
 {
 	link->prev = NULL;
@@ -164,5 +182,5 @@
  *
  */
-NO_TRACE static inline void list_initialize(list_t *list)
+_NO_TRACE static inline void list_initialize(list_t *list)
 {
 	list->head.prev = &list->head;
@@ -200,5 +218,5 @@
  *
  */
-NO_TRACE static inline void list_prepend(link_t *link, list_t *list)
+_NO_TRACE static inline void list_prepend(link_t *link, list_t *list)
 {
 	list_insert_after(link, &list->head);
@@ -213,5 +231,5 @@
  *
  */
-NO_TRACE static inline void list_append(link_t *link, list_t *list)
+_NO_TRACE static inline void list_append(link_t *link, list_t *list)
 {
 	list_insert_before(link, &list->head);
@@ -226,5 +244,5 @@
  *
  */
-NO_TRACE static inline void list_remove(link_t *link)
+_NO_TRACE static inline void list_remove(link_t *link)
 {
 	if ((link->prev != NULL) && (link->next != NULL)) {
@@ -243,5 +261,5 @@
  *
  */
-NO_TRACE static inline bool list_empty(const list_t *list)
+_NO_TRACE static inline bool list_empty(const list_t *list)
 {
 	return (list->head.next == &list->head);
@@ -311,5 +329,5 @@
  *
  */
-NO_TRACE static inline void headless_list_split_or_concat(link_t *part1, link_t *part2)
+_NO_TRACE static inline void headless_list_split_or_concat(link_t *part1, link_t *part2)
 {
 	part1->prev->next = part2;
@@ -332,5 +350,5 @@
  *
  */
-NO_TRACE static inline void headless_list_split(link_t *part1, link_t *part2)
+_NO_TRACE static inline void headless_list_split(link_t *part1, link_t *part2)
 {
 	headless_list_split_or_concat(part1, part2);
@@ -347,5 +365,5 @@
  *
  */
-NO_TRACE static inline void headless_list_concat(link_t *part1, link_t *part2)
+_NO_TRACE static inline void headless_list_concat(link_t *part1, link_t *part2)
 {
 	headless_list_split_or_concat(part1, part2);
@@ -362,5 +380,5 @@
  *
  */
-NO_TRACE static inline void list_concat(list_t *list1, list_t *list2)
+_NO_TRACE static inline void list_concat(list_t *list1, list_t *list2)
 {
 	list_splice(list2, list1->head.prev);
@@ -425,7 +443,5 @@
 }
 
-#define list_pop(list, type, member) \
-	((type *) list_pop_internal(list, \
-	    (list_link_to_void(&(((type *) NULL)->member)) - NULL)))
+__HELENOS_DECLS_END;
 
 #endif
Index: uspace/lib/c/include/adt/prodcons.h
===================================================================
--- uspace/lib/c/include/adt/prodcons.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/adt/prodcons.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRODCONS_H_
-#define LIBC_PRODCONS_H_
+#ifndef _LIBC_PRODCONS_H_
+#define _LIBC_PRODCONS_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/include/align.h
===================================================================
--- uspace/lib/c/include/align.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/align.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ALIGN_H_
-#define LIBC_ALIGN_H_
+#ifndef _LIBC_ALIGN_H_
+#define _LIBC_ALIGN_H_
 
 /** Align to the nearest lower address which is a power of two.
Index: uspace/lib/c/include/arg_parse.h
===================================================================
--- uspace/lib/c/include/arg_parse.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/arg_parse.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ARG_PARSE_H_
-#define LIBC_ARG_PARSE_H_
+#ifndef _LIBC_ARG_PARSE_H_
+#define _LIBC_ARG_PARSE_H_
 
 #include <errno.h>
Index: uspace/lib/c/include/as.h
===================================================================
--- uspace/lib/c/include/as.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/as.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_AS_H_
-#define LIBC_AS_H_
+#ifndef _LIBC_AS_H_
+#define _LIBC_AS_H_
 
 #include <types/common.h>
Index: uspace/lib/c/include/assert.h
===================================================================
--- uspace/lib/c/include/assert.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/assert.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,10 +38,14 @@
 // This is in accordance with the C standard.
 
-#ifndef LIBC_ASSERT_H_
-#define LIBC_ASSERT_H_
+#ifndef _LIBC_ASSERT_H_
+#define _LIBC_ASSERT_H_
+
+#include <_bits/decls.h>
 
 #ifndef __cplusplus
-#define static_assert(expr)	_Static_assert(expr, "")
+#define static_assert _Static_assert
 #endif
+
+__C_DECLS_BEGIN;
 
 extern void __helenos_assert_abort(const char *, const char *, unsigned int)
@@ -50,4 +54,6 @@
 extern void __helenos_assert_quick_abort(const char *, const char *, unsigned int)
     __attribute__((noreturn));
+
+__C_DECLS_END;
 
 #endif
Index: uspace/lib/c/include/async.h
===================================================================
--- uspace/lib/c/include/async.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/async.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,13 +33,12 @@
  */
 
-#if ((defined(LIBC_IPC_H_)) && (!defined(LIBC_ASYNC_C_)))
+#if ((defined(_LIBC_IPC_H_)) && (!defined(_LIBC_ASYNC_C_)))
 #error Do not intermix low-level IPC interface and async framework
 #endif
 
-#ifndef LIBC_ASYNC_H_
-#define LIBC_ASYNC_H_
+#ifndef _LIBC_ASYNC_H_
+#define _LIBC_ASYNC_H_
 
 #include <ipc/common.h>
-#include <fibril.h>
 #include <time.h>
 #include <stdbool.h>
@@ -109,32 +108,16 @@
 extern __noreturn void async_manager(void);
 
-#define async_get_call(data) \
-	async_get_call_timeout(data, 0)
-
+extern bool async_get_call(ipc_call_t *);
 extern bool async_get_call_timeout(ipc_call_t *, usec_t);
 
-/*
- * User-friendly wrappers for async_send_fast() and async_send_slow(). The
- * macros are in the form async_send_m(), where m denotes the number of payload
- * arguments. Each macros chooses between the fast and the slow version based
- * on m.
- */
-
-#define async_send_0(exch, method, dataptr) \
-	async_send_fast(exch, method, 0, 0, 0, 0, dataptr)
-#define async_send_1(exch, method, arg1, dataptr) \
-	async_send_fast(exch, method, arg1, 0, 0, 0, dataptr)
-#define async_send_2(exch, method, arg1, arg2, dataptr) \
-	async_send_fast(exch, method, arg1, arg2, 0, 0, dataptr)
-#define async_send_3(exch, method, arg1, arg2, arg3, dataptr) \
-	async_send_fast(exch, method, arg1, arg2, arg3, 0, dataptr)
-#define async_send_4(exch, method, arg1, arg2, arg3, arg4, dataptr) \
-	async_send_fast(exch, method, arg1, arg2, arg3, arg4, dataptr)
-#define async_send_5(exch, method, arg1, arg2, arg3, arg4, arg5, dataptr) \
-	async_send_slow(exch, method, arg1, arg2, arg3, arg4, arg5, dataptr)
-
-extern aid_t async_send_fast(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+extern aid_t async_send_0(async_exch_t *, sysarg_t, ipc_call_t *);
+extern aid_t async_send_1(async_exch_t *, sysarg_t, sysarg_t, ipc_call_t *);
+extern aid_t async_send_2(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    ipc_call_t *);
+extern aid_t async_send_3(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, ipc_call_t *);
+extern aid_t async_send_4(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
     sysarg_t, sysarg_t, ipc_call_t *);
-extern aid_t async_send_slow(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+extern aid_t async_send_5(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
     sysarg_t, sysarg_t, sysarg_t, ipc_call_t *);
 
@@ -199,134 +182,90 @@
  */
 
-extern errno_t async_forward_fast(ipc_call_t *, async_exch_t *, sysarg_t,
+extern errno_t async_forward_0(ipc_call_t *, async_exch_t *, sysarg_t,
+    unsigned int);
+extern errno_t async_forward_1(ipc_call_t *, async_exch_t *, sysarg_t,
+    sysarg_t, unsigned int);
+extern errno_t async_forward_2(ipc_call_t *, async_exch_t *, sysarg_t,
     sysarg_t, sysarg_t, unsigned int);
-extern errno_t async_forward_slow(ipc_call_t *, async_exch_t *, sysarg_t,
+extern errno_t async_forward_3(ipc_call_t *, async_exch_t *, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t, unsigned int);
+extern errno_t async_forward_4(ipc_call_t *, async_exch_t *, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t, sysarg_t, unsigned int);
+extern errno_t async_forward_5(ipc_call_t *, async_exch_t *, sysarg_t,
     sysarg_t, sysarg_t, sysarg_t, sysarg_t, sysarg_t, unsigned int);
 
 /*
- * User-friendly wrappers for async_req_fast() and async_req_slow(). The macros
- * are in the form async_req_m_n(), where m is the number of payload arguments
- * and n is the number of return arguments. The macros decide between the fast
- * and slow verion based on m.
- */
-
-#define async_req_0_0(exch, method) \
-	async_req_fast(exch, method, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)
-#define async_req_0_1(exch, method, r1) \
-	async_req_fast(exch, method, 0, 0, 0, 0, r1, NULL, NULL, NULL, NULL)
-#define async_req_0_2(exch, method, r1, r2) \
-	async_req_fast(exch, method, 0, 0, 0, 0, r1, r2, NULL, NULL, NULL)
-#define async_req_0_3(exch, method, r1, r2, r3) \
-	async_req_fast(exch, method, 0, 0, 0, 0, r1, r2, r3, NULL, NULL)
-#define async_req_0_4(exch, method, r1, r2, r3, r4) \
-	async_req_fast(exch, method, 0, 0, 0, 0, r1, r2, r3, r4, NULL)
-#define async_req_0_5(exch, method, r1, r2, r3, r4, r5) \
-	async_req_fast(exch, method, 0, 0, 0, 0, r1, r2, r3, r4, r5)
-
-#define async_req_1_0(exch, method, arg1) \
-	async_req_fast(exch, method, arg1, 0, 0, 0, NULL, NULL, NULL, NULL, \
-	    NULL)
-#define async_req_1_1(exch, method, arg1, rc1) \
-	async_req_fast(exch, method, arg1, 0, 0, 0, rc1, NULL, NULL, NULL, \
-	    NULL)
-#define async_req_1_2(exch, method, arg1, rc1, rc2) \
-	async_req_fast(exch, method, arg1, 0, 0, 0, rc1, rc2, NULL, NULL, \
-	    NULL)
-#define async_req_1_3(exch, method, arg1, rc1, rc2, rc3) \
-	async_req_fast(exch, method, arg1, 0, 0, 0, rc1, rc2, rc3, NULL, \
-	    NULL)
-#define async_req_1_4(exch, method, arg1, rc1, rc2, rc3, rc4) \
-	async_req_fast(exch, method, arg1, 0, 0, 0, rc1, rc2, rc3, rc4, \
-	    NULL)
-#define async_req_1_5(exch, method, arg1, rc1, rc2, rc3, rc4, rc5) \
-	async_req_fast(exch, method, arg1, 0, 0, 0, rc1, rc2, rc3, rc4, \
-	    rc5)
-
-#define async_req_2_0(exch, method, arg1, arg2) \
-	async_req_fast(exch, method, arg1, arg2, 0, 0, NULL, NULL, NULL, \
-	    NULL, NULL)
-#define async_req_2_1(exch, method, arg1, arg2, rc1) \
-	async_req_fast(exch, method, arg1, arg2, 0, 0, rc1, NULL, NULL, \
-	    NULL, NULL)
-#define async_req_2_2(exch, method, arg1, arg2, rc1, rc2) \
-	async_req_fast(exch, method, arg1, arg2, 0, 0, rc1, rc2, NULL, NULL, \
-	    NULL)
-#define async_req_2_3(exch, method, arg1, arg2, rc1, rc2, rc3) \
-	async_req_fast(exch, method, arg1, arg2, 0, 0, rc1, rc2, rc3, NULL, \
-	    NULL)
-#define async_req_2_4(exch, method, arg1, arg2, rc1, rc2, rc3, rc4) \
-	async_req_fast(exch, method, arg1, arg2, 0, 0, rc1, rc2, rc3, rc4, \
-	    NULL)
-#define async_req_2_5(exch, method, arg1, arg2, rc1, rc2, rc3, rc4, rc5) \
-	async_req_fast(exch, method, arg1, arg2, 0, 0, rc1, rc2, rc3, rc4, \
-	    rc5)
-
-#define async_req_3_0(exch, method, arg1, arg2, arg3) \
-	async_req_fast(exch, method, arg1, arg2, arg3, 0, NULL, NULL, NULL, \
-	    NULL, NULL)
-#define async_req_3_1(exch, method, arg1, arg2, arg3, rc1) \
-	async_req_fast(exch, method, arg1, arg2, arg3, 0, rc1, NULL, NULL, \
-	    NULL, NULL)
-#define async_req_3_2(exch, method, arg1, arg2, arg3, rc1, rc2) \
-	async_req_fast(exch, method, arg1, arg2, arg3, 0, rc1, rc2, NULL, \
-	    NULL, NULL)
-#define async_req_3_3(exch, method, arg1, arg2, arg3, rc1, rc2, rc3) \
-	async_req_fast(exch, method, arg1, arg2, arg3, 0, rc1, rc2, rc3, \
-	    NULL, NULL)
-#define async_req_3_4(exch, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4) \
-	async_req_fast(exch, method, arg1, arg2, arg3, 0, rc1, rc2, rc3, \
-	    rc4, NULL)
-#define async_req_3_5(exch, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4, \
-    rc5) \
-	async_req_fast(exch, method, arg1, arg2, arg3, 0, rc1, rc2, rc3, \
-	    rc4, rc5)
-
-#define async_req_4_0(exch, method, arg1, arg2, arg3, arg4) \
-	async_req_fast(exch, method, arg1, arg2, arg3, arg4, NULL, NULL, \
-	    NULL, NULL, NULL)
-#define async_req_4_1(exch, method, arg1, arg2, arg3, arg4, rc1) \
-	async_req_fast(exch, method, arg1, arg2, arg3, arg4, rc1, NULL, \
-	    NULL, NULL, NULL)
-#define async_req_4_2(exch, method, arg1, arg2, arg3, arg4, rc1, rc2) \
-	async_req_fast(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, NULL, \
-	    NULL, NULL)
-#define async_req_4_3(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3) \
-	async_req_fast(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
-	    NULL, NULL)
-#define async_req_4_4(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
-    rc4) \
-	async_req_fast(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
-	    rc4, NULL)
-#define async_req_4_5(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
-    rc4, rc5) \
-	async_req_fast(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
-	    rc4, rc5)
-
-#define async_req_5_0(exch, method, arg1, arg2, arg3, arg4, arg5) \
-	async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, NULL, \
-	    NULL, NULL, NULL, NULL)
-#define async_req_5_1(exch, method, arg1, arg2, arg3, arg4, arg5, rc1) \
-	async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, \
-	    NULL, NULL, NULL, NULL)
-#define async_req_5_2(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2) \
-	async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
-	    NULL, NULL, NULL)
-#define async_req_5_3(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
-    rc3) \
-	async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
-	    rc3, NULL, NULL)
-#define async_req_5_4(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
-    rc3, rc4) \
-	async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
-	    rc3, rc4, NULL)
-#define async_req_5_5(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
-    rc3, rc4, rc5) \
-	async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
-	    rc3, rc4, rc5)
-
-extern errno_t async_req_fast(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+ * User-friendly wrappers for async_req_*_*().
+ * The functions are in the form async_req_m_n(), where m is the number of
+ * payload arguments and n is the number of return arguments.
+ */
+
+extern errno_t async_req_0_0(async_exch_t *, sysarg_t);
+extern errno_t async_req_0_1(async_exch_t *, sysarg_t, sysarg_t *);
+extern errno_t async_req_0_2(async_exch_t *, sysarg_t, sysarg_t *, sysarg_t *);
+extern errno_t async_req_0_3(async_exch_t *, sysarg_t, sysarg_t *, sysarg_t *,
+    sysarg_t *);
+extern errno_t async_req_0_4(async_exch_t *, sysarg_t, sysarg_t *, sysarg_t *,
+    sysarg_t *, sysarg_t *);
+extern errno_t async_req_0_5(async_exch_t *, sysarg_t, sysarg_t *, sysarg_t *,
+    sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_1_0(async_exch_t *, sysarg_t, sysarg_t);
+extern errno_t async_req_1_1(async_exch_t *, sysarg_t, sysarg_t, sysarg_t *);
+extern errno_t async_req_1_2(async_exch_t *, sysarg_t, sysarg_t, sysarg_t *,
+    sysarg_t *);
+extern errno_t async_req_1_3(async_exch_t *, sysarg_t, sysarg_t, sysarg_t *,
+    sysarg_t *, sysarg_t *);
+extern errno_t async_req_1_4(async_exch_t *, sysarg_t, sysarg_t, sysarg_t *,
+    sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_1_5(async_exch_t *, sysarg_t, sysarg_t, sysarg_t *,
+    sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_2_0(async_exch_t *, sysarg_t, sysarg_t, sysarg_t);
+extern errno_t async_req_2_1(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t *);
+extern errno_t async_req_2_2(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t *, sysarg_t *);
+extern errno_t async_req_2_3(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_2_4(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_2_5(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_3_0(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t);
+extern errno_t async_req_3_1(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t *);
+extern errno_t async_req_3_2(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t *, sysarg_t *);
+extern errno_t async_req_3_3(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_3_4(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_3_5(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_4_0(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t);
+extern errno_t async_req_4_1(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t *);
+extern errno_t async_req_4_2(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t *, sysarg_t *);
+extern errno_t async_req_4_3(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_4_4(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_4_5(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
     sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *,
     sysarg_t *);
-extern errno_t async_req_slow(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+extern errno_t async_req_5_0(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t);
+extern errno_t async_req_5_1(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t, sysarg_t *);
+extern errno_t async_req_5_2(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t, sysarg_t *, sysarg_t *);
+extern errno_t async_req_5_3(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_5_4(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *,
+    sysarg_t *);
+extern errno_t async_req_5_5(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
     sysarg_t, sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *,
     sysarg_t *, sysarg_t *);
@@ -358,15 +297,12 @@
  */
 
-#define async_share_in_start_0_0(exch, size, dst) \
-	async_share_in_start(exch, size, 0, NULL, dst)
-#define async_share_in_start_0_1(exch, size, flags, dst) \
-	async_share_in_start(exch, size, 0, flags, dst)
-#define async_share_in_start_1_0(exch, size, arg, dst) \
-	async_share_in_start(exch, size, arg, NULL, dst)
-#define async_share_in_start_1_1(exch, size, arg, flags, dst) \
-	async_share_in_start(exch, size, arg, flags, dst)
-
-extern errno_t async_share_in_start(async_exch_t *, size_t, sysarg_t,
+extern errno_t async_share_in_start_0_0(async_exch_t *, size_t, void **);
+extern errno_t async_share_in_start_0_1(async_exch_t *, size_t,
     unsigned int *, void **);
+extern errno_t async_share_in_start_1_0(async_exch_t *, size_t, sysarg_t,
+    void **);
+extern errno_t async_share_in_start_1_1(async_exch_t *, size_t, sysarg_t,
+    unsigned int *, void **);
+
 extern bool async_share_in_receive(ipc_call_t *, size_t *);
 extern errno_t async_share_in_finalize(ipc_call_t *, void *, unsigned int);
@@ -376,33 +312,23 @@
 extern errno_t async_share_out_finalize(ipc_call_t *, void **);
 
-/*
- * User-friendly wrappers for async_data_read_forward_fast().
- */
-
-#define async_data_read_forward_0_0(exch, method, answer) \
-	async_data_read_forward_fast(exch, method, 0, 0, 0, 0, NULL)
-#define async_data_read_forward_0_1(exch, method, answer) \
-	async_data_read_forward_fast(exch, method, 0, 0, 0, 0, answer)
-#define async_data_read_forward_1_0(exch, method, arg1, answer) \
-	async_data_read_forward_fast(exch, method, arg1, 0, 0, 0, NULL)
-#define async_data_read_forward_1_1(exch, method, arg1, answer) \
-	async_data_read_forward_fast(exch, method, arg1, 0, 0, 0, answer)
-#define async_data_read_forward_2_0(exch, method, arg1, arg2, answer) \
-	async_data_read_forward_fast(exch, method, arg1, arg2, 0, 0, NULL)
-#define async_data_read_forward_2_1(exch, method, arg1, arg2, answer) \
-	async_data_read_forward_fast(exch, method, arg1, arg2, 0, 0, answer)
-#define async_data_read_forward_3_0(exch, method, arg1, arg2, arg3, answer) \
-	async_data_read_forward_fast(exch, method, arg1, arg2, arg3, 0, NULL)
-#define async_data_read_forward_3_1(exch, method, arg1, arg2, arg3, answer) \
-	async_data_read_forward_fast(exch, method, arg1, arg2, arg3, 0, \
-	    answer)
-#define async_data_read_forward_4_0(exch, method, arg1, arg2, arg3, arg4, \
-    answer) \
-	async_data_read_forward_fast(exch, method, arg1, arg2, arg3, arg4, \
-	    NULL)
-#define async_data_read_forward_4_1(exch, method, arg1, arg2, arg3, arg4, \
-    answer) \
-	async_data_read_forward_fast(exch, method, arg1, arg2, arg3, arg4, \
-	    answer)
+extern errno_t async_data_read_forward_0_0(async_exch_t *, sysarg_t);
+extern errno_t async_data_read_forward_1_0(async_exch_t *, sysarg_t, sysarg_t);
+extern errno_t async_data_read_forward_2_0(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t);
+extern errno_t async_data_read_forward_3_0(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t);
+extern errno_t async_data_read_forward_4_0(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t);
+
+extern errno_t async_data_read_forward_0_1(async_exch_t *, sysarg_t,
+    ipc_call_t *);
+extern errno_t async_data_read_forward_1_1(async_exch_t *, sysarg_t, sysarg_t,
+    ipc_call_t *);
+extern errno_t async_data_read_forward_2_1(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t, ipc_call_t *);
+extern errno_t async_data_read_forward_3_1(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, ipc_call_t *);
+extern errno_t async_data_read_forward_4_1(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t, ipc_call_t *);
 
 extern aid_t async_data_read(async_exch_t *, void *, size_t, ipc_call_t *);
@@ -411,37 +337,23 @@
 extern errno_t async_data_read_finalize(ipc_call_t *, const void *, size_t);
 
-extern errno_t async_data_read_forward_fast(async_exch_t *, sysarg_t, sysarg_t,
+extern errno_t async_data_write_forward_0_0(async_exch_t *, sysarg_t);
+extern errno_t async_data_write_forward_1_0(async_exch_t *, sysarg_t, sysarg_t);
+extern errno_t async_data_write_forward_2_0(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t);
+extern errno_t async_data_write_forward_3_0(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t);
+extern errno_t async_data_write_forward_4_0(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t);
+
+extern errno_t async_data_write_forward_0_1(async_exch_t *, sysarg_t,
+    ipc_call_t *);
+extern errno_t async_data_write_forward_1_1(async_exch_t *, sysarg_t, sysarg_t,
+    ipc_call_t *);
+extern errno_t async_data_write_forward_2_1(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t, ipc_call_t *);
+extern errno_t async_data_write_forward_3_1(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, ipc_call_t *);
+extern errno_t async_data_write_forward_4_1(async_exch_t *, sysarg_t, sysarg_t,
     sysarg_t, sysarg_t, sysarg_t, ipc_call_t *);
-
-/*
- * User-friendly wrappers for async_data_write_forward_fast().
- */
-
-#define async_data_write_forward_0_0(exch, method, answer) \
-	async_data_write_forward_fast(exch, method, 0, 0, 0, 0, NULL)
-#define async_data_write_forward_0_1(exch, method, answer) \
-	async_data_write_forward_fast(exch, method, 0, 0, 0, 0, answer)
-#define async_data_write_forward_1_0(exch, method, arg1, answer) \
-	async_data_write_forward_fast(exch, method, arg1, 0, 0, 0, NULL)
-#define async_data_write_forward_1_1(exch, method, arg1, answer) \
-	async_data_write_forward_fast(exch, method, arg1, 0, 0, 0, answer)
-#define async_data_write_forward_2_0(exch, method, arg1, arg2, answer) \
-	async_data_write_forward_fast(exch, method, arg1, arg2, 0, 0, NULL)
-#define async_data_write_forward_2_1(exch, method, arg1, arg2, answer) \
-	async_data_write_forward_fast(exch, method, arg1, arg2, 0, 0, answer)
-#define async_data_write_forward_3_0(exch, method, arg1, arg2, arg3, answer) \
-	async_data_write_forward_fast(exch, method, arg1, arg2, arg3, 0, \
-	    NULL)
-#define async_data_write_forward_3_1(exch, method, arg1, arg2, arg3, answer) \
-	async_data_write_forward_fast(exch, method, arg1, arg2, arg3, 0, \
-	    answer)
-#define async_data_write_forward_4_0(exch, method, arg1, arg2, arg3, arg4, \
-    answer) \
-	async_data_write_forward_fast(exch, method, arg1, arg2, arg3, arg4, \
-	    NULL)
-#define async_data_write_forward_4_1(exch, method, arg1, arg2, arg3, arg4, \
-    answer) \
-	async_data_write_forward_fast(exch, method, arg1, arg2, arg3, arg4, \
-	    answer)
 
 extern errno_t async_data_write_start(async_exch_t *, const void *, size_t);
@@ -452,7 +364,4 @@
     const size_t, const size_t, size_t *);
 extern void async_data_write_void(errno_t);
-
-extern errno_t async_data_write_forward_fast(async_exch_t *, sysarg_t, sysarg_t,
-    sysarg_t, sysarg_t, sysarg_t, ipc_call_t *);
 
 extern async_sess_t *async_callback_receive(exch_mgmt_t);
@@ -473,5 +382,4 @@
 
 errno_t async_spawn_notification_handler(void);
-fid_t async_create_manager(void);
 
 #endif
Index: uspace/lib/c/include/barrier.h
===================================================================
--- uspace/lib/c/include/barrier.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/barrier.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_COMPILER_BARRIER_H_
-#define LIBC_COMPILER_BARRIER_H_
+#ifndef _LIBC_COMPILER_BARRIER_H_
+#define _LIBC_COMPILER_BARRIER_H_
 
 #include <stdatomic.h>
@@ -61,3 +61,3 @@
 #define ACCESS_ONCE(var) (*((volatile typeof(var)*)&(var)))
 
-#endif /* LIBC_COMPILER_BARRIER_H_ */
+#endif /* _LIBC_COMPILER_BARRIER_H_ */
Index: uspace/lib/c/include/bd.h
===================================================================
--- uspace/lib/c/include/bd.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/bd.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_BD_H_
-#define LIBC_BD_H_
+#ifndef _LIBC_BD_H_
+#define _LIBC_BD_H_
 
 #include <async.h>
Index: uspace/lib/c/include/bd_srv.h
===================================================================
--- uspace/lib/c/include/bd_srv.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/bd_srv.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_BD_SRV_H_
-#define LIBC_BD_SRV_H_
+#ifndef _LIBC_BD_SRV_H_
+#define _LIBC_BD_SRV_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/include/bitops.h
===================================================================
--- uspace/lib/c/include/bitops.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/bitops.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_BITOPS_H_
-#define LIBC_BITOPS_H_
+#ifndef _LIBC_BITOPS_H_
+#define _LIBC_BITOPS_H_
 
 #include <stddef.h>
Index: uspace/lib/c/include/bsearch.h
===================================================================
--- uspace/lib/c/include/bsearch.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/bsearch.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,11 +33,16 @@
  */
 
-#ifndef LIBC_BSEARCH_H_
-#define LIBC_BSEARCH_H_
+#ifndef _LIBC_BSEARCH_H_
+#define _LIBC_BSEARCH_H_
 
 #include <stddef.h>
+#include <_bits/decls.h>
+
+__C_DECLS_BEGIN;
 
 extern void *bsearch(const void *, const void *, size_t, size_t,
     int (*)(const void *, const void *));
+
+__C_DECLS_END;
 
 #endif
Index: uspace/lib/c/include/byteorder.h
===================================================================
--- uspace/lib/c/include/byteorder.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/byteorder.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_BYTEORDER_H_
-#define LIBC_BYTEORDER_H_
+#ifndef _LIBC_BYTEORDER_H_
+#define _LIBC_BYTEORDER_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/cap.h
===================================================================
--- uspace/lib/c/include/cap.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/cap.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_CAP_H_
-#define LIBC_CAP_H_
+#ifndef _LIBC_CAP_H_
+#define _LIBC_CAP_H_
 
 #include <adt/list.h>
Index: pace/lib/c/include/cc.h
===================================================================
--- uspace/lib/c/include/cc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,49 +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
- * @{
- */
-/** @file
- * Macros related to used compiler (such as GCC-specific attributes).
- */
-
-#ifndef LIBC_CC_H_
-#define LIBC_CC_H_
-
-#ifndef __clang__
-#define ATTRIBUTE_OPTIMIZE(opt) \
-	__attribute__ ((optimize(opt)))
-#else
-#define ATTRIBUTE_OPTIMIZE(opt)
-#endif
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/include/clipboard.h
===================================================================
--- uspace/lib/c/include/clipboard.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/clipboard.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_CLIPBOARD_H_
-#define LIBC_CLIPBOARD_H_
+#ifndef _LIBC_CLIPBOARD_H_
+#define _LIBC_CLIPBOARD_H_
 
 extern errno_t clipboard_put_str(const char *);
Index: uspace/lib/c/include/config.h
===================================================================
--- uspace/lib/c/include/config.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_CONFIG_H_
-#define LIBC_CONFIG_H_
+#ifndef _LIBC_CONFIG_H_
+#define _LIBC_CONFIG_H_
 
 #include <stdbool.h>
Index: uspace/lib/c/include/context.h
===================================================================
--- uspace/lib/c/include/context.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,9 +27,11 @@
  */
 
-#ifndef LIBC_CONTEXT_H_
-#define LIBC_CONTEXT_H_
+#ifndef _LIBC_CONTEXT_H_
+#define _LIBC_CONTEXT_H_
 
 #include <_bits/size_t.h>
 #include <libarch/fibril_context.h>
+
+typedef __context_t context_t;
 
 /* Context initialization data. */
Index: uspace/lib/c/include/corecfg.h
===================================================================
--- uspace/lib/c/include/corecfg.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/corecfg.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_CORECFG_H_
-#define LIBC_CORECFG_H_
+#ifndef _LIBC_CORECFG_H_
+#define _LIBC_CORECFG_H_
 
 #include <errno.h>
Index: uspace/lib/c/include/ctype.h
===================================================================
--- uspace/lib/c/include/ctype.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ctype.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,104 +27,25 @@
  */
 
-/** @addtogroup libc
- * @{
- */
-/** @file
- */
+#ifndef _LIBC_CTYPE_H_
+#define _LIBC_CTYPE_H_
 
-#ifndef LIBC_CTYPE_H_
-#define LIBC_CTYPE_H_
+#include <_bits/decls.h>
 
-static inline int islower(int c)
-{
-	return ((c >= 'a') && (c <= 'z'));
-}
-
-static inline int isupper(int c)
-{
-	return ((c >= 'A') && (c <= 'Z'));
-}
-
-static inline int isalpha(int c)
-{
-	return (islower(c) || isupper(c));
-}
-
-static inline int isdigit(int c)
-{
-	return ((c >= '0') && (c <= '9'));
-}
-
-static inline int isalnum(int c)
-{
-	return (isalpha(c) || isdigit(c));
-}
-
-static inline int isblank(int c)
-{
-	return c == ' ' || c == '\t';
-}
-
-static inline int iscntrl(int c)
-{
-	return (c >= 0 && c < 0x20) || c == 0x7E;
-}
-
-static inline int isprint(int c)
-{
-	return c >= 0 && c < 0x80 && !iscntrl(c);
-}
-
-static inline int isgraph(int c)
-{
-	return isprint(c) && c != ' ';
-}
-
-static inline int isspace(int c)
-{
-	switch (c) {
-	case ' ':
-	case '\n':
-	case '\t':
-	case '\f':
-	case '\r':
-	case '\v':
-		return 1;
-		break;
-	default:
-		return 0;
-	}
-}
-
-static inline int ispunct(int c)
-{
-	return !isspace(c) && !isalnum(c) && isprint(c);
-}
-
-static inline int isxdigit(int c)
-{
-	return isdigit(c) ||
-	    (c >= 'a' && c <= 'f') ||
-	    (c >= 'A' && c <= 'F');
-}
-
-static inline int tolower(int c)
-{
-	if (isupper(c))
-		return (c + ('a' - 'A'));
-	else
-		return c;
-}
-
-static inline int toupper(int c)
-{
-	if (islower(c))
-		return (c + ('A' - 'a'));
-	else
-		return c;
-}
+__C_DECLS_BEGIN;
+int islower(int);
+int isupper(int);
+int isalpha(int);
+int isdigit(int);
+int isalnum(int);
+int isblank(int);
+int iscntrl(int);
+int isprint(int);
+int isgraph(int);
+int isspace(int);
+int ispunct(int);
+int isxdigit(int);
+int tolower(int);
+int toupper(int);
+__C_DECLS_END;
 
 #endif
-
-/** @}
- */
Index: uspace/lib/c/include/ddi.h
===================================================================
--- uspace/lib/c/include/ddi.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_DDI_H_
-#define LIBC_DDI_H_
+#ifndef _LIBC_DDI_H_
+#define _LIBC_DDI_H_
 
 #include <stdbool.h>
Index: uspace/lib/c/include/device/clock_dev.h
===================================================================
--- uspace/lib/c/include/device/clock_dev.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/device/clock_dev.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_DEVICE_CLOCK_DEV_H_
-#define LIBC_DEVICE_CLOCK_DEV_H_
+#ifndef _LIBC_DEVICE_CLOCK_DEV_H_
+#define _LIBC_DEVICE_CLOCK_DEV_H_
 
 #include <async.h>
Index: uspace/lib/c/include/device/hw_res.h
===================================================================
--- uspace/lib/c/include/device/hw_res.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/device/hw_res.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_DEVICE_HW_RES_H_
-#define LIBC_DEVICE_HW_RES_H_
+#ifndef _LIBC_DEVICE_HW_RES_H_
+#define _LIBC_DEVICE_HW_RES_H_
 
 #include <ipc/dev_iface.h>
Index: uspace/lib/c/include/device/hw_res_parsed.h
===================================================================
--- uspace/lib/c/include/device/hw_res_parsed.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/device/hw_res_parsed.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_DEVICE_HW_RES_PARSED_H_
-#define LIBC_DEVICE_HW_RES_PARSED_H_
+#ifndef _LIBC_DEVICE_HW_RES_PARSED_H_
+#define _LIBC_DEVICE_HW_RES_PARSED_H_
 
 #include <device/hw_res.h>
Index: uspace/lib/c/include/device/led_dev.h
===================================================================
--- uspace/lib/c/include/device/led_dev.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/device/led_dev.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_DEVICE_LED_DEV_H_
-#define LIBC_DEVICE_LED_DEV_H_
+#ifndef _LIBC_DEVICE_LED_DEV_H_
+#define _LIBC_DEVICE_LED_DEV_H_
 
 #include <async.h>
Index: uspace/lib/c/include/device/pio_window.h
===================================================================
--- uspace/lib/c/include/device/pio_window.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/device/pio_window.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_DEVICE_PIO_WINDOW_H_
-#define LIBC_DEVICE_PIO_WINDOW_H_
+#ifndef _LIBC_DEVICE_PIO_WINDOW_H_
+#define _LIBC_DEVICE_PIO_WINDOW_H_
 
 #include <ipc/dev_iface.h>
Index: uspace/lib/c/include/devman.h
===================================================================
--- uspace/lib/c/include/devman.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/devman.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_DEVMAN_H_
-#define LIBC_DEVMAN_H_
+#ifndef _LIBC_DEVMAN_H_
+#define _LIBC_DEVMAN_H_
 
 #include <ipc/devman.h>
Index: uspace/lib/c/include/dirent.h
===================================================================
--- uspace/lib/c/include/dirent.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/dirent.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,20 +33,16 @@
  */
 
-#ifndef LIBC_DIRENT_H_
-#define LIBC_DIRENT_H_
+#ifndef _LIBC_DIRENT_H_
+#define _LIBC_DIRENT_H_
 
-#define NAME_MAX  256
+#include <_bits/decls.h>
 
-#include <offset.h>
+__C_DECLS_BEGIN;
 
 struct dirent {
-	char d_name[NAME_MAX + 1];
+	char d_name[256];
 };
 
-typedef struct {
-	int fd;
-	struct dirent res;
-	aoff64_t pos;
-} DIR;
+typedef struct __dirstream DIR;
 
 extern DIR *opendir(const char *);
@@ -55,4 +51,6 @@
 extern int closedir(DIR *);
 
+__C_DECLS_END;
+
 #endif
 
Index: uspace/lib/c/include/dlfcn.h
===================================================================
--- uspace/lib/c/include/dlfcn.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/dlfcn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,9 +34,15 @@
  */
 
-#ifndef LIBC_DLFCN_H_
-#define LIBC_DLFCN_H_
+#ifndef _LIBC_DLFCN_H_
+#define _LIBC_DLFCN_H_
+
+#include <_bits/decls.h>
+
+__C_DECLS_BEGIN;
 
 void *dlopen(const char *, int);
 void *dlsym(void *, const char *);
+
+__C_DECLS_END;
 
 #endif
Index: uspace/lib/c/include/elf/elf.h
===================================================================
--- uspace/lib/c/include/elf/elf.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/elf/elf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ELF_H_
-#define LIBC_ELF_H_
+#ifndef _LIBC_ELF_H_
+#define _LIBC_ELF_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/elf/elf_linux.h
===================================================================
--- uspace/lib/c/include/elf/elf_linux.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/elf/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ELF_LINUX_H_
-#define LIBC_ELF_LINUX_H_
+#ifndef _LIBC_ELF_LINUX_H_
+#define _LIBC_ELF_LINUX_H_
 
 #include <elf/elf.h>
Index: uspace/lib/c/include/elf/elf_load.h
===================================================================
--- uspace/lib/c/include/elf/elf_load.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/elf/elf_load.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -45,5 +45,5 @@
 } elf_info_t;
 
-extern int elf_load(int, elf_info_t *);
+extern errno_t elf_load(int, elf_info_t *);
 extern void elf_set_pcb(elf_info_t *, pcb_t *);
 
Index: uspace/lib/c/include/elf/elf_mod.h
===================================================================
--- uspace/lib/c/include/elf/elf_mod.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/elf/elf_mod.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -42,15 +42,4 @@
 #include <stdint.h>
 #include <loader/pcb.h>
-
-/**
- * ELF error return codes
- */
-#define EE_OK			0	/* No error */
-#define EE_INVALID		1	/* Invalid ELF image */
-#define EE_MEMORY		2	/* Cannot allocate address space */
-#define EE_INCOMPATIBLE		3	/* ELF image is not compatible with current architecture */
-#define EE_UNSUPPORTED		4	/* Non-supported ELF (e.g. dynamic ELFs) */
-#define EE_IRRECOVERABLE	5
-#define EE_IO			6	/* Could not read file. */
 
 typedef enum {
@@ -110,7 +99,6 @@
 } elf_ld_t;
 
-extern const char *elf_error(unsigned int);
-extern int elf_load_file(int, eld_flags_t, elf_finfo_t *);
-extern int elf_load_file_name(const char *, eld_flags_t, elf_finfo_t *);
+extern errno_t elf_load_file(int, eld_flags_t, elf_finfo_t *);
+extern errno_t elf_load_file_name(const char *, eld_flags_t, elf_finfo_t *);
 
 #endif
Index: uspace/lib/c/include/entry_point.h
===================================================================
--- uspace/lib/c/include/entry_point.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/entry_point.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ENTRY_POINT_H_
-#define LIBC_ENTRY_POINT_H_
+#ifndef _LIBC_ENTRY_POINT_H_
+#define _LIBC_ENTRY_POINT_H_
 
 /* Defined in arch/ARCH/src/entryjmp.[c|s] */
Index: uspace/lib/c/include/errno.h
===================================================================
--- uspace/lib/c/include/errno.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/errno.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,13 +33,22 @@
  */
 
-#ifndef LIBC_ERRNO_H_
-#define LIBC_ERRNO_H_
+#ifndef _LIBC_ERRNO_H_
+#define _LIBC_ERRNO_H_
 
 #include <_bits/errno.h>
 #include <abi/errno.h>
+#include <_bits/decls.h>
 
-#define errno  (*(__errno()))
+__HELENOS_DECLS_BEGIN;
 
 extern errno_t *__errno(void) __attribute__((const));
+
+__HELENOS_DECLS_END;
+
+#ifdef __cplusplus
+#define errno  (*(::helenos::__errno()))
+#else
+#define errno  (*(__errno()))
+#endif
 
 #endif
Index: uspace/lib/c/include/fibril.h
===================================================================
--- uspace/lib/c/include/fibril.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,11 +33,13 @@
  */
 
-#ifndef LIBC_FIBRIL_H_
-#define LIBC_FIBRIL_H_
+#ifndef _LIBC_FIBRIL_H_
+#define _LIBC_FIBRIL_H_
 
-#include <types/common.h>
 #include <time.h>
+#include <_bits/errno.h>
 #include <_bits/__noreturn.h>
-#include <ipc/common.h>
+#include <_bits/decls.h>
+
+__HELENOS_DECLS_BEGIN;
 
 typedef struct fibril fibril_t;
@@ -49,10 +51,11 @@
 typedef fibril_t *fid_t;
 
+#ifndef __cplusplus
 /** Fibril-local variable specifier */
 #define fibril_local __thread
-
-#define FIBRIL_DFLT_STK_SIZE	0
+#endif
 
 extern fid_t fibril_create_generic(errno_t (*)(void *), void *, size_t);
+extern fid_t fibril_create(errno_t (*)(void *), void *);
 extern void fibril_destroy(fid_t);
 extern void fibril_add_ready(fid_t);
@@ -68,11 +71,8 @@
 extern void fibril_detach(fid_t fid);
 
-static inline fid_t fibril_create(errno_t (*func)(void *), void *arg)
-{
-	return fibril_create_generic(func, arg, FIBRIL_DFLT_STK_SIZE);
-}
-
 extern void fibril_start(fid_t);
 extern __noreturn void fibril_exit(long);
+
+__HELENOS_DECLS_END;
 
 #endif
Index: uspace/lib/c/include/fibril_synch.h
===================================================================
--- uspace/lib/c/include/fibril_synch.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/fibril_synch.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,18 +33,14 @@
  */
 
-#ifndef LIBC_FIBRIL_SYNCH_H_
-#define LIBC_FIBRIL_SYNCH_H_
+#ifndef _LIBC_FIBRIL_SYNCH_H_
+#define _LIBC_FIBRIL_SYNCH_H_
 
 #include <fibril.h>
 #include <adt/list.h>
-#include <tls.h>
 #include <time.h>
 #include <stdbool.h>
-
-typedef struct {
-	fibril_owner_info_t oi;  /**< Keep this the first thing. */
-	int counter;
-	list_t waiters;
-} fibril_mutex_t;
+#include <_bits/decls.h>
+
+#ifndef __cplusplus
 
 #define FIBRIL_MUTEX_INITIALIZER(name) \
@@ -54,21 +50,9 @@
 		}, \
 		.counter = 1, \
-		.waiters = { \
-			.head = { \
-				.prev = &(name).waiters.head, \
-				.next = &(name).waiters.head, \
-			} \
-		} \
+		.waiters = LIST_INITIALIZER((name).waiters), \
 	}
 
 #define FIBRIL_MUTEX_INITIALIZE(name) \
 	fibril_mutex_t name = FIBRIL_MUTEX_INITIALIZER(name)
-
-typedef struct {
-	fibril_owner_info_t oi;  /**< Keep this the first thing. */
-	unsigned int writers;
-	unsigned int readers;
-	list_t waiters;
-} fibril_rwlock_t;
 
 #define FIBRIL_RWLOCK_INITIALIZER(name) \
@@ -79,10 +63,5 @@
 		.readers = 0, \
 		.writers = 0, \
-		.waiters = { \
-			.head = { \
-				.prev = &(name).waiters.head, \
-				.next = &(name).waiters.head, \
-			} \
-		} \
+		.waiters = LIST_INITIALIZER((name).waiters), \
 	}
 
@@ -90,20 +69,41 @@
 	fibril_rwlock_t name = FIBRIL_RWLOCK_INITIALIZER(name)
 
-typedef struct {
-	list_t waiters;
-} fibril_condvar_t;
-
 #define FIBRIL_CONDVAR_INITIALIZER(name) \
 	{ \
-		.waiters = { \
-			.head = { \
-				.next = &(name).waiters.head, \
-				.prev = &(name).waiters.head, \
-			} \
-		} \
+		.waiters = LIST_INITIALIZER((name).waiters), \
 	}
 
 #define FIBRIL_CONDVAR_INITIALIZE(name) \
 	fibril_condvar_t name = FIBRIL_CONDVAR_INITIALIZER(name)
+
+#define FIBRIL_SEMAPHORE_INITIALIZER(name, cnt) \
+	{ \
+		.count = (cnt), \
+		.waiters = LIST_INITIALIZER((name).waiters), \
+	}
+
+#define FIBRIL_SEMAPHORE_INITIALIZE(name, cnt) \
+	fibril_semaphore_t name = FIBRIL_SEMAPHORE_INITIALIZER(name, cnt)
+
+#endif
+
+__HELENOS_DECLS_BEGIN;
+
+typedef struct {
+	fibril_owner_info_t oi;  /**< Keep this the first thing. */
+	int counter;
+	list_t waiters;
+} fibril_mutex_t;
+
+typedef struct {
+	fibril_owner_info_t oi;  /**< Keep this the first thing. */
+	unsigned int writers;
+	unsigned int readers;
+	list_t waiters;
+} fibril_rwlock_t;
+
+typedef struct {
+	list_t waiters;
+} fibril_condvar_t;
 
 typedef void (*fibril_timer_fun_t)(void *);
@@ -150,18 +150,4 @@
 } fibril_semaphore_t;
 
-#define FIBRIL_SEMAPHORE_INITIALIZER(name, cnt) \
-	{ \
-		.count = (cnt), \
-		.waiters = { \
-			.head = { \
-				.next = &(name).waiters.head, \
-				.prev = &(name).waiters.head, \
-			} \
-		} \
-	}
-
-#define FIBRIL_SEMAPHORE_INITIALIZE(name, cnt) \
-	fibril_semaphore_t name = FIBRIL_SEMAPHORE_INITIALIZER(name, cnt)
-
 extern void __fibril_synch_init(void);
 extern void __fibril_synch_fini(void);
@@ -211,4 +197,6 @@
 extern void mpsc_close(mpsc_t *);
 
+__HELENOS_DECLS_END;
+
 #endif
 
Index: uspace/lib/c/include/fourcc.h
===================================================================
--- uspace/lib/c/include/fourcc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/fourcc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_FOURCC_H_
-#define LIBC_FOURCC_H_
+#ifndef _LIBC_FOURCC_H_
+#define _LIBC_FOURCC_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/gsort.h
===================================================================
--- uspace/lib/c/include/gsort.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/gsort.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_SORT_H_
-#define LIBC_SORT_H_
+#ifndef _LIBC_SORT_H_
+#define _LIBC_SORT_H_
 
 #include <stddef.h>
Index: uspace/lib/c/include/ieee80211/ieee80211.h
===================================================================
--- uspace/lib/c/include/ieee80211/ieee80211.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ieee80211/ieee80211.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,6 +35,6 @@
  */
 
-#ifndef LIBC_IEEE80211_H_
-#define LIBC_IEEE80211_H_
+#ifndef _LIBC_IEEE80211_H_
+#define _LIBC_IEEE80211_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/include/imath.h
===================================================================
--- uspace/lib/c/include/imath.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/imath.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_IMATH_H_
-#define LIBC_IMATH_H_
+#ifndef _LIBC_IMATH_H_
+#define _LIBC_IMATH_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/inet/addr.h
===================================================================
--- uspace/lib/c/include/inet/addr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/addr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_ADDR_H_
-#define LIBC_INET_ADDR_H_
+#ifndef _LIBC_INET_ADDR_H_
+#define _LIBC_INET_ADDR_H_
 
 #include <errno.h>
Index: uspace/lib/c/include/inet/dhcp.h
===================================================================
--- uspace/lib/c/include/inet/dhcp.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/dhcp.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_DHCP_H_
-#define LIBC_INET_DHCP_H_
+#ifndef _LIBC_INET_DHCP_H_
+#define _LIBC_INET_DHCP_H_
 
 #include <types/common.h>
Index: uspace/lib/c/include/inet/dnsr.h
===================================================================
--- uspace/lib/c/include/inet/dnsr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/dnsr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_DNSR_H_
-#define LIBC_INET_DNSR_H_
+#ifndef _LIBC_INET_DNSR_H_
+#define _LIBC_INET_DNSR_H_
 
 #include <inet/inet.h>
Index: uspace/lib/c/include/inet/endpoint.h
===================================================================
--- uspace/lib/c/include/inet/endpoint.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/endpoint.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_ENDPOINT_H_
-#define LIBC_INET_ENDPOINT_H_
+#ifndef _LIBC_INET_ENDPOINT_H_
+#define _LIBC_INET_ENDPOINT_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/inet/host.h
===================================================================
--- uspace/lib/c/include/inet/host.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/host.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_HOST_H_
-#define LIBC_INET_HOST_H_
+#ifndef _LIBC_INET_HOST_H_
+#define _LIBC_INET_HOST_H_
 
 #include <inet/addr.h>
Index: uspace/lib/c/include/inet/hostname.h
===================================================================
--- uspace/lib/c/include/inet/hostname.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/hostname.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_HOSTNAME_H_
-#define LIBC_INET_HOSTNAME_H_
+#ifndef _LIBC_INET_HOSTNAME_H_
+#define _LIBC_INET_HOSTNAME_H_
 
 extern errno_t inet_hostname_parse(const char *, char **, char **);
Index: uspace/lib/c/include/inet/hostport.h
===================================================================
--- uspace/lib/c/include/inet/hostport.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/hostport.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_HOSTPORT_H_
-#define LIBC_INET_HOSTPORT_H_
+#ifndef _LIBC_INET_HOSTPORT_H_
+#define _LIBC_INET_HOSTPORT_H_
 
 #include <inet/addr.h>
Index: uspace/lib/c/include/inet/inet.h
===================================================================
--- uspace/lib/c/include/inet/inet.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/inet.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_INET_H_
-#define LIBC_INET_INET_H_
+#ifndef _LIBC_INET_INET_H_
+#define _LIBC_INET_INET_H_
 
 #include <inet/addr.h>
Index: uspace/lib/c/include/inet/inetcfg.h
===================================================================
--- uspace/lib/c/include/inet/inetcfg.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/inetcfg.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_INETCFG_H_
-#define LIBC_INET_INETCFG_H_
+#ifndef _LIBC_INET_INETCFG_H_
+#define _LIBC_INET_INETCFG_H_
 
 #include <inet/inet.h>
Index: uspace/lib/c/include/inet/inetping.h
===================================================================
--- uspace/lib/c/include/inet/inetping.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/inetping.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_INETPING_H_
-#define LIBC_INET_INETPING_H_
+#ifndef _LIBC_INET_INETPING_H_
+#define _LIBC_INET_INETPING_H_
 
 #include <inet/inet.h>
Index: uspace/lib/c/include/inet/iplink.h
===================================================================
--- uspace/lib/c/include/inet/iplink.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/iplink.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_IPLINK_H_
-#define LIBC_INET_IPLINK_H_
+#ifndef _LIBC_INET_IPLINK_H_
+#define _LIBC_INET_IPLINK_H_
 
 #include <async.h>
Index: uspace/lib/c/include/inet/iplink_srv.h
===================================================================
--- uspace/lib/c/include/inet/iplink_srv.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/iplink_srv.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_IPLINK_SRV_H_
-#define LIBC_INET_IPLINK_SRV_H_
+#ifndef _LIBC_INET_IPLINK_SRV_H_
+#define _LIBC_INET_IPLINK_SRV_H_
 
 #include <async.h>
Index: uspace/lib/c/include/inet/tcp.h
===================================================================
--- uspace/lib/c/include/inet/tcp.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/tcp.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_TCP_H_
-#define LIBC_INET_TCP_H_
+#ifndef _LIBC_INET_TCP_H_
+#define _LIBC_INET_TCP_H_
 
 #include <fibril_synch.h>
Index: uspace/lib/c/include/inet/udp.h
===================================================================
--- uspace/lib/c/include/inet/udp.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/udp.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_UDP_H_
-#define LIBC_INET_UDP_H_
+#ifndef _LIBC_INET_UDP_H_
+#define _LIBC_INET_UDP_H_
 
 #include <async.h>
Index: uspace/lib/c/include/io/chardev.h
===================================================================
--- uspace/lib/c/include/io/chardev.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/chardev.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,9 +31,10 @@
  */
 
-#ifndef LIBC_IO_CHARDEV_H_
-#define LIBC_IO_CHARDEV_H_
+#ifndef _LIBC_IO_CHARDEV_H_
+#define _LIBC_IO_CHARDEV_H_
 
 #include <async.h>
 #include <stddef.h>
+#include <types/io/chardev.h>
 
 typedef struct {
@@ -43,5 +44,6 @@
 extern errno_t chardev_open(async_sess_t *, chardev_t **);
 extern void chardev_close(chardev_t *);
-extern errno_t chardev_read(chardev_t *, void *, size_t, size_t *);
+extern errno_t chardev_read(chardev_t *, void *, size_t, size_t *,
+    chardev_flags_t);
 extern errno_t chardev_write(chardev_t *, const void *, size_t, size_t *);
 
Index: uspace/lib/c/include/io/chardev_srv.h
===================================================================
--- uspace/lib/c/include/io/chardev_srv.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/chardev_srv.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_CHARDEV_SRV_H_
-#define LIBC_IO_CHARDEV_SRV_H_
+#ifndef _LIBC_IO_CHARDEV_SRV_H_
+#define _LIBC_IO_CHARDEV_SRV_H_
 
 #include <adt/list.h>
@@ -41,4 +41,5 @@
 #include <stdbool.h>
 #include <stddef.h>
+#include <types/io/chardev.h>
 
 typedef struct chardev_ops chardev_ops_t;
@@ -59,5 +60,6 @@
 	errno_t (*open)(chardev_srvs_t *, chardev_srv_t *);
 	errno_t (*close)(chardev_srv_t *);
-	errno_t (*read)(chardev_srv_t *, void *, size_t, size_t *);
+	errno_t (*read)(chardev_srv_t *, void *, size_t, size_t *,
+	    chardev_flags_t);
 	errno_t (*write)(chardev_srv_t *, const void *, size_t, size_t *);
 	void (*def_handler)(chardev_srv_t *, ipc_call_t *);
Index: uspace/lib/c/include/io/charfield.h
===================================================================
--- uspace/lib/c/include/io/charfield.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/charfield.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_IO_CHARFIELD_H_
-#define LIBC_IO_CHARFIELD_H_
+#ifndef _LIBC_IO_CHARFIELD_H_
+#define _LIBC_IO_CHARFIELD_H_
 
 #include <stdbool.h>
Index: uspace/lib/c/include/io/chargrid.h
===================================================================
--- uspace/lib/c/include/io/chargrid.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/chargrid.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_IO_CHARGRID_H_
-#define LIBC_IO_CHARGRID_H_
+#ifndef _LIBC_IO_CHARGRID_H_
+#define _LIBC_IO_CHARGRID_H_
 
 #include <io/charfield.h>
Index: uspace/lib/c/include/io/color.h
===================================================================
--- uspace/lib/c/include/io/color.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/color.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_COLOR_H_
-#define LIBC_IO_COLOR_H_
+#ifndef _LIBC_IO_COLOR_H_
+#define _LIBC_IO_COLOR_H_
 
 typedef enum {
Index: uspace/lib/c/include/io/con_srv.h
===================================================================
--- uspace/lib/c/include/io/con_srv.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/con_srv.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_CON_SRV_H_
-#define LIBC_CON_SRV_H_
+#ifndef _LIBC_CON_SRV_H_
+#define _LIBC_CON_SRV_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/include/io/concaps.h
===================================================================
--- uspace/lib/c/include/io/concaps.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/concaps.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_CONCAPS_H_
-#define LIBC_IO_CONCAPS_H_
+#ifndef _LIBC_IO_CONCAPS_H_
+#define _LIBC_IO_CONCAPS_H_
 
 typedef enum {
Index: uspace/lib/c/include/io/cons_event.h
===================================================================
--- uspace/lib/c/include/io/cons_event.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/cons_event.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_CONS_EVENT_H_
-#define LIBC_IO_CONS_EVENT_H_
+#ifndef _LIBC_IO_CONS_EVENT_H_
+#define _LIBC_IO_CONS_EVENT_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/include/io/console.h
===================================================================
--- uspace/lib/c/include/io/console.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/console.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_CONSOLE_H_
-#define LIBC_IO_CONSOLE_H_
+#ifndef _LIBC_IO_CONSOLE_H_
+#define _LIBC_IO_CONSOLE_H_
 
 #include <time.h>
Index: uspace/lib/c/include/io/input.h
===================================================================
--- uspace/lib/c/include/io/input.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/input.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_INPUT_H_
-#define LIBC_IO_INPUT_H_
+#ifndef _LIBC_IO_INPUT_H_
+#define _LIBC_IO_INPUT_H_
 
 #include <async.h>
Index: uspace/lib/c/include/io/kbd_event.h
===================================================================
--- uspace/lib/c/include/io/kbd_event.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/kbd_event.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_KBD_EVENT_H_
-#define LIBC_IO_KBD_EVENT_H_
+#ifndef _LIBC_IO_KBD_EVENT_H_
+#define _LIBC_IO_KBD_EVENT_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/include/io/keycode.h
===================================================================
--- uspace/lib/c/include/io/keycode.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/keycode.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_KEYCODE_H_
-#define LIBC_IO_KEYCODE_H_
+#ifndef _LIBC_IO_KEYCODE_H_
+#define _LIBC_IO_KEYCODE_H_
 
 /** Keycode definitions.
Index: uspace/lib/c/include/io/kio.h
===================================================================
--- uspace/lib/c/include/io/kio.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/kio.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_KIO_H_
-#define LIBC_IO_KIO_H_
+#ifndef _LIBC_IO_KIO_H_
+#define _LIBC_IO_KIO_H_
 
 #include <stddef.h>
Index: uspace/lib/c/include/io/klog.h
===================================================================
--- uspace/lib/c/include/io/klog.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/klog.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_KLOG_H_
-#define LIBC_IO_KLOG_H_
+#ifndef _LIBC_IO_KLOG_H_
+#define _LIBC_IO_KLOG_H_
 
 #include <stddef.h>
Index: uspace/lib/c/include/io/label.h
===================================================================
--- uspace/lib/c/include/io/label.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/label.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_LABEL_H_
-#define LIBC_IO_LABEL_H_
+#ifndef _LIBC_IO_LABEL_H_
+#define _LIBC_IO_LABEL_H_
 
 #include <types/label.h>
Index: uspace/lib/c/include/io/log.h
===================================================================
--- uspace/lib/c/include/io/log.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/log.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -32,6 +32,6 @@
  */
 
-#ifndef LIBC_IO_LOG_H_
-#define LIBC_IO_LOG_H_
+#ifndef _LIBC_IO_LOG_H_
+#define _LIBC_IO_LOG_H_
 
 #include <stdarg.h>
Index: uspace/lib/c/include/io/logctl.h
===================================================================
--- uspace/lib/c/include/io/logctl.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/logctl.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_IO_LOGCTL_H_
-#define LIBC_IO_LOGCTL_H_
+#ifndef _LIBC_IO_LOGCTL_H_
+#define _LIBC_IO_LOGCTL_H_
 
 #include <io/log.h>
Index: uspace/lib/c/include/io/mode.h
===================================================================
--- uspace/lib/c/include/io/mode.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/mode.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_IO_MODE_H_
-#define LIBC_IO_MODE_H_
+#ifndef _LIBC_IO_MODE_H_
+#define _LIBC_IO_MODE_H_
 
 #include <abi/fb/visuals.h>
Index: uspace/lib/c/include/io/output.h
===================================================================
--- uspace/lib/c/include/io/output.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/output.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_OUTPUT_H_
-#define LIBC_IO_OUTPUT_H_
+#ifndef _LIBC_IO_OUTPUT_H_
+#define _LIBC_IO_OUTPUT_H_
 
 #include <ipc/output.h>
Index: uspace/lib/c/include/io/pixel.h
===================================================================
--- uspace/lib/c/include/io/pixel.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/pixel.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_IO_PIXEL_H_
-#define LIBC_IO_PIXEL_H_
+#ifndef _LIBC_IO_PIXEL_H_
+#define _LIBC_IO_PIXEL_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/io/pixelmap.h
===================================================================
--- uspace/lib/c/include/io/pixelmap.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/pixelmap.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,6 +35,6 @@
  */
 
-#ifndef LIBC_IO_PIXELMAP_H_
-#define LIBC_IO_PIXELMAP_H_
+#ifndef _LIBC_IO_PIXELMAP_H_
+#define _LIBC_IO_PIXELMAP_H_
 
 #include <types/common.h>
Index: uspace/lib/c/include/io/pos_event.h
===================================================================
--- uspace/lib/c/include/io/pos_event.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/pos_event.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_IO_POS_EVENT_H_
-#define LIBC_IO_POS_EVENT_H_
+#ifndef _LIBC_IO_POS_EVENT_H_
+#define _LIBC_IO_POS_EVENT_H_
 
 #include <types/common.h>
Index: uspace/lib/c/include/io/printf_core.h
===================================================================
--- uspace/lib/c/include/io/printf_core.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/printf_core.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRINTF_CORE_H_
-#define LIBC_PRINTF_CORE_H_
+#ifndef _LIBC_PRINTF_CORE_H_
+#define _LIBC_PRINTF_CORE_H_
 
 #include <stddef.h>
Index: uspace/lib/c/include/io/serial.h
===================================================================
--- uspace/lib/c/include/io/serial.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/serial.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_SERIAL_H_
-#define LIBC_IO_SERIAL_H_
+#ifndef _LIBC_IO_SERIAL_H_
+#define _LIBC_IO_SERIAL_H_
 
 #include <async.h>
Index: uspace/lib/c/include/io/style.h
===================================================================
--- uspace/lib/c/include/io/style.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/style.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_STYLE_H_
-#define LIBC_IO_STYLE_H_
+#ifndef _LIBC_IO_STYLE_H_
+#define _LIBC_IO_STYLE_H_
 
 typedef enum {
Index: uspace/lib/c/include/io/table.h
===================================================================
--- uspace/lib/c/include/io/table.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/table.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_TABLE_H_
-#define LIBC_IO_TABLE_H_
+#ifndef _LIBC_IO_TABLE_H_
+#define _LIBC_IO_TABLE_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/include/io/verify.h
===================================================================
--- uspace/lib/c/include/io/verify.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/verify.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_VERIFY_H_
-#define LIBC_IO_VERIFY_H_
+#ifndef _LIBC_IO_VERIFY_H_
+#define _LIBC_IO_VERIFY_H_
 
 #ifdef __clang__
Index: uspace/lib/c/include/io/visualizer.h
===================================================================
--- uspace/lib/c/include/io/visualizer.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/visualizer.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_VISUALIZER_H_
-#define LIBC_IO_VISUALIZER_H_
+#ifndef _LIBC_IO_VISUALIZER_H_
+#define _LIBC_IO_VISUALIZER_H_
 
 #include <async.h>
Index: uspace/lib/c/include/io/window.h
===================================================================
--- uspace/lib/c/include/io/window.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/window.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_WINDOW_H_
-#define LIBC_IO_WINDOW_H_
+#ifndef _LIBC_IO_WINDOW_H_
+#define _LIBC_IO_WINDOW_H_
 
 #include <stdbool.h>
Index: uspace/lib/c/include/ipc/adb.h
===================================================================
--- uspace/lib/c/include/ipc/adb.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/adb.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_IPC_ADB_H_
-#define LIBC_IPC_ADB_H_
+#ifndef _LIBC_IPC_ADB_H_
+#define _LIBC_IPC_ADB_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/bd.h
===================================================================
--- uspace/lib/c/include/ipc/bd.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/bd.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_BD_H_
-#define LIBC_IPC_BD_H_
+#ifndef _LIBC_IPC_BD_H_
+#define _LIBC_IPC_BD_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/chardev.h
===================================================================
--- uspace/lib/c/include/ipc/chardev.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/chardev.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_IPC_CHARDEV_H_
-#define LIBC_IPC_CHARDEV_H_
+#ifndef _LIBC_IPC_CHARDEV_H_
+#define _LIBC_IPC_CHARDEV_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/clipboard.h
===================================================================
--- uspace/lib/c/include/ipc/clipboard.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/clipboard.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_CLIPBOARD_H_
-#define LIBC_IPC_CLIPBOARD_H_
+#ifndef _LIBC_IPC_CLIPBOARD_H_
+#define _LIBC_IPC_CLIPBOARD_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/common.h
===================================================================
--- uspace/lib/c/include/ipc/common.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/common.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_COMMON_H_
-#define LIBC_IPC_COMMON_H_
+#ifndef _LIBC_IPC_COMMON_H_
+#define _LIBC_IPC_COMMON_H_
 
 #include <types/common.h>
Index: uspace/lib/c/include/ipc/console.h
===================================================================
--- uspace/lib/c/include/ipc/console.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/console.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_CONSOLE_H_
-#define LIBC_IPC_CONSOLE_H_
+#ifndef _LIBC_IPC_CONSOLE_H_
+#define _LIBC_IPC_CONSOLE_H_
 
 #include <ipc/vfs.h>
Index: uspace/lib/c/include/ipc/corecfg.h
===================================================================
--- uspace/lib/c/include/ipc/corecfg.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/corecfg.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_IPC_CORECFG_H_
-#define LIBC_IPC_CORECFG_H_
+#ifndef _LIBC_IPC_CORECFG_H_
+#define _LIBC_IPC_CORECFG_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/dev_iface.h
===================================================================
--- uspace/lib/c/include/ipc/dev_iface.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/dev_iface.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,6 +27,6 @@
  */
 
-#ifndef LIBC_IPC_DEV_IFACE_H_
-#define LIBC_IPC_DEV_IFACE_H_
+#ifndef _LIBC_IPC_DEV_IFACE_H_
+#define _LIBC_IPC_DEV_IFACE_H_
 
 #include <stdlib.h>
@@ -91,8 +91,8 @@
  */
 
-#define DEV_IPC_GET_ARG1(call) IPC_GET_ARG2((call))
-#define DEV_IPC_GET_ARG2(call) IPC_GET_ARG3((call))
-#define DEV_IPC_GET_ARG3(call) IPC_GET_ARG4((call))
-#define DEV_IPC_GET_ARG4(call) IPC_GET_ARG5((call))
+#define DEV_IPC_GET_ARG1(call) ipc_get_arg2(&(call))
+#define DEV_IPC_GET_ARG2(call) ipc_get_arg3(&(call))
+#define DEV_IPC_GET_ARG3(call) ipc_get_arg4(&(call))
+#define DEV_IPC_GET_ARG4(call) ipc_get_arg5(&(call))
 
 #endif
Index: uspace/lib/c/include/ipc/devman.h
===================================================================
--- uspace/lib/c/include/ipc/devman.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/devman.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_IPC_DEVMAN_H_
-#define LIBC_IPC_DEVMAN_H_
+#ifndef _LIBC_IPC_DEVMAN_H_
+#define _LIBC_IPC_DEVMAN_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/dhcp.h
===================================================================
--- uspace/lib/c/include/ipc/dhcp.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/dhcp.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_DHCP_H_
-#define LIBC_IPC_DHCP_H_
+#ifndef _LIBC_IPC_DHCP_H_
+#define _LIBC_IPC_DHCP_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/dnsr.h
===================================================================
--- uspace/lib/c/include/ipc/dnsr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/dnsr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_IPC_DNSR_H_
-#define LIBC_IPC_DNSR_H_
+#ifndef _LIBC_IPC_DNSR_H_
+#define _LIBC_IPC_DNSR_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/event.h
===================================================================
--- uspace/lib/c/include/ipc/event.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/event.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_EVENT_H_
-#define LIBC_IPC_EVENT_H_
+#ifndef _LIBC_IPC_EVENT_H_
+#define _LIBC_IPC_EVENT_H_
 
 #include <abi/ipc/event.h>
Index: uspace/lib/c/include/ipc/graph.h
===================================================================
--- uspace/lib/c/include/ipc/graph.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/graph.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_GRAPH_H_
-#define LIBC_IPC_GRAPH_H_
+#ifndef _LIBC_IPC_GRAPH_H_
+#define _LIBC_IPC_GRAPH_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/inet.h
===================================================================
--- uspace/lib/c/include/ipc/inet.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/inet.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_INET_H_
-#define LIBC_IPC_INET_H_
+#ifndef _LIBC_IPC_INET_H_
+#define _LIBC_IPC_INET_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/input.h
===================================================================
--- uspace/lib/c/include/ipc/input.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/input.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_INPUT_H_
-#define LIBC_IPC_INPUT_H_
+#ifndef _LIBC_IPC_INPUT_H_
+#define _LIBC_IPC_INPUT_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/ipc.h
===================================================================
--- uspace/lib/c/include/ipc/ipc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/ipc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,10 +33,10 @@
  */
 
-#if ((defined(LIBC_ASYNC_H_)) && (!defined(LIBC_ASYNC_C_)))
+#if ((defined(_LIBC_ASYNC_H_)) && (!defined(_LIBC_ASYNC_C_)))
 #error Do not intermix low-level IPC interface and async framework
 #endif
 
-#ifndef LIBC_IPC_H_
-#define LIBC_IPC_H_
+#ifndef _LIBC_IPC_H_
+#define _LIBC_IPC_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/ipc_test.h
===================================================================
--- uspace/lib/c/include/ipc/ipc_test.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/ipc_test.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_IPC_TEST_H_
-#define LIBC_IPC_IPC_TEST_H_
+#ifndef _LIBC_IPC_IPC_TEST_H_
+#define _LIBC_IPC_IPC_TEST_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/iplink.h
===================================================================
--- uspace/lib/c/include/ipc/iplink.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/iplink.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_IPLINK_H_
-#define LIBC_IPC_IPLINK_H_
+#ifndef _LIBC_IPC_IPLINK_H_
+#define _LIBC_IPC_IPLINK_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/irc.h
===================================================================
--- uspace/lib/c/include/ipc/irc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/irc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_IRC_H_
-#define LIBC_IPC_IRC_H_
+#ifndef _LIBC_IPC_IRC_H_
+#define _LIBC_IPC_IRC_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/irq.h
===================================================================
--- uspace/lib/c/include/ipc/irq.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/irq.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_IRQ_H_
-#define LIBC_IPC_IRQ_H_
+#ifndef _LIBC_IPC_IRQ_H_
+#define _LIBC_IPC_IRQ_H_
 
 #include <types/common.h>
Index: uspace/lib/c/include/ipc/kbdev.h
===================================================================
--- uspace/lib/c/include/ipc/kbdev.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/kbdev.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_KBDEV_H_
-#define LIBC_IPC_KBDEV_H_
+#ifndef _LIBC_IPC_KBDEV_H_
+#define _LIBC_IPC_KBDEV_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/loader.h
===================================================================
--- uspace/lib/c/include/ipc/loader.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/loader.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_LOADER_H_
-#define LIBC_IPC_LOADER_H_
+#ifndef _LIBC_IPC_LOADER_H_
+#define _LIBC_IPC_LOADER_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/loc.h
===================================================================
--- uspace/lib/c/include/ipc/loc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/loc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -32,6 +32,6 @@
  */
 
-#ifndef LIBC_IPC_LOC_H_
-#define LIBC_IPC_LOC_H_
+#ifndef _LIBC_IPC_LOC_H_
+#define _LIBC_IPC_LOC_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/logger.h
===================================================================
--- uspace/lib/c/include/ipc/logger.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/logger.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_IPC_LOGGER_H_
-#define LIBC_IPC_LOGGER_H_
+#ifndef _LIBC_IPC_LOGGER_H_
+#define _LIBC_IPC_LOGGER_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/mouseev.h
===================================================================
--- uspace/lib/c/include/ipc/mouseev.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/mouseev.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_IPC_MOUSEEV_H_
-#define LIBC_IPC_MOUSEEV_H_
+#ifndef _LIBC_IPC_MOUSEEV_H_
+#define _LIBC_IPC_MOUSEEV_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/ns.h
===================================================================
--- uspace/lib/c/include/ipc/ns.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/ns.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_NS_H_
-#define LIBC_IPC_NS_H_
+#ifndef _LIBC_IPC_NS_H_
+#define _LIBC_IPC_NS_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/output.h
===================================================================
--- uspace/lib/c/include/ipc/output.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/output.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_OUTPUT_H_
-#define LIBC_IPC_OUTPUT_H_
+#ifndef _LIBC_IPC_OUTPUT_H_
+#define _LIBC_IPC_OUTPUT_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/pci.h
===================================================================
--- uspace/lib/c/include/ipc/pci.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/include/ipc/pci.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019 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 libcipc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_IPC_PCI_H_
+#define _LIBC_IPC_PCI_H_
+
+#include <ipc/common.h>
+
+/** PCI control service requests */
+typedef enum {
+	PCI_GET_DEVICES = IPC_FIRST_USER_METHOD,
+	PCI_DEV_GET_INFO
+} pci_request_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/c/include/ipc/serial_ctl.h
===================================================================
--- uspace/lib/c/include/ipc/serial_ctl.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/serial_ctl.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,6 +27,6 @@
  */
 
-#ifndef LIBC_IPC_SERIAL_CTL_H_
-#define LIBC_IPC_SERIAL_CTL_H_
+#ifndef _LIBC_IPC_SERIAL_CTL_H_
+#define _LIBC_IPC_SERIAL_CTL_H_
 
 #include <ipc/chardev.h>
Index: uspace/lib/c/include/ipc/services.h
===================================================================
--- uspace/lib/c/include/ipc/services.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/services.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,6 +35,6 @@
  */
 
-#ifndef LIBC_SERVICES_H_
-#define LIBC_SERVICES_H_
+#ifndef _LIBC_SERVICES_H_
+#define _LIBC_SERVICES_H_
 
 #include <abi/fourcc.h>
Index: uspace/lib/c/include/ipc/tcp.h
===================================================================
--- uspace/lib/c/include/ipc/tcp.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/tcp.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_TCP_H_
-#define LIBC_IPC_TCP_H_
+#ifndef _LIBC_IPC_TCP_H_
+#define _LIBC_IPC_TCP_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/udp.h
===================================================================
--- uspace/lib/c/include/ipc/udp.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/udp.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_UDP_H_
-#define LIBC_IPC_UDP_H_
+#ifndef _LIBC_IPC_UDP_H_
+#define _LIBC_IPC_UDP_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/vbd.h
===================================================================
--- uspace/lib/c/include/ipc/vbd.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/vbd.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_IPC_VBD_H_
-#define LIBC_IPC_VBD_H_
+#ifndef _LIBC_IPC_VBD_H_
+#define _LIBC_IPC_VBD_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/vfs.h
===================================================================
--- uspace/lib/c/include/ipc/vfs.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/vfs.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_VFS_H_
-#define LIBC_IPC_VFS_H_
+#ifndef _LIBC_IPC_VFS_H_
+#define _LIBC_IPC_VFS_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/vol.h
===================================================================
--- uspace/lib/c/include/ipc/vol.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/vol.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_IPC_VOL_H_
-#define LIBC_IPC_VOL_H_
+#ifndef _LIBC_IPC_VOL_H_
+#define _LIBC_IPC_VOL_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/window.h
===================================================================
--- uspace/lib/c/include/ipc/window.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/window.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_WINDOW_H_
-#define LIBC_IPC_WINDOW_H_
+#ifndef _LIBC_IPC_WINDOW_H_
+#define _LIBC_IPC_WINDOW_H_
 
 #include <ipc/vfs.h>
Index: uspace/lib/c/include/ipc_test.h
===================================================================
--- uspace/lib/c/include/ipc_test.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc_test.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_TEST_H_
-#define LIBC_IPC_TEST_H_
+#ifndef _LIBC_IPC_TEST_H_
+#define _LIBC_IPC_TEST_H_
 
 #include <async.h>
Index: uspace/lib/c/include/irc.h
===================================================================
--- uspace/lib/c/include/irc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/irc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IRC_H_
-#define LIBC_IRC_H_
+#ifndef _LIBC_IRC_H_
+#define _LIBC_IRC_H_
 
 extern errno_t irc_enable_interrupt(int);
Index: uspace/lib/c/include/l18n/langs.h
===================================================================
--- uspace/lib/c/include/l18n/langs.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/l18n/langs.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_L18N_LANGS_H_
-#define LIBC_L18N_LANGS_H_
+#ifndef _LIBC_L18N_LANGS_H_
+#define _LIBC_L18N_LANGS_H_
 
 /** Windows locale IDs.
Index: uspace/lib/c/include/libc.h
===================================================================
--- uspace/lib/c/include/libc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/libc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_LIBC_H_
-#define LIBC_LIBC_H_
+#ifndef _LIBC_LIBC_H_
+#define _LIBC_LIBC_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/loader/loader.h
===================================================================
--- uspace/lib/c/include/loader/loader.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/loader/loader.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_LOADER_H_
-#define LIBC_LOADER_H_
+#ifndef _LIBC_LOADER_H_
+#define _LIBC_LOADER_H_
 
 #include <abi/proc/task.h>
Index: uspace/lib/c/include/loader/pcb.h
===================================================================
--- uspace/lib/c/include/loader/pcb.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/loader/pcb.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_PCB_H_
-#define LIBC_PCB_H_
+#ifndef _LIBC_PCB_H_
+#define _LIBC_PCB_H_
 
 #include <tls.h>
Index: uspace/lib/c/include/loc.h
===================================================================
--- uspace/lib/c/include/loc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/loc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_LOC_H_
-#define LIBC_LOC_H_
+#ifndef _LIBC_LOC_H_
+#define _LIBC_LOC_H_
 
 #include <ipc/loc.h>
Index: uspace/lib/c/include/macros.h
===================================================================
--- uspace/lib/c/include/macros.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/macros.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_MACROS_H_
-#define LIBC_MACROS_H_
+#ifndef _LIBC_MACROS_H_
+#define _LIBC_MACROS_H_
 
 #define min(a, b)  ((a) < (b) ? (a) : (b))
Index: uspace/lib/c/include/malloc.h
===================================================================
--- uspace/lib/c/include/malloc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/malloc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,8 +33,11 @@
  */
 
-#ifndef LIBC_MALLOC_H_
-#define LIBC_MALLOC_H_
+#ifndef _LIBC_MALLOC_H_
+#define _LIBC_MALLOC_H_
 
 #include <stddef.h>
+#include <_bits/decls.h>
+
+__C_DECLS_BEGIN;
 
 extern void *malloc(size_t size)
@@ -42,10 +45,19 @@
 extern void *calloc(size_t nmemb, size_t size)
     __attribute__((malloc));
-extern void *memalign(size_t align, size_t size)
-    __attribute__((malloc));
 extern void *realloc(void *addr, size_t size)
     __attribute__((warn_unused_result));
 extern void free(void *addr);
+
+__C_DECLS_END;
+
+#ifdef _HELENOS_SOURCE
+__HELENOS_DECLS_BEGIN;
+
+extern void *memalign(size_t align, size_t size)
+    __attribute__((malloc));
 extern void *heap_check(void);
+
+__HELENOS_DECLS_END;
+#endif
 
 #endif
Index: uspace/lib/c/include/mem.h
===================================================================
--- uspace/lib/c/include/mem.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/mem.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,16 +34,16 @@
  */
 
-#ifndef LIBC_MEM_H_
-#define LIBC_MEM_H_
+#ifndef _LIBC_MEM_H_
+#define _LIBC_MEM_H_
 
 #include <stddef.h>
-#include <cc.h>
+#include <_bits/decls.h>
+
+__C_DECLS_BEGIN;
 
 extern void *memset(void *, int, size_t)
-    __attribute__((nonnull(1)))
-    ATTRIBUTE_OPTIMIZE("-fno-tree-loop-distribute-patterns");
+    __attribute__((nonnull(1)));
 extern void *memcpy(void *, const void *, size_t)
-    __attribute__((nonnull(1, 2)))
-    ATTRIBUTE_OPTIMIZE("-fno-tree-loop-distribute-patterns");
+    __attribute__((nonnull(1, 2)));
 extern void *memmove(void *, const void *, size_t)
     __attribute__((nonnull(1, 2)));
@@ -53,4 +53,6 @@
     __attribute__((nonnull(1)));
 
+__C_DECLS_END;
+
 #endif
 
Index: uspace/lib/c/include/nic/eth_phys.h
===================================================================
--- uspace/lib/c/include/nic/eth_phys.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/nic/eth_phys.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -28,6 +28,6 @@
  */
 
-#ifndef LIBC_NIC_ETH_PHYS_H_
-#define LIBC_NIC_ETH_PHYS_H_
+#ifndef _LIBC_NIC_ETH_PHYS_H_
+#define _LIBC_NIC_ETH_PHYS_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/nic/nic.h
===================================================================
--- uspace/lib/c/include/nic/nic.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/nic/nic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -36,6 +36,6 @@
  */
 
-#ifndef LIBC_NIC_H_
-#define LIBC_NIC_H_
+#ifndef _LIBC_NIC_H_
+#define _LIBC_NIC_H_
 
 #include <nic/eth_phys.h>
Index: uspace/lib/c/include/ns.h
===================================================================
--- uspace/lib/c/include/ns.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ns.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_NS_H_
-#define LIBC_NS_H_
+#ifndef _LIBC_NS_H_
+#define _LIBC_NS_H_
 
 #include <ipc/services.h>
Index: uspace/lib/c/include/offset.h
===================================================================
--- uspace/lib/c/include/offset.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/offset.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,8 +33,14 @@
  */
 
-#ifndef LIBC_OFFSET_H_
-#define LIBC_OFFSET_H_
+#ifndef _LIBC_OFFSET_H_
+#define _LIBC_OFFSET_H_
+
+#ifndef _HELENOS_SOURCE
+#error This file should only be included from HelenOS sources
+#endif
 
 #include <stdint.h>
+#include <_bits/decls.h>
+#include <_bits/off64_t.h>
 
 /* off64_t */
@@ -52,9 +58,10 @@
 #define PRIXOFF64 PRIX64
 
-/** Relative offset */
-typedef int64_t off64_t;
+__HELENOS_DECLS_BEGIN;
 
 /** Absolute offset */
 typedef uint64_t aoff64_t;
+
+__HELENOS_DECLS_END;
 
 #endif
Index: uspace/lib/c/include/pci.h
===================================================================
--- uspace/lib/c/include/pci.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/include/pci.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_PCI_H_
+#define _LIBC_PCI_H_
+
+#include <errno.h>
+#include <ipc/devman.h>
+#include <loc.h>
+#include <types/pci.h>
+
+extern errno_t pci_open(service_id_t, pci_t **);
+extern void pci_close(pci_t *);
+extern errno_t pci_get_devices(pci_t *, devman_handle_t **, size_t *);
+extern errno_t pci_dev_get_info(pci_t *, devman_handle_t, pci_dev_info_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/perf.h
===================================================================
--- uspace/lib/c/include/perf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/include/perf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2018 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
+ * System performance measurement utilities.
+ */
+
+#ifndef _LIBC_PERF_H_
+#define _LIBC_PERF_H_
+
+#include <time.h>
+
+/** Stopwatch is THE way to measure elapsed time on HelenOS. */
+typedef struct {
+	struct timespec start;
+	struct timespec end;
+} stopwatch_t;
+
+#define STOPWATCH_INITIALIZE_STATIC { { 0, 0 }, { 0, 0 } }
+
+/** Initialize system stopwatch.
+ *
+ * @param stopwatch Stopwatch to initialize.
+ */
+static inline void stopwatch_init(stopwatch_t *stopwatch)
+{
+	stopwatch->start.tv_sec = 0;
+	stopwatch->start.tv_nsec = 0;
+	stopwatch->end.tv_sec = 0;
+	stopwatch->end.tv_nsec = 0;
+}
+
+/** Emulate elapsed time for use in tests.
+ *
+ * @param stopwatch Stopwatch to use.
+ * @param nanos Elapsed time in nanoseconds to set.
+ */
+static inline void stopwatch_set_nanos(stopwatch_t *stopwatch, nsec_t nanos)
+{
+	stopwatch->start.tv_sec = 0;
+	stopwatch->start.tv_nsec = 0;
+	stopwatch->end.tv_sec = NSEC2SEC(nanos);
+	stopwatch->end.tv_nsec = nanos - SEC2NSEC(stopwatch->end.tv_sec);
+}
+
+/** Start the stopwatch.
+ *
+ * Note that repeated starts/stops do NOT aggregate the elapsed time.
+ *
+ * @param stopwatch Stopwatch to start.
+ */
+static inline void stopwatch_start(stopwatch_t *stopwatch)
+{
+	getuptime(&stopwatch->start);
+}
+
+/** Stop the stopwatch.
+ *
+ * Note that repeated starts/stops do NOT aggregate the elapsed time.
+ *
+ * @param stopwatch Stopwatch to stop.
+ */
+static inline void stopwatch_stop(stopwatch_t *stopwatch)
+{
+	getuptime(&stopwatch->end);
+}
+
+/** Get elapsed time in nanoseconds.
+ *
+ * @param stopwatch Stopwatch to read from.
+ * @return Elapsed time in nanoseconds.
+ */
+static inline nsec_t stopwatch_get_nanos(stopwatch_t *stopwatch)
+{
+	return ts_sub_diff(&stopwatch->end, &stopwatch->start);
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/qsort.h
===================================================================
--- uspace/lib/c/include/qsort.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/qsort.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,13 +33,21 @@
  */
 
-#ifndef LIBC_QSORT_H_
-#define LIBC_QSORT_H_
+#ifndef _LIBC_QSORT_H_
+#define _LIBC_QSORT_H_
 
 #include <stddef.h>
+#include <_bits/decls.h>
 
+__C_DECLS_BEGIN;
 extern void qsort(void *, size_t, size_t, int (*)(const void *,
     const void *));
+__C_DECLS_END;
+
+#ifdef _HELENOS_SOURCE
+__HELENOS_DECLS_BEGIN;
 extern void qsort_r(void *, size_t, size_t, int (*)(const void *,
     const void *, void *), void *);
+__HELENOS_DECLS_END;
+#endif
 
 #endif
Index: uspace/lib/c/include/refcount.h
===================================================================
--- uspace/lib/c/include/refcount.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/refcount.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,6 +37,6 @@
  */
 
-#ifndef LIBC_REFCOUNT_H_
-#define LIBC_REFCOUNT_H_
+#ifndef _LIBC_REFCOUNT_H_
+#define _LIBC_REFCOUNT_H_
 
 #include <assert.h>
Index: uspace/lib/c/include/rndgen.h
===================================================================
--- uspace/lib/c/include/rndgen.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/rndgen.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_RNDGEN_H_
-#define LIBC_RNDGEN_H_
+#ifndef _LIBC_RNDGEN_H_
+#define _LIBC_RNDGEN_H_
 
 #include <errno.h>
Index: uspace/lib/c/include/rtld/dynamic.h
===================================================================
--- uspace/lib/c/include/rtld/dynamic.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/rtld/dynamic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_RTLD_DYNAMIC_H_
-#define LIBC_RTLD_DYNAMIC_H_
+#ifndef _LIBC_RTLD_DYNAMIC_H_
+#define _LIBC_RTLD_DYNAMIC_H_
 
 #include <stdbool.h>
Index: uspace/lib/c/include/rtld/elf_dyn.h
===================================================================
--- uspace/lib/c/include/rtld/elf_dyn.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/rtld/elf_dyn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,84 +33,9 @@
  */
 
-#ifndef LIBC_RTLD_ELF_DYN_H_
-#define LIBC_RTLD_ELF_DYN_H_
+#ifndef _LIBC_RTLD_ELF_DYN_H_
+#define _LIBC_RTLD_ELF_DYN_H_
 
 #include <elf/elf.h>
 #include <libarch/rtld/elf_dyn.h>
-
-#define ELF32_R_SYM(i) ((i)>>8)
-#define ELF32_R_TYPE(i) ((unsigned char)(i))
-
-struct elf32_dyn {
-	elf_sword d_tag;
-	union {
-		elf_word d_val;
-		elf32_addr d_ptr;
-	} d_un;
-};
-
-struct elf32_rel {
-	elf32_addr r_offset;
-	elf_word r_info;
-};
-
-struct elf32_rela {
-	elf32_addr r_offset;
-	elf_word r_info;
-	elf_sword r_addend;
-};
-
-#ifdef __32_BITS__
-typedef struct elf32_dyn elf_dyn_t;
-typedef struct elf32_rel elf_rel_t;
-typedef struct elf32_rela elf_rela_t;
-#endif
-
-/*
- * Dynamic array tags
- */
-#define DT_NULL		0
-#define DT_NEEDED	1
-#define DT_PLTRELSZ	2
-#define DT_PLTGOT	3
-#define DT_HASH		4
-#define DT_STRTAB	5
-#define DT_SYMTAB	6
-#define DT_RELA		7
-#define DT_RELASZ	8
-#define DT_RELAENT	9
-#define DT_STRSZ	10
-#define DT_SYMENT	11
-#define DT_INIT		12
-#define DT_FINI		13
-#define DT_SONAME	14
-#define DT_RPATH	15
-#define DT_SYMBOLIC	16
-#define DT_REL		17
-#define DT_RELSZ	18
-#define DT_RELENT	19
-#define DT_PLTREL	20
-#define DT_DEBUG	21
-#define DT_TEXTREL	22
-#define DT_JMPREL	23
-#define DT_BIND_NOW	24
-#define DT_LOPROC	0x70000000
-#define DT_HIPROC	0x7fffffff
-
-/*
- * Special section indexes
- */
-#define SHN_UNDEF	0
-#define SHN_LORESERVE	0xff00
-#define SHN_LOPROC	0xff00
-#define SHN_HIPROC	0xff1f
-#define SHN_ABS		0xfff1
-#define SHN_COMMON	0xfff2
-#define SHN_HIRESERVE	0xffff
-
-/*
- * Special symbol table index
- */
-#define STN_UNDEF	0
 
 #endif
Index: uspace/lib/c/include/rtld/module.h
===================================================================
--- uspace/lib/c/include/rtld/module.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_RTLD_MODULE_H_
-#define LIBC_RTLD_MODULE_H_
+#ifndef _LIBC_RTLD_MODULE_H_
+#define _LIBC_RTLD_MODULE_H_
 
 #include <rtld/dynamic.h>
@@ -45,5 +45,5 @@
 extern module_t *module_find(rtld_t *, const char *);
 extern module_t *module_load(rtld_t *, const char *, mlflags_t);
-extern void module_load_deps(module_t *, mlflags_t);
+extern errno_t module_load_deps(module_t *, mlflags_t);
 extern module_t *module_by_id(rtld_t *, unsigned long);
 
Index: uspace/lib/c/include/rtld/rtld.h
===================================================================
--- uspace/lib/c/include/rtld/rtld.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/rtld/rtld.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_RTLD_H_
-#define LIBC_RTLD_H_
+#ifndef _LIBC_RTLD_H_
+#define _LIBC_RTLD_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/include/rtld/rtld_arch.h
===================================================================
--- uspace/lib/c/include/rtld/rtld_arch.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/rtld/rtld_arch.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_RTLD_RTLD_ARCH_H_
-#define LIBC_RTLD_RTLD_ARCH_H_
+#ifndef _LIBC_RTLD_RTLD_ARCH_H_
+#define _LIBC_RTLD_RTLD_ARCH_H_
 
 #include <rtld/rtld.h>
Index: uspace/lib/c/include/rtld/rtld_debug.h
===================================================================
--- uspace/lib/c/include/rtld/rtld_debug.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/rtld/rtld_debug.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_RTLD_RTLD_DEBUG_H_
-#define LIBC_RTLD_RTLD_DEBUG_H_
+#ifndef _LIBC_RTLD_RTLD_DEBUG_H_
+#define _LIBC_RTLD_RTLD_DEBUG_H_
 
 #include <stdio.h>
Index: uspace/lib/c/include/rtld/symbol.h
===================================================================
--- uspace/lib/c/include/rtld/symbol.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/rtld/symbol.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_RTLD_SYMBOL_H_
-#define LIBC_RTLD_SYMBOL_H_
+#ifndef _LIBC_RTLD_SYMBOL_H_
+#define _LIBC_RTLD_SYMBOL_H_
 
 #include <elf/elf.h>
Index: uspace/lib/c/include/setjmp.h
===================================================================
--- uspace/lib/c/include/setjmp.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/setjmp.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,25 +31,23 @@
  */
 
-#ifndef LIBC_SETJMP_H_
-#define LIBC_SETJMP_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#ifndef _LIBC_SETJMP_H_
+#define _LIBC_SETJMP_H_
 
 #include <libarch/fibril_context.h>
 #include <_bits/__noreturn.h>
+#include <_bits/decls.h>
 
-typedef context_t jmp_buf[1];
+__C_DECLS_BEGIN;
 
-extern int __setjmp(jmp_buf) __attribute__((returns_twice));
-extern __noreturn void __longjmp(jmp_buf, int);
+typedef __context_t jmp_buf[1];
 
-#define setjmp __setjmp
+extern int __context_save(__context_t *) __attribute__((returns_twice));
+extern __noreturn void __context_restore(__context_t *, int);
+
 extern __noreturn void longjmp(jmp_buf, int);
 
-#ifdef __cplusplus
-}
-#endif
+__C_DECLS_END;
+
+#define setjmp __context_save
 
 #endif
Index: uspace/lib/c/include/smc.h
===================================================================
--- uspace/lib/c/include/smc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/smc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,7 +33,8 @@
  */
 
-#ifndef LIBC_SMC_H_
-#define LIBC_SMC_H_
+#ifndef _LIBC_SMC_H_
+#define _LIBC_SMC_H_
 
+#include <errno.h>
 #include <stddef.h>
 
Index: uspace/lib/c/include/stack.h
===================================================================
--- uspace/lib/c/include/stack.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/stack.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_STACK_H_
-#define LIBC_STACK_H_
+#ifndef _LIBC_STACK_H_
+#define _LIBC_STACK_H_
 
 #include <types/common.h>
Index: uspace/lib/c/include/stacktrace.h
===================================================================
--- uspace/lib/c/include/stacktrace.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/stacktrace.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_STACKTRACE_H_
-#define LIBC_STACKTRACE_H_
+#ifndef _LIBC_STACKTRACE_H_
+#define _LIBC_STACKTRACE_H_
 
 #include <errno.h>
Index: uspace/lib/c/include/stats.h
===================================================================
--- uspace/lib/c/include/stats.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/stats.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_STATS_H_
-#define LIBC_STATS_H_
+#ifndef _LIBC_STATS_H_
+#define _LIBC_STATS_H_
 
 #include <task.h>
Index: uspace/lib/c/include/stdio.h
===================================================================
--- uspace/lib/c/include/stdio.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/stdio.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,12 +34,7 @@
  */
 
-#ifndef LIBC_STDIO_H_
-#define LIBC_STDIO_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <offset.h>
+#ifndef _LIBC_STDIO_H_
+#define _LIBC_STDIO_H_
+
 #include <stdarg.h>
 #include <io/verify.h>
@@ -48,13 +43,5 @@
 #include <_bits/wchar_t.h>
 #include <_bits/wint_t.h>
-
-/** Forward declaration */
-struct _IO_FILE;
-typedef struct _IO_FILE FILE;
-
-/** File position */
-typedef struct {
-	off64_t pos;
-} fpos_t;
+#include <_bits/decls.h>
 
 #ifndef _HELENOS_SOURCE
@@ -70,5 +57,5 @@
 
 /** Max number of files that is guaranteed to be able to open at the same time */
-#define FOPEN_MAX VFS_MAX_OPEN_FILES
+#define FOPEN_MAX 16
 
 /** Recommended size of fixed-size array for holding file names. */
@@ -92,4 +79,15 @@
 /** Minimum number of unique temporary file names */
 #define TMP_MAX 1000000
+
+__C_DECLS_BEGIN;
+
+/** Forward declaration */
+struct _IO_FILE;
+typedef struct _IO_FILE FILE;
+
+/** File position */
+typedef struct {
+	long long pos;
+} fpos_t;
 
 extern FILE *stdin;
@@ -98,15 +96,23 @@
 
 /* Character and string input functions */
-#define getc fgetc
 extern int fgetc(FILE *);
 extern char *fgets(char *, int, FILE *);
 extern char *gets(char *, size_t) __attribute__((deprecated));
 
+static inline int getc(FILE *f)
+{
+	return fgetc(f);
+}
+
 extern int getchar(void);
 
 /* Character and string output functions */
-#define putc fputc
 extern int fputc(int, FILE *);
 extern int fputs(const char *, FILE *);
+
+static inline int putc(int i, FILE *f)
+{
+	return fputc(i, f);
+}
 
 extern int putchar(int);
@@ -180,9 +186,15 @@
 extern char *tmpnam(char *s);
 
+__C_DECLS_END;
+
 #ifdef _HELENOS_SOURCE
 
+#include <_bits/off64_t.h>
+
+__HELENOS_DECLS_BEGIN;
+
 /* Nonstandard extensions. */
 
-enum _buffer_type {
+enum __buffer_type {
 	/** No buffering */
 	_IONBF,
@@ -193,30 +205,14 @@
 };
 
-enum _buffer_state {
-	/** Buffer is empty */
-	_bs_empty,
-
-	/** Buffer contains data to be written */
-	_bs_write,
-
-	/** Buffer contains prefetched data for reading */
-	_bs_read
-};
-
-extern int vprintf_size(const char *, va_list);
-extern int printf_size(const char *, ...)
+extern int vprintf_length(const char *, va_list);
+extern int printf_length(const char *, ...)
     _HELENOS_PRINTF_ATTRIBUTE(1, 2);
 extern FILE *fdopen(int, const char *);
 extern int fileno(FILE *);
 
-#include <offset.h>
-
 extern int fseek64(FILE *, off64_t, int);
 extern off64_t ftell64(FILE *);
 
-#endif
-
-#ifdef __cplusplus
-}
+__HELENOS_DECLS_END;
 #endif
 
Index: uspace/lib/c/include/stdlib.h
===================================================================
--- uspace/lib/c/include/stdlib.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/stdlib.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,16 +33,22 @@
  */
 
-#ifndef LIBC_STDLIB_H_
-#define LIBC_STDLIB_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#ifndef _LIBC_STDLIB_H_
+#define _LIBC_STDLIB_H_
 
 #include <_bits/size_t.h>
 #include <_bits/wchar_t.h>
+#include <_bits/decls.h>
 #include <bsearch.h>
 #include <malloc.h>
 #include <qsort.h>
+
+#define EXIT_SUCCESS 0
+#define EXIT_FAILURE 1
+
+#define RAND_MAX  714025
+
+#define MB_CUR_MAX 4
+
+__C_DECLS_BEGIN;
 
 /** Type returned by the div function */
@@ -69,11 +75,4 @@
 	long long rem;
 } lldiv_t;
-
-#define EXIT_FAILURE 1
-#define EXIT_SUCCESS 0
-
-#define RAND_MAX  714025
-
-#define MB_CUR_MAX 4
 
 extern long double strtold(const char *, char **);
@@ -109,7 +108,5 @@
 extern lldiv_t lldiv(long long, long long);
 
-#ifdef __cplusplus
-}
-#endif
+__C_DECLS_END;
 
 #endif
Index: uspace/lib/c/include/str.h
===================================================================
--- uspace/lib/c/include/str.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/str.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,3 +1,4 @@
 /*
+ * Copyright (c) 2001-2004 Jakub Jermar
  * Copyright (c) 2005 Martin Decky
  * Copyright (c) 2011 Oleg Romanenko
@@ -34,18 +35,19 @@
  */
 
-#ifndef LIBC_STR_H_
-#define LIBC_STR_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#ifndef _LIBC_STR_H_
+#define _LIBC_STR_H_
 
 #include <errno.h>
-#include <mem.h>
+#include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
-#include <stdbool.h>
 
-#define U_SPECIAL  '?'
+#include <mem.h>
+#include <_bits/decls.h>
+
+#ifndef __cplusplus
+
+/* Common Unicode characters */
+#define U_SPECIAL      '?'
 
 /** No size limit constant */
@@ -61,7 +63,11 @@
 #define SPASCII_STR_BUFSIZE(spa_size) ((spa_size) + 1)
 
+#endif
+
+__HELENOS_DECLS_BEGIN;
+
 extern wchar_t str_decode(const char *str, size_t *offset, size_t sz);
 extern wchar_t str_decode_reverse(const char *str, size_t *offset, size_t sz);
-extern errno_t chr_encode(const wchar_t ch, char *str, size_t *offset, size_t sz);
+extern errno_t chr_encode(wchar_t ch, char *str, size_t *offset, size_t sz);
 
 extern size_t str_size(const char *str);
@@ -116,6 +122,6 @@
 extern bool wstr_remove(wchar_t *str, size_t pos);
 
-extern char *str_dup(const char *);
-extern char *str_ndup(const char *, size_t max_size);
+extern char *str_dup(const char *src);
+extern char *str_ndup(const char *src, size_t n);
 
 extern char *str_tok(char *, const char *, char **);
@@ -144,7 +150,5 @@
 extern unsigned long strtoul(const char *, char **, int);
 
-#ifdef __cplusplus
-}
-#endif
+__HELENOS_DECLS_END;
 
 #endif
Index: uspace/lib/c/include/str_error.h
===================================================================
--- uspace/lib/c/include/str_error.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/str_error.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_STRERROR_H_
-#define LIBC_STRERROR_H_
+#ifndef _LIBC_STRERROR_H_
+#define _LIBC_STRERROR_H_
 
 #include <errno.h>
Index: uspace/lib/c/include/string.h
===================================================================
--- uspace/lib/c/include/string.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/string.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,14 +33,18 @@
  */
 
-#ifndef LIBC_STRING_H_
-#define LIBC_STRING_H_
+#ifndef _LIBC_STRING_H_
+#define _LIBC_STRING_H_
 
-#if defined(_HELENOS_SOURCE) && !defined(_REALLY_WANT_STRING_H)
+#if defined(_HELENOS_SOURCE) && !defined(_REALLY_WANT_STRING_H) && \
+    !defined(_LIBC_SOURCE)
 #error Please use str.h and mem.h instead
 #endif
 
+#include <_bits/decls.h>
 #include <_bits/size_t.h>
 #include <_bits/NULL.h>
 #include <mem.h>
+
+__C_DECLS_BEGIN;
 
 extern char *strcpy(char *, const char *);
@@ -63,4 +67,12 @@
 extern size_t strlen(const char *);
 
+#if defined(_HELENOS_SOURCE) || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_LIBC_SOURCE)
+extern size_t strnlen(const char *, size_t);
+extern char *strdup(const char *);
+extern char *strndup(const char *, size_t);
+#endif
+
+__C_DECLS_END;
+
 #endif
 
Index: uspace/lib/c/include/syscall.h
===================================================================
--- uspace/lib/c/include/syscall.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,6 +37,6 @@
  */
 
-#ifndef LIBC_SYSCALL_H_
-#define LIBC_SYSCALL_H_
+#ifndef _LIBC_SYSCALL_H_
+#define _LIBC_SYSCALL_H_
 
 #ifndef LIBARCH_SYSCALL_GENERIC
Index: uspace/lib/c/include/sysinfo.h
===================================================================
--- uspace/lib/c/include/sysinfo.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/sysinfo.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_SYSINFO_H_
-#define LIBC_SYSINFO_H_
+#ifndef _LIBC_SYSINFO_H_
+#define _LIBC_SYSINFO_H_
 
 #include <types/common.h>
Index: uspace/lib/c/include/task.h
===================================================================
--- uspace/lib/c/include/task.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/task.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TASK_H_
-#define LIBC_TASK_H_
+#ifndef _LIBC_TASK_H_
+#define _LIBC_TASK_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/time.h
===================================================================
--- uspace/lib/c/include/time.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/time.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,10 +33,8 @@
  */
 
-#ifndef LIBC_TIME_H_
-#define LIBC_TIME_H_
+#ifndef _LIBC_TIME_H_
+#define _LIBC_TIME_H_
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include <_bits/decls.h>
 
 /* ISO/IEC 9899:2011 7.27.1 (2) */
@@ -52,4 +50,6 @@
 #include <_bits/size_t.h>
 
+__C_DECLS_BEGIN;
+
 /* ISO/IEC 9899:2011 7.27.1 (3), (4) */
 
@@ -64,7 +64,5 @@
 struct tm {
 	int tm_sec;
-#ifdef _HELENOS_SOURCE
-	int tm_nsec;
-#endif
+	int tm_nsec;  /**< Nonstandard extension, nanoseconds since last second. */
 	int tm_min;
 	int tm_hour;
@@ -108,4 +106,6 @@
     const struct tm *__restrict__);
 
+__C_DECLS_END;
+
 #ifdef _HELENOS_SOURCE
 
@@ -116,4 +116,6 @@
 #include <stdbool.h>
 #include <_bits/errno.h>
+
+__HELENOS_DECLS_BEGIN;
 
 typedef long long sec_t;
@@ -157,9 +159,7 @@
 extern void udelay(sysarg_t);
 
+__HELENOS_DECLS_END;
+
 #endif /* _HELENOS_SOURCE */
-
-#ifdef __cplusplus
-}
-#endif
 
 #endif
Index: uspace/lib/c/include/tls.h
===================================================================
--- uspace/lib/c/include/tls.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TLS_H_
-#define LIBC_TLS_H_
+#ifndef _LIBC_TLS_H_
+#define _LIBC_TLS_H_
 
 #include <libarch/tls.h>
Index: uspace/lib/c/include/tmpfile.h
===================================================================
--- uspace/lib/c/include/tmpfile.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/tmpfile.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,6 +27,6 @@
  */
 
-#ifndef LIBC_TMPFILE_H_
-#define LIBC_TMPFILE_H_
+#ifndef _LIBC_TMPFILE_H_
+#define _LIBC_TMPFILE_H_
 
 #include <stdbool.h>
Index: uspace/lib/c/include/trace.h
===================================================================
--- uspace/lib/c/include/trace.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/trace.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,8 +33,8 @@
  */
 
-#ifndef LIBC_TRACE_H_
-#define LIBC_TRACE_H_
+#ifndef _LIBC_TRACE_H_
+#define _LIBC_TRACE_H_
 
-#define NO_TRACE  __attribute__((no_instrument_function))
+#define _NO_TRACE  __attribute__((no_instrument_function))
 
 #endif
Index: uspace/lib/c/include/types/casting.h
===================================================================
--- uspace/lib/c/include/types/casting.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/include/types/casting.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2019 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
+ */
+
+#ifndef _LIBC_TYPES_CASTING_H_
+#define _LIBC_TYPES_CASTING_H_
+
+#include <stdbool.h>
+#include <stddef.h>
+
+/**
+ * Checks that the size_t value can be casted to int without loss of data.
+ *
+ * @param val Value to test.
+ * @return Whether it is safe to typecast value to int.
+ */
+static inline bool can_cast_size_t_to_int(size_t val)
+{
+	unsigned int as_uint = (unsigned int) val;
+	return !((as_uint != val) || (((int) as_uint) < 0));
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/types/common.h
===================================================================
--- uspace/lib/c/include/types/common.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/common.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_COMMON_H_
-#define LIBC_TYPES_COMMON_H_
+#ifndef _LIBC_TYPES_COMMON_H_
+#define _LIBC_TYPES_COMMON_H_
 
 #if __SIZEOF_POINTER__ == 4
Index: uspace/lib/c/include/types/inet.h
===================================================================
--- uspace/lib/c/include/types/inet.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/inet.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_INET_H_
-#define LIBC_TYPES_INET_H_
+#ifndef _LIBC_TYPES_INET_H_
+#define _LIBC_TYPES_INET_H_
 
 #include <inet/addr.h>
Index: uspace/lib/c/include/types/inet/host.h
===================================================================
--- uspace/lib/c/include/types/inet/host.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/inet/host.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_INET_HOST_H_
-#define LIBC_TYPES_INET_HOST_H_
+#ifndef _LIBC_TYPES_INET_HOST_H_
+#define _LIBC_TYPES_INET_HOST_H_
 
 #include <inet/addr.h>
Index: uspace/lib/c/include/types/inet/hostport.h
===================================================================
--- uspace/lib/c/include/types/inet/hostport.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/inet/hostport.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_INET_HOSTPORT_H_
-#define LIBC_TYPES_INET_HOSTPORT_H_
+#ifndef _LIBC_TYPES_INET_HOSTPORT_H_
+#define _LIBC_TYPES_INET_HOSTPORT_H_
 
 #include <inet/addr.h>
Index: uspace/lib/c/include/types/inetcfg.h
===================================================================
--- uspace/lib/c/include/types/inetcfg.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/inetcfg.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_INETCFG_H_
-#define LIBC_TYPES_INETCFG_H_
+#ifndef _LIBC_TYPES_INETCFG_H_
+#define _LIBC_TYPES_INETCFG_H_
 
 #include <inet/inet.h>
Index: uspace/lib/c/include/types/inetping.h
===================================================================
--- uspace/lib/c/include/types/inetping.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/inetping.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,6 +35,6 @@
  */
 
-#ifndef LIBC_TYPES_INETPING_H_
-#define LIBC_TYPES_INETPING_H_
+#ifndef _LIBC_TYPES_INETPING_H_
+#define _LIBC_TYPES_INETPING_H_
 
 #include <inet/addr.h>
Index: uspace/lib/c/include/types/io/chardev.h
===================================================================
--- uspace/lib/c/include/types/io/chardev.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/include/types/io/chardev.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019 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 libc
+ * @{
+ */
+
+#ifndef _LIBC_TYPES_IO_CHARDEV_H_
+#define _LIBC_TYPES_IO_CHARDEV_H_
+
+/** Chardev read/write operation flags */
+typedef enum {
+	/** No flags */
+	chardev_f_none = 0,
+	/** Do not block even if no bytes can be transferred */
+	chardev_f_nonblock = 0x1
+} chardev_flags_t;
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/c/include/types/label.h
===================================================================
--- uspace/lib/c/include/types/label.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/label.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_LABEL_H_
-#define LIBC_TYPES_LABEL_H_
+#ifndef _LIBC_TYPES_LABEL_H_
+#define _LIBC_TYPES_LABEL_H_
 
 #include <types/uuid.h>
Index: uspace/lib/c/include/types/pci.h
===================================================================
--- uspace/lib/c/include/types/pci.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/include/types/pci.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2019 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_TYPES_PCI_H_
+#define _LIBC_TYPES_PCI_H_
+
+#include <async.h>
+#include <ipc/devman.h>
+#include <stdint.h>
+
+/** PCI device information */
+typedef struct {
+	/** Devman function handle */
+	devman_handle_t dev_handle;
+	/** Bus number */
+	uint8_t bus_num;
+	/** Device number */
+	uint8_t dev_num;
+	/** Function number */
+	uint8_t fn_num;
+	/** Vendor ID */
+	uint16_t vendor_id;
+	/** Device ID */
+	uint16_t device_id;
+} pci_dev_info_t;
+
+/** PCI service */
+typedef struct {
+	/** Session with PCI control service */
+	async_sess_t *sess;
+} pci_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/types/rtld/module.h
===================================================================
--- uspace/lib/c/include/types/rtld/module.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_RTLD_MODULE_H_
-#define LIBC_TYPES_RTLD_MODULE_H_
+#ifndef _LIBC_TYPES_RTLD_MODULE_H_
+#define _LIBC_TYPES_RTLD_MODULE_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/include/types/rtld/rtld.h
===================================================================
--- uspace/lib/c/include/types/rtld/rtld.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/rtld/rtld.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_RTLD_RTLD_H_
-#define LIBC_TYPES_RTLD_RTLD_H_
+#ifndef _LIBC_TYPES_RTLD_RTLD_H_
+#define _LIBC_TYPES_RTLD_RTLD_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/include/types/task.h
===================================================================
--- uspace/lib/c/include/types/task.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/task.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_TASK_H_
-#define LIBC_TYPES_TASK_H_
+#ifndef _LIBC_TYPES_TASK_H_
+#define _LIBC_TYPES_TASK_H_
 
 typedef enum {
Index: uspace/lib/c/include/types/uuid.h
===================================================================
--- uspace/lib/c/include/types/uuid.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/uuid.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_UUID_H_
-#define LIBC_TYPES_UUID_H_
+#ifndef _LIBC_TYPES_UUID_H_
+#define _LIBC_TYPES_UUID_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/types/vol.h
===================================================================
--- uspace/lib/c/include/types/vol.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/vol.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_VOL_H_
-#define LIBC_TYPES_VOL_H_
+#ifndef _LIBC_TYPES_VOL_H_
+#define _LIBC_TYPES_VOL_H_
 
 #include <async.h>
Index: uspace/lib/c/include/udebug.h
===================================================================
--- uspace/lib/c/include/udebug.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/udebug.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_UDEBUG_H_
-#define LIBC_UDEBUG_H_
+#ifndef _LIBC_UDEBUG_H_
+#define _LIBC_UDEBUG_H_
 
 #include <abi/udebug.h>
Index: uspace/lib/c/include/unaligned.h
===================================================================
--- uspace/lib/c/include/unaligned.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/unaligned.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_UNALIGNED_H_
-#define LIBC_UNALIGNED_H_
+#ifndef _LIBC_UNALIGNED_H_
+#define _LIBC_UNALIGNED_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/uuid.h
===================================================================
--- uspace/lib/c/include/uuid.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/uuid.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,9 +33,10 @@
  */
 
-#ifndef LIBC_UUID_H_
-#define LIBC_UUID_H_
+#ifndef _LIBC_UUID_H_
+#define _LIBC_UUID_H_
 
 #include <stdint.h>
 #include <types/uuid.h>
+#include <stdbool.h>
 
 extern errno_t uuid_generate(uuid_t *);
@@ -43,5 +44,5 @@
 extern void uuid_decode(uint8_t *, uuid_t *);
 extern errno_t uuid_parse(const char *, uuid_t *, const char **);
-extern errno_t uuid_format(uuid_t *, char **);
+extern errno_t uuid_format(uuid_t *, char **, bool);
 
 #endif
Index: uspace/lib/c/include/vbd.h
===================================================================
--- uspace/lib/c/include/vbd.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/vbd.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_VBD_H_
-#define LIBC_VBD_H_
+#ifndef _LIBC_VBD_H_
+#define _LIBC_VBD_H_
 
 #include <async.h>
Index: uspace/lib/c/include/vfs/canonify.h
===================================================================
--- uspace/lib/c/include/vfs/canonify.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/vfs/canonify.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_VFS_CANONIFY_H_
-#define LIBC_VFS_CANONIFY_H_
+#ifndef _LIBC_VFS_CANONIFY_H_
+#define _LIBC_VFS_CANONIFY_H_
 
 #include <stddef.h>
Index: uspace/lib/c/include/vfs/inbox.h
===================================================================
--- uspace/lib/c/include/vfs/inbox.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/vfs/inbox.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -36,6 +36,6 @@
  */
 
-#ifndef LIBC_VFS_INBOX_H_
-#define LIBC_VFS_INBOX_H_
+#ifndef _LIBC_VFS_INBOX_H_
+#define _LIBC_VFS_INBOX_H_
 
 enum {
Index: uspace/lib/c/include/vfs/vfs.h
===================================================================
--- uspace/lib/c/include/vfs/vfs.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/vfs/vfs.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_VFS_H_
-#define LIBC_VFS_H_
+#ifndef _LIBC_VFS_H_
+#define _LIBC_VFS_H_
 
 #include <stddef.h>
@@ -44,6 +44,4 @@
 #include <async.h>
 #include <offset.h>
-
-#define VFS_MAX_OPEN_FILES  128
 
 enum vfs_change_state_type {
Index: uspace/lib/c/include/vfs/vfs_mtab.h
===================================================================
--- uspace/lib/c/include/vfs/vfs_mtab.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/vfs/vfs_mtab.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_VFS_MTAB_H_
-#define LIBC_VFS_MTAB_H_
+#ifndef _LIBC_VFS_MTAB_H_
+#define _LIBC_VFS_MTAB_H_
 
 #include <ipc/vfs.h>
Index: uspace/lib/c/include/vfs/vfs_sess.h
===================================================================
--- uspace/lib/c/include/vfs/vfs_sess.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/vfs/vfs_sess.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_VFS_SESS_H_
-#define LIBC_VFS_SESS_H_
+#ifndef _LIBC_VFS_SESS_H_
+#define _LIBC_VFS_SESS_H_
 
 #include <async.h>
Index: uspace/lib/c/include/vol.h
===================================================================
--- uspace/lib/c/include/vol.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/vol.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_VOL_H_
-#define LIBC_VOL_H_
+#ifndef _LIBC_VOL_H_
+#define _LIBC_VOL_H_
 
 #include <async.h>
Index: uspace/lib/c/include/wchar.h
===================================================================
--- uspace/lib/c/include/wchar.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/wchar.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,6 +38,6 @@
  */
 
-#ifndef LIBC_WCHAR_H_
-#define LIBC_WCHAR_H_
+#ifndef _LIBC_WCHAR_H_
+#define _LIBC_WCHAR_H_
 
 #include <_bits/size_t.h>
Index: uspace/lib/c/test/adt/odict.c
===================================================================
--- uspace/lib/c/test/adt/odict.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/test/adt/odict.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2016 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.
+ */
+
+#include <adt/odict.h>
+#include <pcut/pcut.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/** Test entry */
+typedef struct {
+	odlink_t odict;
+	int key;
+} test_entry_t;
+
+enum {
+	/** Length of test number sequences */
+	test_seq_len = 100
+};
+
+/** Test get key function.
+ *
+ * @param odlink Ordered dictionary link
+ * @return Pointer to key
+ */
+static void *test_getkey(odlink_t *odlink)
+{
+	return &odict_get_instance(odlink, test_entry_t, odict)->key;
+}
+
+/** Test compare function.
+ *
+ * @param a First key
+ * @param b Second key
+ * @return <0, 0, >0 if @a a is less than, equal or greater than @a b
+ */
+static int test_cmp(void *a, void *b)
+{
+	int *ia = (int *)a;
+	int *ib = (int *)b;
+
+	return *ia - *ib;
+}
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(odict);
+
+/** Increasing sequence test.
+ *
+ * Test initialization, emptiness, insertion of increasing sequence and walking.
+ */
+PCUT_TEST(incr_seq)
+{
+	odict_t odict;
+	test_entry_t *e;
+	odlink_t *c;
+	int i;
+
+	odict_initialize(&odict, test_getkey, test_cmp);
+
+	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
+
+	for (i = 0; i < test_seq_len; i++) {
+		e = calloc(1, sizeof(test_entry_t));
+		PCUT_ASSERT_NOT_NULL(e);
+
+		e->key = i;
+		odict_insert(&e->odict, &odict, NULL);
+		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
+	}
+
+	i = 0;
+	c = odict_first(&odict);
+	while (c != NULL) {
+		e = odict_get_instance(c, test_entry_t, odict);
+		PCUT_ASSERT_INT_EQUALS(i, e->key);
+		c = odict_next(c, &odict);
+		++i;
+	}
+	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
+
+	i = test_seq_len;
+	c = odict_last(&odict);
+	while (c != NULL) {
+		--i;
+		e = odict_get_instance(c, test_entry_t, odict);
+		PCUT_ASSERT_INT_EQUALS(i, e->key);
+		c = odict_prev(c, &odict);
+	}
+
+	PCUT_ASSERT_INT_EQUALS(0, i);
+}
+
+/** Decreasing sequence test.
+ *
+ * Test initialization, emptiness, insertion of decreasing sequence and walking.
+ */
+PCUT_TEST(decr_seq)
+{
+	odict_t odict;
+	test_entry_t *e;
+	odlink_t *c;
+	int i;
+
+	odict_initialize(&odict, test_getkey, test_cmp);
+
+	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
+
+	for (i = 0; i < test_seq_len; i++) {
+		e = calloc(1, sizeof(test_entry_t));
+		PCUT_ASSERT_NOT_NULL(e);
+
+		e->key = test_seq_len - i - 1;
+		odict_insert(&e->odict, &odict, NULL);
+		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
+	}
+
+	i = 0;
+	c = odict_first(&odict);
+	while (c != NULL) {
+		e = odict_get_instance(c, test_entry_t, odict);
+		PCUT_ASSERT_INT_EQUALS(i, e->key);
+		c = odict_next(c, &odict);
+		++i;
+	}
+	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
+
+	i = test_seq_len;
+	c = odict_last(&odict);
+	while (c != NULL) {
+		--i;
+		e = odict_get_instance(c, test_entry_t, odict);
+		PCUT_ASSERT_INT_EQUALS(i, e->key);
+		c = odict_prev(c, &odict);
+	}
+
+	PCUT_ASSERT_INT_EQUALS(0, i);
+}
+
+/** Increasing sequence insertion and removal test.
+ *
+ * Test sequential insertion of increasing sequence and sequential removal.
+ */
+PCUT_TEST(incr_seq_ins_rem)
+{
+	odict_t odict;
+	test_entry_t *e;
+	odlink_t *c;
+	int i;
+
+	odict_initialize(&odict, test_getkey, test_cmp);
+
+	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
+
+	for (i = 0; i < test_seq_len; i++) {
+		e = calloc(1, sizeof(test_entry_t));
+		PCUT_ASSERT_NOT_NULL(e);
+
+		e->key = i;
+		odict_insert(&e->odict, &odict, NULL);
+		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
+	}
+
+	i = 0;
+	c = odict_first(&odict);
+	while (c != NULL) {
+		e = odict_get_instance(c, test_entry_t, odict);
+		PCUT_ASSERT_INT_EQUALS(i, e->key);
+
+		odict_remove(c);
+		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
+
+		c = odict_first(&odict);
+		++i;
+	}
+
+	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
+}
+
+/** Generate pseudorandom sequence. */
+static int seq_next(int cur)
+{
+	return (cur * 1951) % 1000000;
+}
+
+/** Test 4.
+ *
+ * Test inserting a pseudorandom sequence and then extracting it again.
+ */
+PCUT_TEST(prseq_ins_extract)
+{
+	odict_t odict;
+	test_entry_t *e, *ep;
+	odlink_t *c, *d;
+	int prev;
+	int i;
+	int v;
+
+	odict_initialize(&odict, test_getkey, test_cmp);
+
+	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
+
+	v = 1;
+	ep = NULL;
+	for (i = 0; i < test_seq_len; i++) {
+		e = calloc(1, sizeof(test_entry_t));
+		PCUT_ASSERT_NOT_NULL(e);
+
+		e->key = v;
+		odict_insert(&e->odict, &odict, &ep->odict);
+		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
+		v = seq_next(v);
+		ep = e;
+	}
+
+	/* Verify that entries are in ascending order */
+	c = odict_first(&odict);
+	prev = -1;
+	i = 0;
+	while (c != NULL) {
+		e = odict_get_instance(c, test_entry_t, odict);
+		PCUT_ASSERT_EQUALS(true, e->key > prev);
+
+		prev = e->key;
+		c = odict_next(c, &odict);
+		++i;
+	}
+
+	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
+
+	/* Try extracting the sequence */
+	v = 1;
+	for (i = 0; i < test_seq_len; i++) {
+		c = odict_find_eq(&odict, (void *)&v, NULL);
+		PCUT_ASSERT_NOT_NULL(c);
+
+		e = odict_get_instance(c, test_entry_t, odict);
+		PCUT_ASSERT_INT_EQUALS(v, e->key);
+
+		d = odict_find_eq_last(&odict, (void *)&v, NULL);
+		PCUT_ASSERT_NOT_NULL(d);
+
+		e = odict_get_instance(d, test_entry_t, odict);
+		PCUT_ASSERT_INT_EQUALS(v, e->key);
+
+		odict_remove(c);
+		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
+
+		v = seq_next(v);
+	}
+}
+
+PCUT_EXPORT(odict);
Index: uspace/lib/c/test/cap.c
===================================================================
--- uspace/lib/c/test/cap.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/test/cap.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2019 Matthieu Riolo
+ * 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 <pcut/pcut.h>
+#include <cap.h>
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(cap);
+
+PCUT_TEST(cap_format)
+{
+	int block_size = 4;
+	size_t block[] = {
+		0,
+		1,
+		2,
+		10,
+	};
+
+	int input_size = 5;
+	size_t input[] = {
+		0,
+		10,
+		100,
+		1000,
+		1000000,
+		1000000000,
+	};
+
+	const char *out[] = {
+		"0 B",
+		"0 B",
+		"0 B",
+		"0 B",
+
+		"0 B",
+		"10 B",
+		"20 B",
+		"100 B",
+
+		"0 B",
+		"100 B",
+		"200 B",
+		"1.000 kB",
+
+		"0 B",
+		"1.000 kB",
+		"2.000 kB",
+		"10.00 kB",
+
+		"0 B",
+		"1.000 MB",
+		"2.000 MB",
+		"10.00 MB",
+
+		"0 B",
+		"1.000 GB",
+		"2.000 GB",
+		"10.00 GB",
+	};
+
+	cap_spec_t cap;
+	char *str;
+	errno_t rc;
+
+	int x, i;
+	for (i = 0; i < input_size; i++) {
+		for (x = 0; x < block_size; x++) {
+			cap_from_blocks(input[i], block[x], &cap);
+			cap_simplify(&cap);
+
+			rc = cap_format(&cap, &str);
+
+			PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+			PCUT_ASSERT_STR_EQUALS(out[x + (block_size * i)], str);
+			free(str);
+
+			cap_from_blocks(block[x], input[i], &cap);
+			cap_simplify(&cap);
+
+			rc = cap_format(&cap, &str);
+
+			PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+			PCUT_ASSERT_STR_EQUALS(out[x + (block_size * i)], str);
+			free(str);
+		}
+	}
+}
+
+PCUT_TEST(cap_format_rounding)
+{
+	int input_size = 8;
+	uint64_t input[] = {
+		555,
+		5555,
+		55555,
+		555555555,
+		5555555555,
+		555999999,
+		5999999,
+		999999
+	};
+
+	const char *out[] = {
+		"555 B",
+		"5.555 kB",
+		"55.56 kB",
+		"555.6 MB",
+		"5.556 GB",
+		"556.0 MB",
+		"6.000 MB",
+		"1.000 MB",
+	};
+
+	cap_spec_t cap;
+	char *str;
+	errno_t rc;
+
+	int i;
+	for (i = 0; i < input_size; i++) {
+		cap_from_blocks(input[i], 1, &cap);
+		cap_simplify(&cap);
+
+		rc = cap_format(&cap, &str);
+
+		PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+		PCUT_ASSERT_STR_EQUALS(out[i], str);
+		free(str);
+
+		cap_from_blocks(1, input[i], &cap);
+		cap_simplify(&cap);
+
+		rc = cap_format(&cap, &str);
+
+		PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+		PCUT_ASSERT_STR_EQUALS(out[i], str);
+		free(str);
+	}
+}
+
+PCUT_TEST(cap_parse)
+{
+	int input_size = 4;
+	const char *input[] = {
+		"0 B",
+		"100 B",
+		"1 kB",
+		"1.555 kB",
+	};
+
+	int out_cunit[] = {
+		cu_byte,
+		cu_byte,
+		cu_kbyte,
+		cu_kbyte,
+	};
+
+	int out_dp[] = {
+		0,
+		0,
+		0,
+		3,
+	};
+
+	int out_m[] = {
+		0,
+		100,
+		1,
+		1555,
+	};
+
+	cap_spec_t cap;
+	errno_t rc;
+	int i;
+
+	for (i = 0; i < input_size; i++) {
+		rc = cap_parse(input[i], &cap);
+
+		PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+		PCUT_ASSERT_INT_EQUALS(out_cunit[i], cap.cunit);
+		PCUT_ASSERT_INT_EQUALS(out_dp[i], cap.dp);
+		PCUT_ASSERT_INT_EQUALS(out_m[i], cap.m);
+	}
+}
+
+PCUT_TEST(cap_to_blocks)
+{
+	int input_size = 0;
+	int input_m[] = {
+		0,
+		1,
+		1000,
+		5555,
+		7777,
+	};
+
+	int input_dp[] = {
+		0,
+		0,
+		3,
+		3,
+		2,
+	};
+
+	int block[] = {
+		1,
+		1,
+		1,
+		2,
+		3,
+	};
+
+	int out_nom[] = {
+		0,
+		1000,
+		1000,
+		2778,
+		25923,
+	};
+
+	int out_min[] = {
+		0,
+		1000,
+		1000,
+		2777,
+		25923,
+	};
+
+	int out_max[] = {
+		0,
+		1000,
+		1000,
+		2778,
+		25924,
+	};
+
+	cap_spec_t cap;
+	errno_t rc;
+	int i;
+	uint64_t ret;
+
+	for (i = 0; i < input_size; i++) {
+		cap.m = input_m[i];
+		cap.dp = input_dp[i];
+		cap.cunit = cu_kbyte;
+
+		rc = cap_to_blocks(&cap, cv_nom, block[i], &ret);
+		PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+		PCUT_ASSERT_INT_EQUALS(out_nom[i], ret);
+
+		rc = cap_to_blocks(&cap, cv_min, block[i], &ret);
+		PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+		PCUT_ASSERT_INT_EQUALS(out_min[i], ret);
+
+		rc = cap_to_blocks(&cap, cv_max, block[i], &ret);
+		PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+		PCUT_ASSERT_INT_EQUALS(out_max[i], ret);
+	}
+}
+
+PCUT_EXPORT(cap);
Index: uspace/lib/c/test/casting.c
===================================================================
--- uspace/lib/c/test/casting.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/test/casting.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2019 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 <pcut/pcut.h>
+#include <limits.h>
+#include <types/casting.h>
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(casting);
+
+/*
+ * Following tests checks functionality of can_cast_size_t_to_int.
+ */
+
+PCUT_TEST(size_t_to_int_with_small)
+{
+	PCUT_ASSERT_TRUE(can_cast_size_t_to_int(0));
+	PCUT_ASSERT_TRUE(can_cast_size_t_to_int(128));
+}
+
+PCUT_TEST(size_t_to_int_with_biggest_int)
+{
+	PCUT_ASSERT_TRUE(can_cast_size_t_to_int(INT_MAX));
+}
+
+PCUT_TEST(size_t_to_int_with_biggest_size_t)
+{
+	PCUT_ASSERT_FALSE(can_cast_size_t_to_int(SIZE_MAX));
+}
+
+PCUT_EXPORT(casting);
Index: uspace/lib/c/test/double_to_str.c
===================================================================
--- uspace/lib/c/test/double_to_str.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/test/double_to_str.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2019 Matthieu Riolo
+ * 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 <pcut/pcut.h>
+#include <ieee_double.h>
+#include <double_to_str.h>
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(double_to_str);
+
+PCUT_TEST(double_to_short_str_pos_zero)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(0.0);
+	int ret = double_to_short_str(d, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(0, dec);
+	PCUT_ASSERT_STR_EQUALS("0", buf);
+}
+
+PCUT_TEST(double_to_short_str_neg_zero)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(-0.0);
+	int ret = double_to_short_str(d, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(0, dec);
+	PCUT_ASSERT_STR_EQUALS("0", buf);
+}
+
+PCUT_TEST(double_to_short_str_pos_one)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1.0);
+	int ret = double_to_short_str(d, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(0, dec);
+	PCUT_ASSERT_STR_EQUALS("1", buf);
+}
+
+PCUT_TEST(double_to_short_str_neg_one)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(-1.0);
+	int ret = double_to_short_str(d, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(0, dec);
+	PCUT_ASSERT_STR_EQUALS("1", buf);
+}
+
+PCUT_TEST(double_to_short_str_small)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1.1);
+	int ret = double_to_short_str(d, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(2, ret);
+	PCUT_ASSERT_INT_EQUALS(-1, dec);
+	PCUT_ASSERT_STR_EQUALS("11", buf);
+}
+
+PCUT_TEST(double_to_short_str_large)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1234.56789);
+	int ret = double_to_short_str(d, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(9, ret);
+	PCUT_ASSERT_INT_EQUALS(-5, dec);
+	PCUT_ASSERT_STR_EQUALS("123456789", buf);
+}
+
+PCUT_TEST(double_to_short_str_mill)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1000000.0);
+	int ret = double_to_short_str(d, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(6, dec);
+	PCUT_ASSERT_STR_EQUALS("1", buf);
+}
+
+PCUT_TEST(double_to_fixed_str_zero)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(0.0);
+	int ret = double_to_fixed_str(d, -1, 3, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(0, dec);
+	PCUT_ASSERT_STR_EQUALS("0", buf);
+}
+
+PCUT_TEST(double_to_fixed_str_pos_one)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1.0);
+	int ret = double_to_fixed_str(d, -1, 3, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(4, ret);
+	PCUT_ASSERT_INT_EQUALS(-3, dec);
+	PCUT_ASSERT_STR_EQUALS("1000", buf);
+}
+
+PCUT_TEST(double_to_fixed_str_neg_one)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(-1.0);
+	int ret = double_to_fixed_str(d, -1, 3, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(4, ret);
+	PCUT_ASSERT_INT_EQUALS(-3, dec);
+	PCUT_ASSERT_STR_EQUALS("1000", buf);
+}
+
+PCUT_TEST(double_to_fixed_str_small)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1.1);
+	int ret = double_to_fixed_str(d, -1, 3, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(4, ret);
+	PCUT_ASSERT_INT_EQUALS(-3, dec);
+	PCUT_ASSERT_STR_EQUALS("1100", buf);
+}
+
+PCUT_TEST(double_to_fixed_str_large)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1234.56789);
+	int ret = double_to_fixed_str(d, -1, 3, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(7, ret);
+	PCUT_ASSERT_INT_EQUALS(-3, dec);
+	PCUT_ASSERT_STR_EQUALS("1234567", buf);
+}
+
+PCUT_TEST(double_to_fixed_str_nodecimals)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1.999);
+	int ret = double_to_fixed_str(d, -1, 0, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(0, dec);
+	PCUT_ASSERT_STR_EQUALS("1", buf);
+}
+
+PCUT_EXPORT(double_to_str);
Index: uspace/lib/c/test/getopt.c
===================================================================
--- uspace/lib/c/test/getopt.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/test/getopt.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,569 @@
+/*
+ * Copyright (c) 2019 Matthieu Riolo
+ * 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 <pcut/pcut.h>
+#include <getopt.h>
+#include <stdio.h>
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(getopt);
+
+PCUT_TEST(getopt_param_flag)
+{
+	int argc = 4;
+	const char *argv[] = {
+		"get_opt_test",
+		"-f",
+		"-p",
+		"param",
+	};
+
+	const char *options = "fp:";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('p', ret);
+	PCUT_ASSERT_INT_EQUALS(4, optind);
+	PCUT_ASSERT_STR_EQUALS("param", optarg);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_concat_flags)
+{
+	int argc = 2;
+	const char *argv[] = {
+		"get_opt_test",
+		"-fda",
+	};
+
+	const char *options = "afd";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(1, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('d', ret);
+	PCUT_ASSERT_INT_EQUALS(1, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('a', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_concat_flag_param)
+{
+	int argc = 3;
+	const char *argv[] = {
+		"get_opt_test",
+		"-fp",
+		"param"
+	};
+
+	const char *options = "fp:";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(1, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('p', ret);
+	PCUT_ASSERT_INT_EQUALS(3, optind);
+	PCUT_ASSERT_STR_EQUALS("param", optarg);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_missing_param1)
+{
+	int argc = 2;
+	const char *argv[] = {
+		"get_opt_test",
+		"-p",
+	};
+
+	const char *options = "p:";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('?', ret);
+	PCUT_ASSERT_INT_EQUALS('p', optopt);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_missing_param2)
+{
+	int argc = 2;
+	const char *argv[] = {
+		"get_opt_test",
+		"-p",
+	};
+
+	const char *options = ":p:";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS(':', ret);
+	PCUT_ASSERT_INT_EQUALS('p', optopt);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_illegal_option)
+{
+	int argc = 2;
+	const char *argv[] = {
+		"get_opt_test",
+		"-p",
+	};
+
+	const char *options = "a";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('?', ret);
+	PCUT_ASSERT_INT_EQUALS('p', optopt);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+
+	options = ":a";
+	optreset = 1;
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+	PCUT_ASSERT_INT_EQUALS('p', optopt);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_flag_with_param)
+{
+	int argc = 4;
+	const char *argv[] = {
+		"get_opt_test",
+		"-f",
+		"param",
+		"-d"
+	};
+
+	const char *options = "fd";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	/* getopt() would print a error message but thx to opterror=0 it doesnt */
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('d', ret);
+	PCUT_ASSERT_INT_EQUALS(4, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_case_sensitive)
+{
+	int argc = 3;
+	const char *argv[] = {
+		"get_opt_test",
+		"-F",
+		"-f"
+	};
+
+	const char *options = "fF";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('F', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(3, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_optional_param)
+{
+	int argc = 4;
+	const char *argv[] = {
+		"get_opt_test",
+		"-f",
+		"-p",
+		"param"
+	};
+
+	const char *options = "f::p::";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+	PCUT_ASSERT_NULL(optarg);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('p', ret);
+	PCUT_ASSERT_INT_EQUALS(3, optind);
+	PCUT_ASSERT_STR_EQUALS("param", optarg);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_special_option)
+{
+	int argc = 4;
+	const char *argv[] = {
+		"get_opt_test",
+		"-f",
+		"--",
+		"-p"
+	};
+
+	const char *options = "fp";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_gnu_plus)
+{
+	int argc = 4;
+	const char *argv[] = {
+		"get_opt_test",
+		"-f",
+		"break",
+		"-p"
+	};
+
+	const char *options = "+fp";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_gnu_minus)
+{
+	int argc = 4;
+	const char *argv[] = {
+		"get_opt_test",
+		"-f",
+		"break",
+		"-p"
+	};
+
+	const char *options = "-fp";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(3, optind);
+	PCUT_ASSERT_STR_EQUALS("break", optarg);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('p', ret);
+	PCUT_ASSERT_INT_EQUALS(4, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_long_flag_param)
+{
+	int argc = 4;
+	const char *argv[] = {
+		"get_opt_test",
+		"--flag",
+		"--parameter",
+		"param"
+	};
+
+	const char *options = "fp:";
+
+	const struct option long_options[] = {
+		{ "flag", no_argument, NULL, 'f' },
+		{ "parameter", required_argument, NULL, 'p' },
+	};
+
+	int ret;
+	int idx;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+	PCUT_ASSERT_INT_EQUALS(0, idx);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('p', ret);
+	PCUT_ASSERT_INT_EQUALS(4, optind);
+	PCUT_ASSERT_INT_EQUALS(1, idx);
+	PCUT_ASSERT_STR_EQUALS("param", optarg);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_long_alt_param)
+{
+	int argc = 3;
+	const char *argv[] = {
+		"get_opt_test",
+		"--flag=\"param param\"",
+		"--parameter=param",
+	};
+
+	const char *options = "f:p:";
+
+	const struct option long_options[] = {
+		{ "flag", required_argument, NULL, 'f' },
+		{ "parameter", required_argument, NULL, 'p' },
+		{ 0, 0, 0, 0 }
+	};
+
+	int ret;
+	int idx;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+	PCUT_ASSERT_INT_EQUALS(0, idx);
+	PCUT_ASSERT_STR_EQUALS("\"param param\"", optarg);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('p', ret);
+	PCUT_ASSERT_INT_EQUALS(3, optind);
+	PCUT_ASSERT_INT_EQUALS(1, idx);
+	PCUT_ASSERT_STR_EQUALS("param", optarg);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_long_optional_param)
+{
+	int argc = 3;
+	const char *argv[] = {
+		"get_opt_test",
+		"--flag=param",
+		"--parameter",
+	};
+
+	const char *options = "f::p::";
+
+	const struct option long_options[] = {
+		{ "flag", optional_argument, NULL, 'f' },
+		{ "parameter", optional_argument, NULL, 'p' },
+		{ 0, 0, 0, 0 }
+	};
+
+	int ret;
+	int idx;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+	PCUT_ASSERT_INT_EQUALS(0, idx);
+	PCUT_ASSERT_STR_EQUALS("param", optarg);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('p', ret);
+	PCUT_ASSERT_INT_EQUALS(3, optind);
+	PCUT_ASSERT_INT_EQUALS(1, idx);
+	PCUT_ASSERT_NULL(optarg);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_long_illegal_option)
+{
+	int argc = 3;
+	const char *argv[] = {
+		"get_opt_test",
+		"--param",
+		"param",
+	};
+
+	const char *options = "f::";
+
+	const struct option long_options[] = {
+		{ "cflag", required_argument, NULL, 'c' },
+		{ "flag", required_argument, NULL, 'f' },
+		{ 0, 0, 0, 0 }
+	};
+
+	int ret;
+	int idx;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('?', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+	PCUT_ASSERT_INT_EQUALS(0, idx);
+	PCUT_ASSERT_INT_EQUALS(0, optopt);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_long_ambiguous_param)
+{
+	int argc = 3;
+	const char *argv[] = {
+		"get_opt_test",
+		"--flag",
+		"param",
+	};
+
+	const char *options = "f::";
+
+	const struct option long_options[] = {
+		{ "flag1", optional_argument, NULL, 'f' },
+		{ "flag2", required_argument, NULL, 'f' },
+		{ 0, 0, 0, 0 }
+	};
+
+	int ret;
+	int idx;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('?', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+	PCUT_ASSERT_INT_EQUALS(0, idx);
+	PCUT_ASSERT_INT_EQUALS(0, optopt);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_EXPORT(getopt);
Index: uspace/lib/c/test/gsort.c
===================================================================
--- uspace/lib/c/test/gsort.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/test/gsort.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2019 Matthieu Riolo
+ * 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 <pcut/pcut.h>
+#include <gsort.h>
+
+static int cmp_func(void *a, void *b, void *param)
+{
+	int ia = *(int *)a;
+	int ib = *(int *)b;
+
+	if (ia == ib)
+		return 0;
+
+	return ia < ib ? -1 : 1;
+}
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(gsort);
+
+/* sort ascending */
+PCUT_TEST(gsort_asc)
+{
+	int size = 10;
+	int data[size];
+
+	for (int i = 0; i < size; i++) {
+		data[i] = i;
+	}
+
+	bool ret = gsort(data, size, sizeof(int), cmp_func, NULL);
+	PCUT_ASSERT_TRUE(ret);
+
+	for (int i = 0; i < size; i++) {
+		PCUT_ASSERT_INT_EQUALS(i, data[i]);
+	}
+}
+
+/* sort ascending including double entries of the same number */
+PCUT_TEST(gsort_asc_complex)
+{
+	int size = 10;
+	int data[size];
+
+	for (int i = 0; i < size; i++) {
+		data[i] = (i * 13) % 9;
+	}
+
+	data[0] = 2;
+	data[1] = 0;
+	data[2] = 4;
+	data[3] = 1;
+
+	bool ret = gsort(data, size, sizeof(int), cmp_func, NULL);
+	PCUT_ASSERT_TRUE(ret);
+
+	int prev = data[0];
+	for (int i = 1; i < size; i++) {
+		PCUT_ASSERT_TRUE(prev <= data[i]);
+		prev = data[i];
+	}
+}
+
+/* sort descanding */
+PCUT_TEST(gsort_desc)
+{
+	int size = 10;
+	int data[size];
+
+	for (int i = 0; i < size; i++) {
+		data[i] = size - i;
+	}
+
+	bool ret = gsort(&data, size, sizeof(int), cmp_func, NULL);
+	PCUT_ASSERT_TRUE(ret);
+
+	for (int i = 0; i < size; i++) {
+		PCUT_ASSERT_INT_EQUALS(i + 1, data[i]);
+	}
+}
+
+PCUT_EXPORT(gsort);
Index: uspace/lib/c/test/ieee_double.c
===================================================================
--- uspace/lib/c/test/ieee_double.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/test/ieee_double.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2019 Matthieu Riolo
+ * 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 <pcut/pcut.h>
+#include <ieee_double.h>
+
+union {
+	uint64_t integer;
+	double floating;
+} ieee_double_bits;
+
+const int EXP_BIAS = 1023;
+const int EXP_BIAS_UNDERFLOWED = 1075;
+const int SIGN_SHIFT = 52;
+const uint64_t HIDDEN_BIT = 1ULL << SIGN_SHIFT;
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(ieee_double);
+
+PCUT_TEST(extract_ieee_sizeof_double)
+{
+	PCUT_ASSERT_INT_EQUALS(8, sizeof(double));
+}
+
+PCUT_TEST(extract_ieee_double_pos_infinity)
+{
+	ieee_double_bits.integer = 0x7FF0000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_TRUE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_TRUE(d.is_infinity);
+	PCUT_ASSERT_FALSE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_neg_infinity)
+{
+	ieee_double_bits.integer = 0xFFF0000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_TRUE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_TRUE(d.is_infinity);
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_nan)
+{
+	ieee_double_bits.integer = 0xFFFFFFFFFFFFFFFFULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_TRUE(d.is_special);
+	PCUT_ASSERT_TRUE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_pos_zero)
+{
+	ieee_double_bits.integer = 0x0000000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_FALSE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.significand);
+}
+
+PCUT_TEST(extract_ieee_double_neg_zero)
+{
+	ieee_double_bits.integer = 0x8000000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.significand);
+}
+
+PCUT_TEST(extract_ieee_double_normal_pos_one)
+{
+	ieee_double_bits.integer = 0x3FF0000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_FALSE(d.is_negative);
+	PCUT_ASSERT_FALSE(d.is_denormal);
+	PCUT_ASSERT_TRUE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(HIDDEN_BIT, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(EXP_BIAS - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_normal_neg_one)
+{
+	ieee_double_bits.integer = 0xBFF0000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_FALSE(d.is_denormal);
+	PCUT_ASSERT_TRUE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(HIDDEN_BIT, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(EXP_BIAS - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_denormal_pos_smallest)
+{
+	ieee_double_bits.integer = 0x0000000000000001ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_FALSE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(1, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(1 - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_denormal_neg_smallest)
+{
+	ieee_double_bits.integer = 0x8000000000000001ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(1, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(1 - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_denormal_pos_largest)
+{
+	ieee_double_bits.integer = 0x000FFFFFFFFFFFFFULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_FALSE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0xFFFFFFFFFFFFFULL, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(1 - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_denormal_neg_largest)
+{
+	ieee_double_bits.integer = 0x800FFFFFFFFFFFFFULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+	PCUT_ASSERT_INT_EQUALS(0xFFFFFFFFFFFFFULL, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(1 - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_normal_pos_smallest)
+{
+	ieee_double_bits.integer = 0x0010000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_FALSE(d.is_negative);
+	PCUT_ASSERT_FALSE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(HIDDEN_BIT, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(1 - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_normal_neg_smallest)
+{
+	ieee_double_bits.integer = 0x8010000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_FALSE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(HIDDEN_BIT, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(1 - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_normal_pos_largest)
+{
+	ieee_double_bits.integer = 0x7FEFFFFFFFFFFFFFULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_FALSE(d.is_negative);
+	PCUT_ASSERT_FALSE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0xFFFFFFFFFFFFFULL + HIDDEN_BIT, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(0x7FEULL - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_normal_neg_largest)
+{
+	ieee_double_bits.integer = 0xFFEFFFFFFFFFFFFFULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_FALSE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0xFFFFFFFFFFFFFULL + HIDDEN_BIT, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(0x7FEULL - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_EXPORT(ieee_double);
Index: uspace/lib/c/test/imath.c
===================================================================
--- uspace/lib/c/test/imath.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/test/imath.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2019 Matthieu Riolo
+ * 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 <pcut/pcut.h>
+#include <imath.h>
+
+static uint64_t MAX_NUM = 10000000000000000000U;
+static unsigned MAX_EXP = 19;
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(imath);
+
+PCUT_TEST(ipow10_u64_zero)
+{
+	errno_t ret;
+	uint64_t result;
+	ret = ipow10_u64(0, &result);
+
+	PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+	PCUT_ASSERT_INT_EQUALS(1, result);
+}
+
+PCUT_TEST(ipow10_u64_one)
+{
+	errno_t ret;
+	uint64_t result;
+	ret = ipow10_u64(1, &result);
+
+	PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+	PCUT_ASSERT_INT_EQUALS(10, result);
+}
+
+PCUT_TEST(ipow10_u64_max)
+{
+	errno_t ret;
+	uint64_t result;
+	ret = ipow10_u64(MAX_EXP, &result);
+
+	PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+	PCUT_ASSERT_INT_EQUALS(MAX_NUM, result);
+}
+
+PCUT_TEST(ipow10_u64_too_large)
+{
+	errno_t ret;
+	uint64_t result;
+	ret = ipow10_u64(MAX_EXP + 1, &result);
+
+	PCUT_ASSERT_ERRNO_VAL(ERANGE, ret);
+}
+
+PCUT_TEST(ilog10_u64_zero)
+{
+	unsigned ret = ilog10_u64(0);
+	PCUT_ASSERT_INT_EQUALS(0, ret);
+}
+
+PCUT_TEST(ilog10_u64_one)
+{
+	unsigned ret = ilog10_u64(1);
+	PCUT_ASSERT_INT_EQUALS(0, ret);
+}
+
+PCUT_TEST(ilog10_u64_max)
+{
+	unsigned ret = ilog10_u64(MAX_NUM);
+	PCUT_ASSERT_INT_EQUALS(MAX_EXP, ret);
+}
+
+PCUT_EXPORT(imath);
Index: uspace/lib/c/test/main.c
===================================================================
--- uspace/lib/c/test/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/test/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -32,9 +32,17 @@
 PCUT_INIT;
 
+PCUT_IMPORT(cap);
+PCUT_IMPORT(casting);
 PCUT_IMPORT(circ_buf);
+PCUT_IMPORT(double_to_str);
 PCUT_IMPORT(fibril_timer);
+PCUT_IMPORT(getopt);
+PCUT_IMPORT(gsort);
+PCUT_IMPORT(ieee_double);
+PCUT_IMPORT(imath);
 PCUT_IMPORT(inttypes);
 PCUT_IMPORT(mem);
 PCUT_IMPORT(odict);
+PCUT_IMPORT(perf);
 PCUT_IMPORT(perm);
 PCUT_IMPORT(qsort);
@@ -45,5 +53,7 @@
 PCUT_IMPORT(str);
 PCUT_IMPORT(string);
+PCUT_IMPORT(strtol);
 PCUT_IMPORT(table);
+PCUT_IMPORT(uuid);
 
 PCUT_MAIN();
Index: pace/lib/c/test/odict.c
===================================================================
--- uspace/lib/c/test/odict.c	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,278 +1,0 @@
-/*
- * Copyright (c) 2016 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.
- */
-
-#include <adt/odict.h>
-#include <pcut/pcut.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/** Test entry */
-typedef struct {
-	odlink_t odict;
-	int key;
-} test_entry_t;
-
-enum {
-	/** Length of test number sequences */
-	test_seq_len = 100
-};
-
-/** Test get key function.
- *
- * @param odlink Ordered dictionary link
- * @return Pointer to key
- */
-static void *test_getkey(odlink_t *odlink)
-{
-	return &odict_get_instance(odlink, test_entry_t, odict)->key;
-}
-
-/** Test compare function.
- *
- * @param a First key
- * @param b Second key
- * @return <0, 0, >0 if @a a is less than, equal or greater than @a b
- */
-static int test_cmp(void *a, void *b)
-{
-	int *ia = (int *)a;
-	int *ib = (int *)b;
-
-	return *ia - *ib;
-}
-
-PCUT_INIT;
-
-PCUT_TEST_SUITE(odict);
-
-/** Increasing sequence test.
- *
- * Test initialization, emptiness, insertion of increasing sequence and walking.
- */
-PCUT_TEST(incr_seq)
-{
-	odict_t odict;
-	test_entry_t *e;
-	odlink_t *c;
-	int i;
-
-	odict_initialize(&odict, test_getkey, test_cmp);
-
-	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
-
-	for (i = 0; i < test_seq_len; i++) {
-		e = calloc(1, sizeof(test_entry_t));
-		PCUT_ASSERT_NOT_NULL(e);
-
-		e->key = i;
-		odict_insert(&e->odict, &odict, NULL);
-		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
-	}
-
-	i = 0;
-	c = odict_first(&odict);
-	while (c != NULL) {
-		e = odict_get_instance(c, test_entry_t, odict);
-		PCUT_ASSERT_INT_EQUALS(i, e->key);
-		c = odict_next(c, &odict);
-		++i;
-	}
-	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
-
-	i = test_seq_len;
-	c = odict_last(&odict);
-	while (c != NULL) {
-		--i;
-		e = odict_get_instance(c, test_entry_t, odict);
-		PCUT_ASSERT_INT_EQUALS(i, e->key);
-		c = odict_prev(c, &odict);
-	}
-
-	PCUT_ASSERT_INT_EQUALS(0, i);
-}
-
-/** Decreasing sequence test.
- *
- * Test initialization, emptiness, insertion of decreasing sequence and walking.
- */
-PCUT_TEST(decr_seq)
-{
-	odict_t odict;
-	test_entry_t *e;
-	odlink_t *c;
-	int i;
-
-	odict_initialize(&odict, test_getkey, test_cmp);
-
-	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
-
-	for (i = 0; i < test_seq_len; i++) {
-		e = calloc(1, sizeof(test_entry_t));
-		PCUT_ASSERT_NOT_NULL(e);
-
-		e->key = test_seq_len - i - 1;
-		odict_insert(&e->odict, &odict, NULL);
-		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
-	}
-
-	i = 0;
-	c = odict_first(&odict);
-	while (c != NULL) {
-		e = odict_get_instance(c, test_entry_t, odict);
-		PCUT_ASSERT_INT_EQUALS(i, e->key);
-		c = odict_next(c, &odict);
-		++i;
-	}
-	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
-
-	i = test_seq_len;
-	c = odict_last(&odict);
-	while (c != NULL) {
-		--i;
-		e = odict_get_instance(c, test_entry_t, odict);
-		PCUT_ASSERT_INT_EQUALS(i, e->key);
-		c = odict_prev(c, &odict);
-	}
-
-	PCUT_ASSERT_INT_EQUALS(0, i);
-}
-
-/** Increasing sequence insertion and removal test.
- *
- * Test sequential insertion of increasing sequence and sequential removal.
- */
-PCUT_TEST(incr_seq_ins_rem)
-{
-	odict_t odict;
-	test_entry_t *e;
-	odlink_t *c;
-	int i;
-
-	odict_initialize(&odict, test_getkey, test_cmp);
-
-	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
-
-	for (i = 0; i < test_seq_len; i++) {
-		e = calloc(1, sizeof(test_entry_t));
-		PCUT_ASSERT_NOT_NULL(e);
-
-		e->key = i;
-		odict_insert(&e->odict, &odict, NULL);
-		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
-	}
-
-	i = 0;
-	c = odict_first(&odict);
-	while (c != NULL) {
-		e = odict_get_instance(c, test_entry_t, odict);
-		PCUT_ASSERT_INT_EQUALS(i, e->key);
-
-		odict_remove(c);
-		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
-
-		c = odict_first(&odict);
-		++i;
-	}
-
-	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
-}
-
-/** Generate pseudorandom sequence. */
-static int seq_next(int cur)
-{
-	return (cur * 1951) % 1000000;
-}
-
-/** Test 4.
- *
- * Test inserting a pseudorandom sequence and then extracting it again.
- */
-PCUT_TEST(prseq_ins_extract)
-{
-	odict_t odict;
-	test_entry_t *e, *ep;
-	odlink_t *c, *d;
-	int prev;
-	int i;
-	int v;
-
-	odict_initialize(&odict, test_getkey, test_cmp);
-
-	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
-
-	v = 1;
-	ep = NULL;
-	for (i = 0; i < test_seq_len; i++) {
-		e = calloc(1, sizeof(test_entry_t));
-		PCUT_ASSERT_NOT_NULL(e);
-
-		e->key = v;
-		odict_insert(&e->odict, &odict, &ep->odict);
-		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
-		v = seq_next(v);
-		ep = e;
-	}
-
-	/* Verify that entries are in ascending order */
-	c = odict_first(&odict);
-	prev = -1;
-	i = 0;
-	while (c != NULL) {
-		e = odict_get_instance(c, test_entry_t, odict);
-		PCUT_ASSERT_EQUALS(true, e->key > prev);
-
-		prev = e->key;
-		c = odict_next(c, &odict);
-		++i;
-	}
-
-	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
-
-	/* Try extracting the sequence */
-	v = 1;
-	for (i = 0; i < test_seq_len; i++) {
-		c = odict_find_eq(&odict, (void *)&v, NULL);
-		PCUT_ASSERT_NOT_NULL(c);
-
-		e = odict_get_instance(c, test_entry_t, odict);
-		PCUT_ASSERT_INT_EQUALS(v, e->key);
-
-		d = odict_find_eq_last(&odict, (void *)&v, NULL);
-		PCUT_ASSERT_NOT_NULL(d);
-
-		e = odict_get_instance(d, test_entry_t, odict);
-		PCUT_ASSERT_INT_EQUALS(v, e->key);
-
-		odict_remove(c);
-		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
-
-		v = seq_next(v);
-	}
-}
-
-PCUT_EXPORT(odict);
Index: uspace/lib/c/test/perf.c
===================================================================
--- uspace/lib/c/test/perf.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/test/perf.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018 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 <pcut/pcut.h>
+#include <fibril.h>
+#include <perf.h>
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(perf);
+
+/* Checks that initialization zeroes out all entries. */
+PCUT_TEST(zero_diff)
+{
+	stopwatch_t sw;
+	stopwatch_init(&sw);
+	PCUT_ASSERT_INT_EQUALS(0, (int) stopwatch_get_nanos(&sw));
+}
+
+/* Checks that initialization zeroes out all entries. */
+PCUT_TEST(zero_diff_static)
+{
+	stopwatch_t sw = STOPWATCH_INITIALIZE_STATIC;
+	PCUT_ASSERT_INT_EQUALS(0, (int) stopwatch_get_nanos(&sw));
+}
+
+/* Checks that measuring 1s sleep does not give completely invalid results. */
+PCUT_TEST(stopwatch_smokes)
+{
+	stopwatch_t sw = STOPWATCH_INITIALIZE_STATIC;
+	stopwatch_start(&sw);
+	fibril_sleep(1);
+	stopwatch_stop(&sw);
+	nsec_t diff_nanos = stopwatch_get_nanos(&sw);
+	PCUT_ASSERT_TRUE(diff_nanos > MSEC2NSEC(500));
+	PCUT_ASSERT_TRUE(diff_nanos < SEC2NSEC(5));
+}
+
+/* Checks that setting time works for small values. */
+PCUT_TEST(stopwatch_emulation_works_small)
+{
+	stopwatch_t sw = STOPWATCH_INITIALIZE_STATIC;
+	stopwatch_set_nanos(&sw, 42);
+	PCUT_ASSERT_INT_EQUALS(42, (int) stopwatch_get_nanos(&sw));
+}
+
+/* Checks that setting time works for big values too. */
+PCUT_TEST(stopwatch_emulation_works_big)
+{
+	stopwatch_t sw = STOPWATCH_INITIALIZE_STATIC;
+	stopwatch_set_nanos(&sw, 4200000000021);
+	PCUT_ASSERT_EQUALS(4200000000021, (long long) stopwatch_get_nanos(&sw));
+}
+
+PCUT_EXPORT(perf);
Index: uspace/lib/c/test/stdlib.c
===================================================================
--- uspace/lib/c/test/stdlib.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/test/stdlib.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -63,31 +63,4 @@
 }
 
-/** atoi function */
-PCUT_TEST(atoi)
-{
-	int i;
-
-	i = atoi(" \t42");
-	PCUT_ASSERT_TRUE(i == 42);
-}
-
-/** atol function */
-PCUT_TEST(atol)
-{
-	long li;
-
-	li = atol(" \t42");
-	PCUT_ASSERT_TRUE(li == 42);
-}
-
-/** atoll function */
-PCUT_TEST(atoll)
-{
-	long long lli;
-
-	lli = atoll(" \t42");
-	PCUT_ASSERT_TRUE(lli == 42);
-}
-
 /** strtold function */
 #include <stdio.h>
@@ -101,95 +74,4 @@
 	printf("ld=%.10lf\n", (double)ld);
 	PCUT_ASSERT_TRUE(ld == 42.0);
-}
-
-/** strtol function */
-PCUT_TEST(strtol)
-{
-	long li;
-	char *ep;
-
-	li = strtol(" \t42x", &ep, 10);
-	PCUT_ASSERT_TRUE(li == 42);
-	PCUT_ASSERT_TRUE(*ep == 'x');
-}
-
-/** strtol function with auto-detected base 10 */
-PCUT_TEST(strtol_dec_auto)
-{
-	long li;
-	char *ep;
-
-	li = strtol(" \t42x", &ep, 0);
-	PCUT_ASSERT_TRUE(li == 42);
-	PCUT_ASSERT_TRUE(*ep == 'x');
-}
-
-/** strtol function with octal number */
-PCUT_TEST(strtol_oct)
-{
-	long li;
-	char *ep;
-
-	li = strtol(" \t052x", &ep, 8);
-	PCUT_ASSERT_TRUE(li == 052);
-	PCUT_ASSERT_TRUE(*ep == 'x');
-}
-
-/** strtol function with octal number with prefix */
-#include <stdio.h>
-PCUT_TEST(strtol_oct_prefix)
-{
-	long li;
-	char *ep;
-
-	li = strtol(" \t052x", &ep, 0);
-	printf("li=%ld (0%lo)\n", li, li);
-	PCUT_ASSERT_TRUE(li == 052);
-	PCUT_ASSERT_TRUE(*ep == 'x');
-}
-
-/** strtol function with hex number */
-PCUT_TEST(strtol_hex)
-{
-	long li;
-	char *ep;
-
-	li = strtol(" \t2ax", &ep, 16);
-	PCUT_ASSERT_TRUE(li == 0x2a);
-	PCUT_ASSERT_TRUE(*ep == 'x');
-}
-
-/** strtol function with hex number with hex prefix */
-PCUT_TEST(strtol_hex_prefixed)
-{
-	long li;
-	char *ep;
-
-	li = strtol(" \t0x2ax", &ep, 0);
-	PCUT_ASSERT_TRUE(li == 0x2a);
-	PCUT_ASSERT_TRUE(*ep == 'x');
-}
-
-/** strtol function with base 16 and number with 0x prefix */
-PCUT_TEST(strtol_base16_prefix)
-{
-	long li;
-	char *ep;
-
-	li = strtol(" \t0x1y", &ep, 16);
-	printf("li=%ld\n", li);
-	PCUT_ASSERT_TRUE(li == 1);
-	PCUT_ASSERT_TRUE(*ep == 'y');
-}
-
-/** strtol function with base 36 number */
-PCUT_TEST(strtol_base36)
-{
-	long li;
-	char *ep;
-
-	li = strtol(" \tz1.", &ep, 36);
-	PCUT_ASSERT_TRUE(li == 35 * 36 + 1);
-	PCUT_ASSERT_TRUE(*ep == '.');
 }
 
Index: uspace/lib/c/test/string.c
===================================================================
--- uspace/lib/c/test/string.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/test/string.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -722,3 +722,113 @@
 }
 
+/** strlen function with empty string and non-zero limit */
+PCUT_TEST(strnlen_empty_short)
+{
+	PCUT_ASSERT_INT_EQUALS(0, strnlen("", 1));
+}
+
+/** strlen function with empty string and zero limit */
+PCUT_TEST(strnlen_empty_eq)
+{
+	PCUT_ASSERT_INT_EQUALS(0, strnlen("", 0));
+}
+
+/** strlen function with non empty string below limit */
+PCUT_TEST(strnlen_nonempty_short)
+{
+	PCUT_ASSERT_INT_EQUALS(3, strnlen("abc", 5));
+}
+
+/** strlen function with non empty string just below limit */
+PCUT_TEST(strnlen_nonempty_just_short)
+{
+	PCUT_ASSERT_INT_EQUALS(3, strnlen("abc", 4));
+}
+
+/** strlen function with non empty string of length equal to limit */
+PCUT_TEST(strnlen_nonempty_eq)
+{
+	PCUT_ASSERT_INT_EQUALS(3, strnlen("abc", 3));
+}
+
+/** strlen function with non empty string of length above limit */
+PCUT_TEST(strnlen_nonempty_long)
+{
+	PCUT_ASSERT_INT_EQUALS(2, strnlen("abc", 2));
+}
+
+/** strdup function with empty string */
+PCUT_TEST(strdup_empty)
+{
+	char *d = strdup("");
+	PCUT_ASSERT_NOT_NULL(d);
+	PCUT_ASSERT_TRUE(d[0] == '\0');
+	free(d);
+}
+
+/** strdup function with non-empty string */
+PCUT_TEST(strdup_nonempty)
+{
+	char *d = strdup("abc");
+	PCUT_ASSERT_NOT_NULL(d);
+	PCUT_ASSERT_TRUE(d[0] == 'a');
+	PCUT_ASSERT_TRUE(d[1] == 'b');
+	PCUT_ASSERT_TRUE(d[2] == 'c');
+	PCUT_ASSERT_TRUE(d[3] == '\0');
+	free(d);
+}
+
+/** strndup function with empty string and non-zero limit */
+PCUT_TEST(strndup_empty_short)
+{
+	char *d = strndup("", 1);
+	PCUT_ASSERT_NOT_NULL(d);
+	PCUT_ASSERT_TRUE(d[0] == '\0');
+	free(d);
+}
+
+/** strndup function with empty string and zero limit */
+PCUT_TEST(strndup_empty_eq)
+{
+	char *d = strndup("", 0);
+	PCUT_ASSERT_NOT_NULL(d);
+	PCUT_ASSERT_TRUE(d[0] == '\0');
+	free(d);
+}
+
+/** strndup function with non-empty string of length below limit */
+PCUT_TEST(strndup_nonempty_short)
+{
+	char *d = strndup("abc", 5);
+	PCUT_ASSERT_NOT_NULL(d);
+	PCUT_ASSERT_TRUE(d[0] == 'a');
+	PCUT_ASSERT_TRUE(d[1] == 'b');
+	PCUT_ASSERT_TRUE(d[2] == 'c');
+	PCUT_ASSERT_TRUE(d[3] == '\0');
+	free(d);
+}
+
+/** strndup function with non-empty string of length equal to limit */
+PCUT_TEST(strndup_nonempty_eq)
+{
+	char *d = strndup("abc", 3);
+	PCUT_ASSERT_NOT_NULL(d);
+	PCUT_ASSERT_TRUE(d[0] == 'a');
+	PCUT_ASSERT_TRUE(d[1] == 'b');
+	PCUT_ASSERT_TRUE(d[2] == 'c');
+	PCUT_ASSERT_TRUE(d[3] == '\0');
+	free(d);
+}
+
+/** strndup function with non-empty string of length above limit */
+PCUT_TEST(strndup_nonempty_long)
+{
+	char *d = strndup("abc", 2);
+	PCUT_ASSERT_NOT_NULL(d);
+	PCUT_ASSERT_TRUE(d[0] == 'a');
+	PCUT_ASSERT_TRUE(d[1] == 'b');
+	PCUT_ASSERT_TRUE(d[2] == '\0');
+	free(d);
+}
+
 PCUT_EXPORT(string);
Index: uspace/lib/c/test/strtol.c
===================================================================
--- uspace/lib/c/test/strtol.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/test/strtol.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,426 @@
+/*
+ * Copyright (c) 2018 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 libc
+ * @{
+ */
+/**
+ * @file
+ * @brief Test string to int conversion functions
+ */
+
+#include <pcut/pcut.h>
+#include <stdlib.h>
+#include <str.h>
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(strtol);
+
+/** atoi function */
+PCUT_TEST(atoi)
+{
+	int i;
+
+	i = atoi(" \t42");
+	PCUT_ASSERT_TRUE(i == 42);
+}
+
+/** atol function */
+PCUT_TEST(atol)
+{
+	long li;
+
+	li = atol(" \t42");
+	PCUT_ASSERT_TRUE(li == 42);
+}
+
+/** atoll function */
+PCUT_TEST(atoll)
+{
+	long long lli;
+
+	lli = atoll(" \t42");
+	PCUT_ASSERT_TRUE(lli == 42);
+}
+
+/** strtol function */
+PCUT_TEST(strtol)
+{
+	long li;
+	char *ep;
+
+	li = strtol(" \t42x", &ep, 10);
+	PCUT_ASSERT_TRUE(li == 42);
+	PCUT_ASSERT_TRUE(*ep == 'x');
+}
+
+/** strtol function with auto-detected base 10 */
+PCUT_TEST(strtol_dec_auto)
+{
+	long li;
+	char *ep;
+
+	li = strtol(" \t42x", &ep, 0);
+	PCUT_ASSERT_TRUE(li == 42);
+	PCUT_ASSERT_TRUE(*ep == 'x');
+}
+
+/** strtol function with octal number */
+PCUT_TEST(strtol_oct)
+{
+	long li;
+	char *ep;
+
+	li = strtol(" \t052x", &ep, 8);
+	PCUT_ASSERT_TRUE(li == 052);
+	PCUT_ASSERT_TRUE(*ep == 'x');
+}
+
+/** strtol function with octal number with prefix */
+#include <stdio.h>
+PCUT_TEST(strtol_oct_prefix)
+{
+	long li;
+	char *ep;
+
+	li = strtol(" \t052x", &ep, 0);
+	printf("li=%ld (0%lo)\n", li, li);
+	PCUT_ASSERT_TRUE(li == 052);
+	PCUT_ASSERT_TRUE(*ep == 'x');
+}
+
+/** strtol function with hex number */
+PCUT_TEST(strtol_hex)
+{
+	long li;
+	char *ep;
+
+	li = strtol(" \t2ax", &ep, 16);
+	PCUT_ASSERT_TRUE(li == 0x2a);
+	PCUT_ASSERT_TRUE(*ep == 'x');
+}
+
+/** strtol function with hex number with hex prefix */
+PCUT_TEST(strtol_hex_prefixed)
+{
+	long li;
+	char *ep;
+
+	li = strtol(" \t0x2ax", &ep, 0);
+	PCUT_ASSERT_TRUE(li == 0x2a);
+	PCUT_ASSERT_TRUE(*ep == 'x');
+}
+
+/** strtol function with base 16 and number with 0x prefix */
+PCUT_TEST(strtol_base16_prefix)
+{
+	long li;
+	char *ep;
+
+	li = strtol(" \t0x1y", &ep, 16);
+	printf("li=%ld\n", li);
+	PCUT_ASSERT_TRUE(li == 1);
+	PCUT_ASSERT_TRUE(*ep == 'y');
+}
+
+/** strtol function with base 36 number */
+PCUT_TEST(strtol_base36)
+{
+	long li;
+	char *ep;
+
+	li = strtol(" \tz1.", &ep, 36);
+	PCUT_ASSERT_TRUE(li == 35 * 36 + 1);
+	PCUT_ASSERT_TRUE(*ep == '.');
+}
+
+PCUT_TEST(str_uint_hex)
+{
+	int base;
+	bool strict;
+	const char *endp;
+	uint32_t result;
+	errno_t rc;
+	const char *input;
+
+	/*
+	 * str_* conversion function do not admit a prefix when base is
+	 * specified.
+	 */
+
+	rc = str_uint32_t(input = "0x10", &endp, base = 0, strict = false, &result);
+	PCUT_ASSERT_INT_EQUALS(EOK, rc);
+	PCUT_ASSERT_INT_EQUALS(0x10, result);
+	PCUT_ASSERT_PTR_EQUALS(input + 4, endp);
+
+	rc = str_uint32_t(input = "0x10", &endp, base = 16, strict = false, &result);
+	PCUT_ASSERT_INT_EQUALS(EOK, rc);
+	PCUT_ASSERT_INT_EQUALS(0, result);
+	PCUT_ASSERT_PTR_EQUALS(input + 1, endp);
+
+	rc = str_uint32_t(input = "  \t0x10", &endp, base = 0, strict = false, &result);
+	PCUT_ASSERT_INT_EQUALS(EOK, rc);
+	PCUT_ASSERT_INT_EQUALS(0x10, result);
+	PCUT_ASSERT_PTR_EQUALS(input + 7, endp);
+
+	rc = str_uint32_t(input = "  \t0x10", &endp, base = 16, strict = false, &result);
+	PCUT_ASSERT_INT_EQUALS(EOK, rc);
+	PCUT_ASSERT_INT_EQUALS(0, result);
+	PCUT_ASSERT_PTR_EQUALS(input + 4, endp);
+}
+
+PCUT_TEST(str_uint_overflow)
+{
+	int base;
+	bool strict;
+	uint64_t result;
+	errno_t rc;
+	const char *input;
+
+	/*
+	 * Naive overflow check will not detect this overflow,
+	 * since the intermediate result is equal to the previous step.
+	 */
+
+	rc = str_uint64_t(input = "0xffffffffffffffffffffffffffffffff", NULL, base = 0, strict = false, &result);
+#if 0
+	/* Buggy result. */
+	PCUT_ASSERT_INT_EQUALS(EOK, rc);
+	PCUT_ASSERT_UINT_EQUALS(0xffffffffffffffff, result);
+#else
+	/* Correct result. */
+	PCUT_ASSERT_INT_EQUALS(EOVERFLOW, rc);
+	PCUT_ASSERT_UINT_EQUALS(UINT64_MAX, result);
+#endif
+
+	/* 3^40 */
+
+	rc = str_uint64_t(input = "1" "0000000000" "0000000000" "0000000000" "0000000000", NULL, base = 3, strict = false, &result);
+	PCUT_ASSERT_INT_EQUALS(EOK, rc);
+	PCUT_ASSERT_UINT_EQUALS(0xa8b8b452291fe821, result);
+
+	/*
+	 * Naive overflow check will not detect this overflow,
+	 * since the intermediate result is greater than the previous step,
+	 * despite overflowing 64 bits.
+	 *
+	 * The input is 3^41 which is greater than 2^64,
+	 * but (3^41 mod 2^64) is still greater than 3^40, so overflow is not
+	 * detected by a naive magnitude check.
+	 */
+
+	rc = str_uint64_t(input = "10" "0000000000" "0000000000" "0000000000" "0000000000", NULL, base = 3, strict = false, &result);
+#if 0
+	/* Buggy result. */
+	PCUT_ASSERT_INT_EQUALS(EOK, rc);
+	/* Correct value is    0x1fa2a1cf67b5fb863 */
+	PCUT_ASSERT_UINT_EQUALS(0xfa2a1cf67b5fb863, result);
+#else
+	/* Correct result. */
+	PCUT_ASSERT_INT_EQUALS(EOVERFLOW, rc);
+	PCUT_ASSERT_UINT_EQUALS(UINT64_MAX, result);
+#endif
+}
+
+PCUT_TEST(strtol_fringe)
+{
+	long output;
+	char *endp;
+	char *endp_unchanged = (char *) "endp_unchanged unique pointer";
+	int errno_unchanged = -1;
+	const char *input;
+	int base;
+
+	/* Variants of plain zero with various bases. */
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "0", &endp, base = 0);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input + 1, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "0", &endp, base = -10);
+	PCUT_ASSERT_INT_EQUALS(EINVAL, errno);
+	PCUT_ASSERT_PTR_EQUALS(endp_unchanged, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "0", &endp, base = 1);
+	PCUT_ASSERT_INT_EQUALS(EINVAL, errno);
+	PCUT_ASSERT_PTR_EQUALS(endp_unchanged, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	for (base = 2; base <= 36; base++) {
+		endp = endp_unchanged;
+		errno = errno_unchanged;
+		output = strtol(input = "0", &endp, base);
+		PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+		PCUT_ASSERT_PTR_EQUALS(input + 1, endp);
+		PCUT_ASSERT_INT_EQUALS(0, output);
+
+		endp = endp_unchanged;
+		errno = errno_unchanged;
+		output = strtol(input = "1", &endp, base);
+		PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+		PCUT_ASSERT_PTR_EQUALS(input + 1, endp);
+		PCUT_ASSERT_INT_EQUALS(1, output);
+
+		endp = endp_unchanged;
+		errno = errno_unchanged;
+		output = strtol(input = "10", &endp, base);
+		PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+		PCUT_ASSERT_PTR_EQUALS(input + 2, endp);
+		PCUT_ASSERT_INT_EQUALS(base, output);
+
+		endp = endp_unchanged;
+		errno = errno_unchanged;
+		output = strtol(input = "100", &endp, base);
+		PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+		PCUT_ASSERT_PTR_EQUALS(input + 3, endp);
+		PCUT_ASSERT_INT_EQUALS(base * base, output);
+
+		endp = endp_unchanged;
+		errno = errno_unchanged;
+		output = strtol(input = "1000", &endp, base);
+		PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+		PCUT_ASSERT_PTR_EQUALS(input + 4, endp);
+		PCUT_ASSERT_INT_EQUALS(base * base * base, output);
+	}
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "0", &endp, base = 8);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input + 1, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "0", &endp, base = 10);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input + 1, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "0", &endp, base = 16);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input + 1, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "0", &endp, base = 36);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input + 1, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "0", &endp, base = 37);
+	PCUT_ASSERT_INT_EQUALS(EINVAL, errno);
+	PCUT_ASSERT_PTR_EQUALS(endp_unchanged, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "0", &endp, base = 37);
+	PCUT_ASSERT_INT_EQUALS(EINVAL, errno);
+	PCUT_ASSERT_PTR_EQUALS(endp_unchanged, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	/* No valid number */
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "", &endp, base = 0);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "    ", &endp, base = 0);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "    ", &endp, base = 10);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "    x", &endp, base = 0);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "    x0", &endp, base = 0);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "    0x", &endp, base = 0);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input + 5, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "    0x1", &endp, base = 0);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input + 7, endp);
+	PCUT_ASSERT_INT_EQUALS(1, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "    0x", &endp, base = 16);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input + 5, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "    0x1", &endp, base = 16);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input + 7, endp);
+	PCUT_ASSERT_INT_EQUALS(1, output);
+}
+
+PCUT_EXPORT(strtol);
Index: uspace/lib/c/test/uuid.c
===================================================================
--- uspace/lib/c/test/uuid.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/test/uuid.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2019 Matthieu Riolo
+ * 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 <pcut/pcut.h>
+#include <uuid.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <str.h>
+#include <ctype.h>
+
+static size_t MAX_SUB_TESTS = 10;
+static size_t uuids_len = 6;
+static const char *uuids[] = {
+	/* uppercase */
+	"F81163AE-299A-4DA2-BED1-0E096C59F3AB",
+	"4A0CE2A3-FD1C-4951-972E-AAA13A703078",
+	"69C7DB62-8309-4C58-831B-8C4E4161E8AC",
+
+	/* lower case*/
+	"c511bf24-70cb-422e-933b-2a74ab699a56",
+	"7b1abd05-456f-4661-ab62-917685069343",
+	"5b00f76b-4a16-4dce-a1fc-b78c60324d89"
+};
+
+static bool uuid_valid(uuid_t uuid)
+{
+	if (!(uuid.b[6] & 0x40)) {
+		return false;
+	}
+
+	int f = (uuid.b[8] & 0x80) || (uuid.b[8] & 0x90);
+	f = f || (uuid.b[8] & 0xA0) || (uuid.b[8] & 0xB0);
+	if (!f) {
+		return false;
+	}
+
+	return true;
+}
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(uuid);
+
+PCUT_TEST(uuid_generate)
+{
+	uuid_t uuid;
+	size_t i;
+
+	for (i = 0; i < MAX_SUB_TESTS; i++) {
+		errno_t ret = uuid_generate(&uuid);
+		PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+		PCUT_ASSERT_TRUE(uuid_valid(uuid));
+	}
+}
+
+PCUT_TEST(uuid_parse)
+{
+	uuid_t uuid;
+	errno_t ret;
+
+	for (size_t i = 0; i < uuids_len; i++) {
+		ret = uuid_parse(uuids[i], &uuid, NULL);
+		PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+		PCUT_ASSERT_TRUE(uuid_valid(uuid));
+	}
+}
+
+PCUT_TEST(uuid_parse_in_text)
+{
+	uuid_t uuid;
+	errno_t ret;
+	const char *endptr;
+	const char *uuid_in_text = "7b1abd05-456f-4661-ab62-917685069343hello world!";
+
+	ret = uuid_parse(uuid_in_text, &uuid, &endptr);
+
+	PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+	PCUT_ASSERT_TRUE(uuid_valid(uuid));
+	PCUT_ASSERT_STR_EQUALS("hello world!", endptr);
+}
+
+PCUT_TEST(uuid_format_generated)
+{
+	uuid_t uuid;
+	size_t i;
+	char *rstr;
+
+	for (i = 0; i < MAX_SUB_TESTS; i++) {
+		errno_t ret = uuid_generate(&uuid);
+		PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+		PCUT_ASSERT_TRUE(uuid_valid(uuid));
+
+		ret = uuid_format(&uuid, &rstr, true);
+		PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+		PCUT_ASSERT_INT_EQUALS('\0', rstr[37]);
+		PCUT_ASSERT_INT_EQUALS(36, str_length(rstr));
+		PCUT_ASSERT_INT_EQUALS('4', rstr[14]);
+
+		int f = rstr[19] == '8' || rstr[19] == '9';
+		f = f || toupper(rstr[19]) == 'A' || toupper(rstr[19]) == 'B';
+		PCUT_ASSERT_TRUE(f);
+
+		free(rstr);
+	}
+}
+
+PCUT_TEST(uuid_format_parsed)
+{
+	uuid_t uuid;
+	char *rstr;
+	errno_t ret;
+
+	for (size_t i = 0; i < uuids_len; i++) {
+		ret = uuid_parse(uuids[i], &uuid, NULL);
+		PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+		PCUT_ASSERT_TRUE(uuid_valid(uuid));
+
+		ret = uuid_format(&uuid, &rstr, true);
+		PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+		PCUT_ASSERT_INT_EQUALS('\0', rstr[37]);
+		PCUT_ASSERT_INT_EQUALS(36, str_length(rstr));
+		PCUT_ASSERT_INT_EQUALS(0, str_casecmp(uuids[i], rstr));
+
+		free(rstr);
+	}
+}
+
+PCUT_EXPORT(uuid);
Index: uspace/lib/clui/tinput.c
===================================================================
--- uspace/lib/clui/tinput.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/clui/tinput.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -56,4 +56,5 @@
 } seek_dir_t;
 
+static void tinput_update_origin(tinput_t *);
 static void tinput_init(tinput_t *);
 static void tinput_insert_string(tinput_t *, const char *);
@@ -71,6 +72,10 @@
 static void tinput_console_set_lpos(tinput_t *ti, unsigned lpos)
 {
-	console_set_pos(ti->console, LIN_TO_COL(ti, lpos),
-	    LIN_TO_ROW(ti, lpos));
+	unsigned col = LIN_TO_COL(ti, lpos);
+	unsigned row = LIN_TO_ROW(ti, lpos);
+
+	assert(col < ti->con_cols);
+	assert(row < ti->con_rows);
+	console_set_pos(ti->console, col, row);
 }
 
@@ -163,4 +168,5 @@
 static void tinput_position_caret(tinput_t *ti)
 {
+	tinput_update_origin(ti);
 	tinput_console_set_lpos(ti, ti->text_coord + ti->pos);
 }
@@ -232,5 +238,4 @@
 
 	tinput_display_tail(ti, ti->pos - 1, 0);
-	tinput_update_origin(ti);
 	tinput_position_caret(ti);
 }
@@ -276,5 +281,4 @@
 
 	tinput_display_tail(ti, ti->pos - ilen, 0);
-	tinput_update_origin(ti);
 	tinput_position_caret(ti);
 }
Index: uspace/lib/cpp/include/__bits/adt/list.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/list.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/adt/list.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -32,4 +32,5 @@
 #include <__bits/adt/list_node.hpp>
 #include <__bits/insert_iterator.hpp>
+#include <cassert>
 #include <cstdlib>
 #include <iterator>
@@ -580,4 +581,5 @@
             {
                 // TODO: implement
+                __unimplemented();
             }
 
@@ -585,4 +587,5 @@
             {
                 // TODO: implement
+                __unimplemented();
             }
 
@@ -1042,4 +1045,5 @@
             {
                 // TODO: implement
+                __unimplemented();
             }
 
@@ -1053,4 +1057,5 @@
             {
                 // TODO: implement
+                __unimplemented();
             }
 
@@ -1064,4 +1069,5 @@
             {
                 // TODO: implement
+                __unimplemented();
             }
 
@@ -1069,4 +1075,5 @@
             {
                 // TODO: implement
+                __unimplemented();
             }
 
@@ -1075,4 +1082,5 @@
             {
                 // TODO: implement
+                __unimplemented();
             }
 
Index: uspace/lib/cpp/include/__bits/chrono.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/chrono.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/chrono.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -611,6 +611,6 @@
             static time_point now()
             {
-                hel::timespec ts{};
-                hel::getrealtime(&ts);
+                ::std::timespec ts{};
+                ::helenos::getrealtime(&ts);
 
                 rep time = NSEC2USEC(ts.tv_nsec);
@@ -654,6 +654,6 @@
             static time_point now()
             {
-                hel::timespec ts{};
-                hel::getuptime(&ts);
+                ::std::timespec ts{};
+                ::helenos::getuptime(&ts);
 
                 rep time = NSEC2USEC(ts.tv_nsec);
Index: pace/lib/cpp/include/__bits/common.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/common.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,41 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * 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 LIBCPP_BITS_COMMON
-#define LIBCPP_BITS_COMMON
-
-/**
- * According to section 17.2 of the standard,
- * the restrict qualifier shall be omitted.
- */
-#define restrict
-
-#undef NULL
-#define NULL nullptr
-
-#endif
Index: uspace/lib/cpp/include/__bits/complex.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/complex.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/complex.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -30,4 +30,5 @@
 #define LIBCPP_BITS_COMPLEX
 
+#include <cassert>
 #include <iosfwd>
 #include <sstream>
@@ -724,4 +725,6 @@
     {
         // TODO: implement
+        __unimplemented();
+        return is;
     }
 
@@ -766,4 +769,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -779,4 +783,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -786,4 +791,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -793,4 +799,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return complex<T>{};
     }
@@ -804,4 +811,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -811,4 +819,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -818,4 +827,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -825,4 +835,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -832,4 +843,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -839,4 +851,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -846,4 +859,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -853,4 +867,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -860,4 +875,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -867,4 +883,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -874,4 +891,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -881,4 +899,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return base;
     }
@@ -888,4 +907,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return base;
     }
@@ -895,4 +915,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return complex<T>{base};
     }
@@ -902,4 +923,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -909,4 +931,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -916,4 +939,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -923,4 +947,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -930,4 +955,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
Index: uspace/lib/cpp/include/__bits/functional/bind.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/functional/bind.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/functional/bind.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -33,4 +33,5 @@
 #include <__bits/functional/invoke.hpp>
 #include <__bits/functional/reference_wrapper.hpp>
+#include <cassert>
 #include <tuple>
 #include <type_traits>
@@ -133,4 +134,5 @@
                 constexpr decltype(auto) operator[](const bind_t<R, B, F, BindArgs...> b)
                 {
+                    __unimplemented();
                     return b; // TODO: bind subexpressions
                 }
Index: uspace/lib/cpp/include/__bits/io/fstream.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/io/fstream.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/io/fstream.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -30,4 +30,5 @@
 #define LIBCPP_BITS_IO_FSTREAM
 
+#include <cassert>
 #include <cstdio>
 #include <ios>
@@ -267,4 +268,5 @@
             {
                 // TODO: implement
+                __unimplemented();
                 return nullptr;
             }
@@ -274,4 +276,5 @@
             {
                 // TODO: implement
+                __unimplemented();
                 return pos_type{};
             }
@@ -281,4 +284,5 @@
             {
                 // TODO: implement
+                __unimplemented();
                 return pos_type{};
             }
Index: uspace/lib/cpp/include/__bits/io/ios.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/io/ios.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/io/ios.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -41,5 +41,5 @@
 {
     using streamoff = long long;
-    using streamsize = hel::ssize_t;
+    using streamsize = ::ssize_t;
 
     /**
Index: uspace/lib/cpp/include/__bits/io/istream.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/io/istream.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/io/istream.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -30,4 +30,5 @@
 #define LIBCPP_BITS_IO_ISTREAM
 
+#include <cassert>
 #include <ios>
 #include <iosfwd>
@@ -339,4 +340,6 @@
             {
                 // TODO: implement
+                __unimplemented();
+                return *this;
             }
 
@@ -344,4 +347,6 @@
             {
                 // TODO: implement
+                __unimplemented();
+                return *this;
             }
 
@@ -349,4 +354,6 @@
             {
                 // TODO: implement
+                __unimplemented();
+                return *this;
             }
 
@@ -354,4 +361,6 @@
             {
                 // TODO: implement
+                __unimplemented();
+                return *this;
             }
 
Index: uspace/lib/cpp/include/__bits/io/ostream.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/io/ostream.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/io/ostream.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -30,4 +30,5 @@
 #define LIBCPP_BITS_IO_OSTREAM
 
+#include <cassert>
 #include <ios>
 #include <iosfwd>
@@ -458,4 +459,5 @@
             {
                 // TODO: implement
+                __unimplemented();
                 return pos_type{};
             }
@@ -464,4 +466,5 @@
             {
                 // TODO: implement
+                __unimplemented();
                 return *this;
             }
@@ -470,4 +473,5 @@
             {
                 // TODO: implement
+                __unimplemented();
                 return *this;
             }
Index: uspace/lib/cpp/include/__bits/limits.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/limits.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/limits.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -528,5 +528,5 @@
             static constexpr unsigned short min()
             {
-                return USHRT_MIN;
+                return 0;
             }
 
@@ -552,5 +552,5 @@
             static constexpr unsigned int min()
             {
-                return UINT_MIN;
+                return 0;
             }
 
@@ -576,5 +576,5 @@
             static constexpr unsigned long min()
             {
-                return ULONG_MIN;
+                return 0;
             }
 
@@ -600,5 +600,5 @@
             static constexpr unsigned long long min()
             {
-                return ULLONG_MIN;
+                return 0;
             }
 
Index: uspace/lib/cpp/include/__bits/locale/num_get.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/locale/num_get.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/locale/num_get.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -301,16 +301,19 @@
                 if (size > 0)
                 {
-                    int ret{};
+                    int olderrno{errno};
+                    errno = EOK;
+                    char *endptr = NULL;
+
                     if constexpr (is_signed<BaseType>::value)
-                        ret = std::hel::str_int64_t(base.buffer_, nullptr, num_base, false, &res);
-                    else
-                        ret = std::hel::str_uint64_t(base.buffer_, nullptr, num_base, false, &res);
-
-                    if (ret != EOK)
-                    {
+                        res = ::strtoll(base.buffer_, &endptr, num_base);
+                    else
+                        res = ::strtoull(base.buffer_, &endptr, num_base);
+
+                    if (errno != EOK || endptr == base.buffer_)
                         err |= ios_base::failbit;
-                        v = 0;
-                    }
-                    else if (res > static_cast<BaseType>(numeric_limits<T>::max()))
+
+                    errno = olderrno;
+
+                    if (res > static_cast<BaseType>(numeric_limits<T>::max()))
                     {
                         err |= ios_base::failbit;
Index: uspace/lib/cpp/include/__bits/new.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/new.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/new.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -30,4 +30,5 @@
 #define LIBCPP_BITS_NEW
 
+#include <cstddef>
 #include <exception>
 
Index: uspace/lib/cpp/include/__bits/random.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/random.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/random.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1030,10 +1030,10 @@
              *       something better.
              */
-            hel::srand(hel::time(nullptr));
+            ::srand(::time(nullptr));
         }
 
         result_type operator()()
         {
-            return hel::rand();
+            return ::rand();
         }
 
Index: uspace/lib/cpp/include/__bits/string/string.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/string/string.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/string/string.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -32,4 +32,5 @@
 #include <__bits/string/stringfwd.hpp>
 #include <algorithm>
+#include <cassert>
 #include <initializer_list>
 #include <iosfwd>
@@ -81,10 +82,10 @@
         static int compare(const char_type* s1, const char_type* s2, size_t n)
         {
-            return hel::str_lcmp(s1, s2, n);
+            return ::strncmp(s1, s2, n);
         }
 
         static size_t length(const char_type* s)
         {
-            return hel::str_size(s);
+            return ::strlen(s);
         }
 
@@ -178,4 +179,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return 0;
         }
@@ -184,4 +186,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return 0;
         }
@@ -190,4 +193,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return nullptr;
         }
@@ -196,4 +200,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return nullptr;
         }
@@ -202,4 +207,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return nullptr;
         }
@@ -208,4 +214,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return nullptr;
         }
@@ -266,4 +273,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return 0;
         }
@@ -272,4 +280,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return 0;
         }
@@ -278,4 +287,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return nullptr;
         }
@@ -284,4 +294,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return nullptr;
         }
@@ -290,4 +301,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return nullptr;
         }
@@ -296,4 +308,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return nullptr;
         }
@@ -353,5 +366,5 @@
         {
             // TODO: This function does not exits...
-            //return hel::wstr_lcmp(s1, s2, n);
+            __unimplemented();
             return 0;
         }
@@ -359,5 +372,8 @@
         static size_t length(const char_type* s)
         {
-            return hel::wstr_size(s);
+            size_t i = 0;
+            while (s[i] != 0)
+                i++;
+            return i;
         }
 
@@ -1939,4 +1955,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return size_t{};
         }
Index: uspace/lib/cpp/include/__bits/thread/condition_variable.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/thread/condition_variable.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/thread/condition_variable.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,9 +35,4 @@
 namespace std
 {
-    extern "C" {
-        #include <fibril.h>
-        #include <fibril_synch.h>
-    }
-
     enum class cv_status
     {
Index: uspace/lib/cpp/include/__bits/thread/future.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/thread/future.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/thread/future.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -30,4 +30,5 @@
 #define LIBCPP_BITS_THREAD_FUTURE
 
+#include <cassert>
 #include <memory>
 #include <system_error>
@@ -171,4 +172,5 @@
     {
         // TODO: implement
+        __unimplemented();
     }
 
@@ -178,4 +180,5 @@
     {
         // TODO: implement
+        __unimplemented();
     }
 }
Index: uspace/lib/cpp/include/__bits/thread/mutex.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/thread/mutex.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/thread/mutex.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,5 +30,4 @@
 #define LIBCPP_BITS_THREAD_MUTEX
 
-#include <__bits/common.hpp>
 #include <__bits/thread/threading.hpp>
 #include <functional>
Index: uspace/lib/cpp/include/__bits/thread/thread.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/thread/thread.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/thread/thread.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,5 +30,4 @@
 #define LIBCPP_BITS_THREAD
 
-#include <__bits/common.hpp>
 #include <__bits/thread/threading.hpp>
 #include <chrono>
Index: uspace/lib/cpp/include/__bits/thread/threading.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/thread/threading.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/thread/threading.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,14 +30,8 @@
 #define LIBCPP_BITS_THREAD_THREADING
 
-namespace std::hel
-{
-    extern "C" {
-        #include <async.h>
-        #include <fibril.h>
-        #include <fibril_synch.h>
-    }
-}
-
 #include <chrono>
+
+#include <fibril.h>
+#include <fibril_synch.h>
 
 namespace std::aux
@@ -55,9 +49,9 @@
     struct threading_policy<fibril_tag>
     {
-        using mutex_type        = hel::fibril_mutex_t;
-        using thread_type       = hel::fid_t;
-        using condvar_type      = hel::fibril_condvar_t;
-        using time_unit         = hel::usec_t;
-        using shared_mutex_type = hel::fibril_rwlock_t;
+        using mutex_type        = ::helenos::fibril_mutex_t;
+        using thread_type       = ::helenos::fid_t;
+        using condvar_type      = ::helenos::fibril_condvar_t;
+        using time_unit         = ::helenos::usec_t;
+        using shared_mutex_type = ::helenos::fibril_rwlock_t;
 
         struct thread
@@ -66,20 +60,20 @@
             static thread_type create(Callable clbl, Payload& pld)
             {
-                return hel::fibril_create(clbl, (void*)&pld);
+                return ::helenos::fibril_create(clbl, (void*)&pld);
             }
 
             static void start(thread_type thr)
             {
-                hel::fibril_add_ready(thr);
+                ::helenos::fibril_add_ready(thr);
             }
 
             static thread_type this_thread()
             {
-                return hel::fibril_get_id();
+                return ::helenos::fibril_get_id();
             }
 
             static void yield()
             {
-                hel::fibril_yield();
+                ::helenos::fibril_yield();
             }
 
@@ -95,20 +89,20 @@
             static void init(mutex_type& mtx)
             {
-                hel::fibril_mutex_initialize(&mtx);
+                ::helenos::fibril_mutex_initialize(&mtx);
             }
 
             static void lock(mutex_type& mtx)
             {
-                hel::fibril_mutex_lock(&mtx);
+                ::helenos::fibril_mutex_lock(&mtx);
             }
 
             static void unlock(mutex_type& mtx)
             {
-                hel::fibril_mutex_unlock(&mtx);
+                ::helenos::fibril_mutex_unlock(&mtx);
             }
 
             static bool try_lock(mutex_type& mtx)
             {
-                return hel::fibril_mutex_trylock(&mtx);
+                return ::helenos::fibril_mutex_trylock(&mtx);
             }
 
@@ -124,25 +118,25 @@
             static void init(condvar_type& cv)
             {
-                hel::fibril_condvar_initialize(&cv);
+                ::helenos::fibril_condvar_initialize(&cv);
             }
 
             static void wait(condvar_type& cv, mutex_type& mtx)
             {
-                hel::fibril_condvar_wait(&cv, &mtx);
+                ::helenos::fibril_condvar_wait(&cv, &mtx);
             }
 
             static int wait_for(condvar_type& cv, mutex_type& mtx, time_unit timeout)
             {
-                return hel::fibril_condvar_wait_timeout(&cv, &mtx, timeout);
+                return ::helenos::fibril_condvar_wait_timeout(&cv, &mtx, timeout);
             }
 
             static void signal(condvar_type& cv)
             {
-                hel::fibril_condvar_signal(&cv);
+                ::helenos::fibril_condvar_signal(&cv);
             }
 
             static void broadcast(condvar_type& cv)
             {
-                hel::fibril_condvar_broadcast(&cv);
+                ::helenos::fibril_condvar_broadcast(&cv);
             }
         };
@@ -158,5 +152,5 @@
             static void sleep(time_unit time)
             {
-                hel::fibril_usleep(time);
+                ::helenos::fibril_usleep(time);
             }
         };
@@ -166,25 +160,25 @@
             static void init(shared_mutex_type& mtx)
             {
-                hel::fibril_rwlock_initialize(&mtx);
+                ::helenos::fibril_rwlock_initialize(&mtx);
             }
 
             static void lock(shared_mutex_type& mtx)
             {
-                hel::fibril_rwlock_write_lock(&mtx);
+                ::helenos::fibril_rwlock_write_lock(&mtx);
             }
 
             static void unlock(shared_mutex_type& mtx)
             {
-                hel::fibril_rwlock_write_unlock(&mtx);
+                ::helenos::fibril_rwlock_write_unlock(&mtx);
             }
 
             static void lock_shared(shared_mutex_type& mtx)
             {
-                hel::fibril_rwlock_read_lock(&mtx);
+                ::helenos::fibril_rwlock_read_lock(&mtx);
             }
 
             static void unlock_shared(shared_mutex_type& mtx)
             {
-                hel::fibril_rwlock_read_unlock(&mtx);
+                ::helenos::fibril_rwlock_read_unlock(&mtx);
             }
 
Index: uspace/lib/cpp/include/cassert
===================================================================
--- uspace/lib/cpp/include/cassert	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/cassert	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -30,30 +30,7 @@
 #define LIBCPP_CASSERT
 
-#include <__bits/common.hpp>
+#include <assert.h>
 
-namespace std::hel
-{
-    extern "C" {
-        #include <assert.h>
-    }
-}
-
-namespace std
-{
-    // Note: The only thing imported is assert
-    //       and that is a macro.
-}
-
-/**
- * We need to fix the assert macro because it uses
- * a non-standard function that we have in the
- * std::hel namespace.
- */
-#undef assert
-#define assert(expr) \
-	do { \
-		if (!(expr)) \
-			std::hel::assert_abort(#expr, __FILE__, __LINE__); \
-	} while (0)
+#define __unimplemented() assert(!"Not implemented!")
 
 #endif
Index: uspace/lib/cpp/include/cctype
===================================================================
--- uspace/lib/cpp/include/cctype	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/cctype	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,29 +30,22 @@
 #define LIBCPP_CCTYPE
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <ctype.h>
-    }
-}
+#include <ctype.h>
 
 namespace std
 {
-    using std::hel::isalnum;
-    using std::hel::isalpha;
-    using std::hel::islower;
-    using std::hel::isupper;
-    using std::hel::isdigit;
-    /* using std::hel::isxdigit; */
-    /* using std::hel::iscntrl; */
-    /* using std::hel::isgraph; */
-    using std::hel::isspace;
-    /* using std::hel::isblank; */
-    /* using std::hel::isprint; */
-    /* using std::hel::ispunct; */
-    using std::hel::tolower;
-    using std::hel::toupper;
+    using ::isalnum;
+    using ::isalpha;
+    using ::islower;
+    using ::isupper;
+    using ::isdigit;
+    using ::isxdigit;
+    using ::iscntrl;
+    using ::isgraph;
+    using ::isspace;
+    using ::isblank;
+    using ::isprint;
+    using ::ispunct;
+    using ::tolower;
+    using ::toupper;
 }
 
Index: uspace/lib/cpp/include/cerrno
===================================================================
--- uspace/lib/cpp/include/cerrno	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/cerrno	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,17 +30,5 @@
 #define LIBCPP_CERRNO
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <errno.h>
-    }
-}
-
-namespace std
-{
-    // Note: Only macros are imported here.
-}
+#include <errno.h>
 
 #endif
Index: uspace/lib/cpp/include/cinttypes
===================================================================
--- uspace/lib/cpp/include/cinttypes	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/cinttypes	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,37 +30,17 @@
 #define LIBCPP_CINTTYPES
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <inttypes.h>
-    }
-}
+#include <cstdint>
+#include <inttypes.h>
 
 namespace std
 {
-    using std::hel::imaxdiv_t;
-    /* using std::hel::abs; */
-    /* using std::hel::div; */
-    /* using std::hel::imaxabs; */
-    /* using std::hel::imaxdiv; */
-    /* using std::hel::strtoimax; */
-    /* using std::hel::strtoumax; */
-    /* using std::hel::wcstoimax; */
-    /* using std::hel::wcstoumax; */
+    using ::imaxdiv_t;
+    using ::imaxabs;
+    using ::imaxdiv;
+    using ::strtoimax;
+    using ::strtoumax;
+    using ::wcstoimax;
+    using ::wcstoumax;
 }
 
-using std::hel::imaxdiv_t;
-/* using std::hel::abs; */
-/* using std::hel::div; */
-/* using std::hel::imaxabs; */
-/* using std::hel::imaxdiv; */
-/* using std::hel::strtoimax; */
-/* using std::hel::strtoumax; */
-/* using std::hel::wcstoimax; */
-/* using std::hel::wcstoumax; */
-
-#include <cstdint>
-
 #endif
Index: uspace/lib/cpp/include/climits
===================================================================
--- uspace/lib/cpp/include/climits	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/climits	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,17 +30,5 @@
 #define LIBCPP_CLIMITS
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <limits.h>
-    }
-}
-
-namespace std
-{
-    // Note: Only macros imported here.
-}
+#include <limits.h>
 
 #endif
Index: uspace/lib/cpp/include/csetjmp
===================================================================
--- uspace/lib/cpp/include/csetjmp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/csetjmp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,26 +30,11 @@
 #define LIBCPP_CSETJMP
 
-#include <__bits/common.hpp>
-
-/**
- * TODO: Currently the <setjmp.h> header uses
- *       _Noreturn, which is not available in C++.
- */
-
-namespace std::hel
-{
-    extern "C" {
-        //#include <setjmp.h>
-    }
-}
+#include <setjmp.h>
 
 namespace std
 {
-    /* using std::hel::jmp_buf; */
-    /* using std::hel::longjmp; */
+    using ::jmp_buf;
+    using ::longjmp;
 }
 
-/* using std::hel::jmp_buf; */
-/* using std::hel::longjmp; */
-
 #endif
Index: uspace/lib/cpp/include/cstdarg
===================================================================
--- uspace/lib/cpp/include/cstdarg	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/cstdarg	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,19 +30,10 @@
 #define LIBCPP_CSTDARG
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <stdarg.h>
-    }
-}
+#include <stdarg.h>
 
 namespace std
 {
-    using std::hel::va_list;
+    using ::va_list;
 }
 
-using std::hel::va_list;
-
 #endif
Index: uspace/lib/cpp/include/cstddef
===================================================================
--- uspace/lib/cpp/include/cstddef	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/cstddef	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,27 +30,13 @@
 #define LIBCPP_CSTDDEF
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <stddef.h>
-    }
-}
-
+#include <stddef.h>
 
 namespace std
 {
-    using nullptr_t = decltype(nullptr);
-
-    using std::hel::size_t;
-    using std::hel::ptrdiff_t;
-    /* using std::hel::max_align_t; */
+    using ::nullptr_t;
+    using ::size_t;
+    using ::ptrdiff_t;
+    using ::max_align_t;
 }
 
-using std::nullptr_t;
-using std::hel::size_t;
-using std::hel::ptrdiff_t;
-/* using std::hel::max_align_t; */
-
 #endif
Index: uspace/lib/cpp/include/cstdint
===================================================================
--- uspace/lib/cpp/include/cstdint	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/cstdint	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,87 +30,44 @@
 #define LIBCPP_CSTDINT
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <stdint.h>
-    }
-}
+#include <stdint.h>
 
 namespace std
 {
-    using int8_t  = std::hel::int8_t;
-    using int16_t = std::hel::int16_t;
-    using int32_t = std::hel::int32_t;
-    using int64_t = std::hel::int64_t;
+    using ::int8_t;
+    using ::int16_t;
+    using ::int32_t;
+    using ::int64_t;
 
-    using intmax_t = std::hel::intmax_t;
-    using intptr_t = std::hel::intptr_t;
+    using ::intmax_t;
+    using ::intptr_t;
 
-    using int_fast8_t  = std::hel::int8_t;
-    using int_fast16_t = std::hel::int16_t;
-    using int_fast32_t = std::hel::int32_t;
-    using int_fast64_t = std::hel::int64_t;
+    using ::int_fast8_t;
+    using ::int_fast16_t;
+    using ::int_fast32_t;
+    using ::int_fast64_t;
 
-    using int_least8_t  = std::hel::int8_t;
-    using int_least16_t = std::hel::int16_t;
-    using int_least32_t = std::hel::int32_t;
-    using int_least64_t = std::hel::int64_t;
+    using ::int_least8_t;
+    using ::int_least16_t;
+    using ::int_least32_t;
+    using ::int_least64_t;
 
-    using uint8_t  = std::hel::uint8_t;
-    using uint16_t = std::hel::uint16_t;
-    using uint32_t = std::hel::uint32_t;
-    using uint64_t = std::hel::uint64_t;
+    using ::uint8_t;
+    using ::uint16_t;
+    using ::uint32_t;
+    using ::uint64_t;
 
-    using uintmax_t = std::hel::uintmax_t;
-    using uintptr_t = std::hel::uintptr_t;
+    using ::uintmax_t;
+    using ::uintptr_t;
 
-    using uint_fast8_t  = std::hel::uint8_t;
-    using uint_fast16_t = std::hel::uint16_t;
-    using uint_fast32_t = std::hel::uint32_t;
-    using uint_fast64_t = std::hel::uint64_t;
+    using ::uint_fast8_t;
+    using ::uint_fast16_t;
+    using ::uint_fast32_t;
+    using ::uint_fast64_t;
 
-    using uint_least8_t  = std::hel::uint8_t;
-    using uint_least16_t = std::hel::uint16_t;
-    using uint_least32_t = std::hel::uint32_t;
-    using uint_least64_t = std::hel::uint64_t;
+    using ::uint_least8_t;
+    using ::uint_least16_t;
+    using ::uint_least32_t;
+    using ::uint_least64_t;
 }
 
-using int8_t  = std::hel::int8_t;
-using int16_t = std::hel::int16_t;
-using int32_t = std::hel::int32_t;
-using int64_t = std::hel::int64_t;
-
-using intmax_t = std::hel::intmax_t;
-using intptr_t = std::hel::intptr_t;
-
-using int_fast8_t  = std::hel::int8_t;
-using int_fast16_t = std::hel::int16_t;
-using int_fast32_t = std::hel::int32_t;
-using int_fast64_t = std::hel::int64_t;
-
-using int_least8_t  = std::hel::int8_t;
-using int_least16_t = std::hel::int16_t;
-using int_least32_t = std::hel::int32_t;
-using int_least64_t = std::hel::int64_t;
-
-using uint8_t  = std::hel::uint8_t;
-using uint16_t = std::hel::uint16_t;
-using uint32_t = std::hel::uint32_t;
-using uint64_t = std::hel::uint64_t;
-
-using uintmax_t = std::hel::uintmax_t;
-using uintptr_t = std::hel::uintptr_t;
-
-using uint_fast8_t  = std::hel::uint8_t;
-using uint_fast16_t = std::hel::uint16_t;
-using uint_fast32_t = std::hel::uint32_t;
-using uint_fast64_t = std::hel::uint64_t;
-
-using uint_least8_t  = std::hel::uint8_t;
-using uint_least16_t = std::hel::uint16_t;
-using uint_least32_t = std::hel::uint32_t;
-using uint_least64_t = std::hel::uint64_t;
-
 #endif
Index: uspace/lib/cpp/include/cstdio
===================================================================
--- uspace/lib/cpp/include/cstdio	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/cstdio	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,116 +30,60 @@
 #define LIBCPP_CSTDIO
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <stdio.h>
-    }
-}
+#include <stdio.h>
 
 namespace std
 {
-    using std::hel::FILE;
-    using std::hel::stdin;
-    using std::hel::stdout;
-    using std::hel::stderr;
-    /* using std::hel::fpos_t */
-    using std::hel::size_t;
+    using ::FILE;
+    using ::stdin;
+    using ::stdout;
+    using ::stderr;
+    using ::fpos_t;
+    using ::size_t;
 
-    using std::hel::clearerr;
-    using std::hel::fclose;
-    using std::hel::feof;
-    using std::hel::ferror;
-    using std::hel::fflush;
-    using std::hel::fgetc;
-    /* using std::hel::fgetpos; */
-    using std::hel::fgets;
-    using std::hel::fopen;
-    using std::hel::fprintf;
-    using std::hel::fputc;
-    using std::hel::fputs;
-    using std::hel::fread;
-    using std::hel::freopen;
-    /* using std::hel::fscanf; */
-    using std::hel::fseek;
-    /* using std::hel::fsetpos; */
-    using std::hel::ftell;
-    using std::hel::fwrite;
-    /* using std::hel::getc; */
-    using std::hel::getchar;
-    /* using std::hel::perror; */
-    using std::hel::printf;
-    /* using std::hel::putc; */
-    using std::hel::putchar;
-    using std::hel::puts;
-    using std::hel::remove;
-    using std::hel::rename;
-    using std::hel::rewind;
-    /* using std::hel::scanf; */
-    using std::hel::setbuf;
-    using std::hel::setvbuf;
-    using std::hel::snprintf;
-    /* using std::hel::sprintf; */
-    /* using std::hel::sscanf; */
-    /* using std::hel::tmpfile; */
-    /* using std::hel::tmpnam; */
-    using std::hel::ungetc;
-    using std::hel::vfprintf;
-    using std::hel::vprintf;
-    /* using std::hel::vscanf; */
-    using std::hel::vsnprintf;
-    /* using std::hel::vsprintf; */
-    /* using std::hel::vsscanf; */
+    using ::clearerr;
+    using ::fclose;
+    using ::feof;
+    using ::ferror;
+    using ::fflush;
+    using ::fgetc;
+    using ::fgetpos;
+    using ::fgets;
+    using ::fopen;
+    using ::fprintf;
+    using ::fputc;
+    using ::fputs;
+    using ::fread;
+    using ::freopen;
+    using ::fscanf;
+    using ::fseek;
+    using ::fsetpos;
+    using ::ftell;
+    using ::fwrite;
+    using ::getc;
+    using ::getchar;
+    using ::perror;
+    using ::printf;
+    using ::putc;
+    using ::putchar;
+    using ::puts;
+    using ::remove;
+    using ::rename;
+    using ::rewind;
+    using ::scanf;
+    using ::setbuf;
+    using ::setvbuf;
+    using ::snprintf;
+    /* using ::sprintf; */
+    /* using ::sscanf; */
+    /* using ::tmpfile; */
+    /* using ::tmpnam; */
+    using ::ungetc;
+    using ::vfprintf;
+    using ::vprintf;
+    /* using ::vscanf; */
+    using ::vsnprintf;
+    /* using ::vsprintf; */
+    /* using ::vsscanf; */
 }
 
-using std::hel::FILE;
-/* using std::hel::fpos_t */
-using std::hel::size_t;
-
-using std::hel::clearerr;
-using std::hel::fclose;
-using std::hel::feof;
-using std::hel::ferror;
-using std::hel::fflush;
-using std::hel::fgetc;
-/* using std::hel::fgetpos; */
-using std::hel::fgets;
-using std::hel::fopen;
-using std::hel::fprintf;
-using std::hel::fputc;
-using std::hel::fputs;
-using std::hel::fread;
-using std::hel::freopen;
-/* using std::hel::fscanf; */
-using std::hel::fseek;
-/* using std::hel::fsetpos; */
-using std::hel::ftell;
-using std::hel::fwrite;
-/* using std::hel::getc; */
-using std::hel::getchar;
-/* using std::hel::perror; */
-using std::hel::printf;
-/* using std::hel::putc; */
-using std::hel::putchar;
-using std::hel::puts;
-using std::hel::remove;
-using std::hel::rename;
-using std::hel::rewind;
-/* using std::hel::scanf; */
-using std::hel::setbuf;
-using std::hel::setvbuf;
-using std::hel::snprintf;
-/* using std::hel::sprintf; */
-/* using std::hel::sscanf; */
-/* using std::hel::tmpfile; */
-/* using std::hel::tmpnam; */
-using std::hel::ungetc;
-using std::hel::vfprintf;
-using std::hel::vprintf;
-/* using std::hel::vscanf; */
-using std::hel::vsnprintf;
-/* using std::hel::vsprintf; */
-/* using std::hel::vsscanf; */
-
 #endif
Index: uspace/lib/cpp/include/cstdlib
===================================================================
--- uspace/lib/cpp/include/cstdlib	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/cstdlib	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,112 +30,57 @@
 #define LIBCPP_CSTDLIB
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <stdlib.h>
-        #include <_bits/ssize_t.h>
-    }
-}
+#include <stdlib.h>
+#include <_bits/ssize_t.h>
 
 namespace std
 {
-    /* using std::hel::div_t; */
-    /* using std::hel::ldiv_t; */
-    /* using std::hel::lldiv_t; */
-    using std::hel::size_t;
+    /* using ::div_t; */
+    /* using ::ldiv_t; */
+    /* using ::lldiv_t; */
+    using ::size_t;
 
-    using std::hel::abort;
-    using std::hel::exit;
-    /* using std::hel::quick_exit; */
-    /* using std::hel::_Exit; */
-    using std::hel::atexit;
-    /* using std::hel::at_quick_exit; */
-    /* using std::hel::system; */
-    /* using std::hel::getenv; */
+    using ::abort;
+    using ::exit;
+    /* using ::quick_exit; */
+    /* using ::_Exit; */
+    using ::atexit;
+    /* using ::at_quick_exit; */
+    /* using ::system; */
+    /* using ::getenv; */
 
-    using std::hel::malloc;
-    using std::hel::calloc;
-    using std::hel::realloc;
-    using std::hel::free;
+    using ::malloc;
+    using ::calloc;
+    using ::realloc;
+    using ::free;
 
-    /* using std::hel::atof; */
-    /* using std::hel::atoi; */
-    /* using std::hel::atol; */
-    /* using std::hel::atoll; */
-    /* using std::hel::strtol; */
-    /* using std::hel::strtoll; */
-    /* using std::hel::strtoul; */
-    /* using std::hel::strtoull; */
-    /* using std::hel::strtof; */
-    /* using std::hel::strtod; */
-    /* using std::hel::strtold; */
+    /* using ::atof; */
+    /* using ::atoi; */
+    /* using ::atol; */
+    /* using ::atoll; */
+    /* using ::strtol; */
+    /* using ::strtoll; */
+    /* using ::strtoul; */
+    /* using ::strtoull; */
+    /* using ::strtof; */
+    /* using ::strtod; */
+    /* using ::strtold; */
 
-    /* using std::hel::mblen; */
-    /* using std::hel::mbtowc; */
-    /* using std::hel::wctomb; */
-    /* using std::hel::mbstowcs; */
-    /* using std::hel::wcstombs; */
+    /* using ::mblen; */
+    /* using ::mbtowc; */
+    /* using ::wctomb; */
+    /* using ::mbstowcs; */
+    /* using ::wcstombs; */
 
-    using std::hel::rand;
-    using std::hel::srand;
-    using std::hel::qsort;
-    /* using std::hel::bsearch; */
-    /* using std::hel::abs; */
-    /* using std::hel::labs; */
-    /* using std::hel::llabs; */
-    /* using std::hel::div; */
-    /* using std::hel::ldiv; */
-    /* using std::hel::lldiv; */
+    using ::rand;
+    using ::srand;
+    using ::qsort;
+    /* using ::bsearch; */
+    /* using ::abs; */
+    /* using ::labs; */
+    /* using ::llabs; */
+    /* using ::div; */
+    /* using ::ldiv; */
+    /* using ::lldiv; */
 }
 
-/* using std::hel::div_t; */
-/* using std::hel::ldiv_t; */
-/* using std::hel::lldiv_t; */
-using std::hel::size_t;
-
-using std::hel::abort;
-using std::hel::exit;
-/* using std::hel::quick_exit; */
-/* using std::hel::_Exit; */
-using std::hel::atexit;
-/* using std::hel::at_quick_exit; */
-/* using std::hel::system; */
-/* using std::hel::getenv; */
-
-using std::hel::malloc;
-using std::hel::calloc;
-using std::hel::realloc;
-using std::hel::free;
-
-/* using std::hel::atof; */
-/* using std::hel::atoi; */
-/* using std::hel::atol; */
-/* using std::hel::atoll; */
-/* using std::hel::strtol; */
-/* using std::hel::strtoll; */
-/* using std::hel::strtoul; */
-/* using std::hel::strtoull; */
-/* using std::hel::strtof; */
-/* using std::hel::strtod; */
-/* using std::hel::strtold; */
-
-/* using std::hel::mblen; */
-/* using std::hel::mbtowc; */
-/* using std::hel::wctomb; */
-/* using std::hel::mbstowcs; */
-/* using std::hel::wcstombs; */
-
-using std::hel::rand;
-using std::hel::srand;
-using std::hel::qsort;
-/* using std::hel::bsearch; */
-/* using std::hel::abs; */
-/* using std::hel::labs; */
-/* using std::hel::llabs; */
-/* using std::hel::div; */
-/* using std::hel::ldiv; */
-/* using std::hel::lldiv; */
-
 #endif
Index: uspace/lib/cpp/include/cstring
===================================================================
--- uspace/lib/cpp/include/cstring	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/cstring	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,71 +30,37 @@
 #define LIBCPP_CSTRING
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <str.h>
-    }
-}
+#define _REALLY_WANT_STRING_H
+#include <string.h>
 
 namespace std
 {
-    using std::hel::size_t;
+    using ::size_t;
 
-    /* using std::hel::strcpy; */
-    /* using std::hel::strncpy; */
-    /* using std::hel::strcat; */
-    /* using std::hel::strncat; */
-    /* using std::hel::strxfrm; */
+    using ::strcpy;
+    using ::strncpy;
+    using ::strcat;
+    using ::strncat;
+    using ::strxfrm;
 
-    /* using std::hel::strlen; */
-    /* using std::hel::strcmp; */
-    /* using std::hel::strncmp; */
-    /* using std::hel::strcoll; */
-    /* using std::hel::strchr; */
-    /* using std::hel::strrchr; */
-    /* using std::hel::strspn; */
-    /* using std::hel::strcspn; */
-    /* using std::hel::strpbrk; */
-    /* using std::hel::strstr; */
-    /* using std::hel::strok; */
+    using ::strlen;
+    using ::strcmp;
+    using ::strncmp;
+    using ::strcoll;
+    using ::strchr;
+    using ::strrchr;
+    using ::strspn;
+    using ::strcspn;
+    using ::strpbrk;
+    using ::strstr;
+    using ::strtok;
 
-    /* using std::hel::memchr; */
-    using std::hel::memcmp;
-    using std::hel::memset;
-    using std::hel::memcpy;
-    using std::hel::memmove;
+    using ::memchr;
+    using ::memcmp;
+    using ::memset;
+    using ::memcpy;
+    using ::memmove;
 
-    /* using std::hel::strerror; */
+    using ::strerror;
 }
 
-using std::hel::size_t;
-
-/* using std::hel::strcpy; */
-/* using std::hel::strncpy; */
-/* using std::hel::strcat; */
-/* using std::hel::strncat; */
-/* using std::hel::strxfrm; */
-
-/* using std::hel::strlen; */
-/* using std::hel::strcmp; */
-/* using std::hel::strncmp; */
-/* using std::hel::strcoll; */
-/* using std::hel::strchr; */
-/* using std::hel::strrchr; */
-/* using std::hel::strspn; */
-/* using std::hel::strcspn; */
-/* using std::hel::strpbrk; */
-/* using std::hel::strstr; */
-/* using std::hel::strok; */
-
-/* using std::hel::memchr; */
-using std::hel::memcmp;
-using std::hel::memset;
-using std::hel::memcpy;
-using std::hel::memmove;
-
-/* using std::hel::strerror; */
-
 #endif
Index: uspace/lib/cpp/include/ctime
===================================================================
--- uspace/lib/cpp/include/ctime	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/ctime	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,51 +30,26 @@
 #define LIBCPP_CTIME
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <time.h>
-    }
-}
+#include <time.h>
 
 namespace std
 {
-    /* using std::hel::clock_t; */
-    using std::hel::size_t;
-    using std::hel::time_t;
-    using std::hel::tm;
-    /* using std::hel::timespec; */
+    using ::clock_t;
+    using ::size_t;
+    using ::time_t;
+    using ::tm;
+    using ::timespec;
 
-    /* using std::hel::clock; */
-    using std::hel::time;
-    using std::hel::difftime;
+    using ::clock;
+    using ::time;
+    using ::difftime;
 
-    /* using std::hel::ctime; */
-    /* using std::hel::asctime; */
-    using std::hel::strftime;
-    /* using std::hel::wcsftime; */
-    /* using std::hel::gmtime; */
-    /* using std::hel::localtime; */
-    using std::hel::mktime;
+    using ::ctime;
+    using ::asctime;
+    using ::strftime;
+    /* using ::wcsftime; */
+    /* using ::gmtime; */
+    /* using ::localtime; */
+    using ::mktime;
 }
 
-/* using std::hel::clock_t; */
-using std::hel::size_t;
-using std::hel::time_t;
-using std::hel::tm;
-/* using std::hel::timespec; */
-
-/* using std::hel::clock; */
-using std::hel::time;
-using std::hel::difftime;
-
-/* using std::hel::ctime; */
-/* using std::hel::asctime; */
-using std::hel::strftime;
-/* using std::hel::wcsftime; */
-/* using std::hel::gmtime; */
-/* using std::hel::localtime; */
-using std::hel::mktime;
-
 #endif
Index: uspace/lib/cpp/include/cwchar
===================================================================
--- uspace/lib/cpp/include/cwchar	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/cwchar	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,150 +30,76 @@
 #define LIBCPP_WCHAR
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <wchar.h>
-        #include <time.h>
-    }
-}
+#include <wchar.h>
+#include <time.h>
 
 namespace std
 {
-    /* using std::hel::mbstate_t; */
-    using std::hel::size_t;
-    using std::hel::wint_t;
-    using std::hel::tm;
+    /* using ::mbstate_t; */
+    using ::size_t;
+    using ::wint_t;
+    using ::tm;
 
-    /* using std::hel::wcscpy; */
-    /* using std::hel::wcsncpy; */
-    /* using std::hel::wcscat; */
-    /* using std::hel::wcsncat; */
-    /* using std::hel::wcsnxfrm; */
+    /* using ::wcscpy; */
+    /* using ::wcsncpy; */
+    /* using ::wcscat; */
+    /* using ::wcsncat; */
+    /* using ::wcsnxfrm; */
 
-    /* using std::hel::wcslen; */
-    /* using std::hel::wcscmp; */
-    /* using std::hel::wcsncmp; */
-    /* using std::hel::wcscoll; */
-    /* using std::hel::wcschr; */
-    /* using std::hel::wcsrchr; */
-    /* using std::hel::wcsspn; */
-    /* using std::hel::wcscspn; */
-    /* using std::hel::wcspbrk; */
-    /* using std::hel::wcsstr; */
-    /* using std::hel::wcstok; */
+    /* using ::wcslen; */
+    /* using ::wcscmp; */
+    /* using ::wcsncmp; */
+    /* using ::wcscoll; */
+    /* using ::wcschr; */
+    /* using ::wcsrchr; */
+    /* using ::wcsspn; */
+    /* using ::wcscspn; */
+    /* using ::wcspbrk; */
+    /* using ::wcsstr; */
+    /* using ::wcstok; */
 
-    /* using std::hel::wmemcpy; */
-    /* using std::hel::wmemmove; */
-    /* using std::hel::wmemcmp; */
-    /* using std::hel::wmemchr; */
-    /* using std::hel::wmemset; */
+    /* using ::wmemcpy; */
+    /* using ::wmemmove; */
+    /* using ::wmemcmp; */
+    /* using ::wmemchr; */
+    /* using ::wmemset; */
 
-    /* using std::hel::msbinit; */
-    /* using std::hel::btowc; */
-    /* using std::hel::wctob; */
-    /* using std::hel::mbrlen; */
-    /* using std::hel::mbrtowc; */
-    /* using std::hel::wctomb; */
-    /* using std::hel::mbsrtowcs; */
-    /* using std::hel::wcsrtombs; */
+    /* using ::msbinit; */
+    /* using ::btowc; */
+    /* using ::wctob; */
+    /* using ::mbrlen; */
+    /* using ::mbrtowc; */
+    /* using ::wctomb; */
+    /* using ::mbsrtowcs; */
+    /* using ::wcsrtombs; */
 
-    /* using std::hel::fgetwc; */
-    /* using std::hel::getwc; */
-    /* using std::hel::fgetws; */
-    /* using std::hel::fputwc; */
-    /* using std::hel::putwc; */
-    /* using std::hel::fputws; */
-    /* using std::hel::getwchar; */
-    /* using std::hel::putwchar; */
-    /* using std::hel::ungetwc; */
-    /* using std::hel::fwide; */
-    /* using std::hel::wscanf; */
-    /* using std::hel::fwscanf; */
-    /* using std::hel::swscanf; */
-    /* using std::hel::vwscanf; */
-    /* using std::hel::vfwscanf; */
-    /* using std::hel::vswscanf; */
-    /* using std::hel::wprintf; */
-    /* using std::hel::fwprintf; */
-    /* using std::hel::swprintf; */
+    /* using ::fgetwc; */
+    /* using ::getwc; */
+    /* using ::fgetws; */
+    /* using ::fputwc; */
+    /* using ::putwc; */
+    /* using ::fputws; */
+    /* using ::getwchar; */
+    /* using ::putwchar; */
+    /* using ::ungetwc; */
+    /* using ::fwide; */
+    /* using ::wscanf; */
+    /* using ::fwscanf; */
+    /* using ::swscanf; */
+    /* using ::vwscanf; */
+    /* using ::vfwscanf; */
+    /* using ::vswscanf; */
+    /* using ::wprintf; */
+    /* using ::fwprintf; */
+    /* using ::swprintf; */
 
-    /* using std::hel::wcsftime; */
-    /* using std::hel::wcstol; */
-    /* using std::hel::wcstoll; */
-    /* using std::hel::wcstoul; */
-    /* using std::hel::wcstoull; */
-    /* using std::hel::wcstof; */
-    /* using std::hel::wcstod; */
-    /* using std::hel::wcstold; */
+    /* using ::wcsftime; */
+    /* using ::wcstol; */
+    /* using ::wcstoll; */
+    /* using ::wcstoul; */
+    /* using ::wcstoull; */
+    /* using ::wcstof; */
+    /* using ::wcstod; */
+    /* using ::wcstold; */
 }
 
-/* using std::hel::mbstate_t; */
-using std::hel::size_t;
-using std::hel::wint_t;
-using std::hel::tm;
-
-/* using std::hel::wcscpy; */
-/* using std::hel::wcsncpy; */
-/* using std::hel::wcscat; */
-/* using std::hel::wcsncat; */
-/* using std::hel::wcsnxfrm; */
-
-/* using std::hel::wcslen; */
-/* using std::hel::wcscmp; */
-/* using std::hel::wcsncmp; */
-/* using std::hel::wcscoll; */
-/* using std::hel::wcschr; */
-/* using std::hel::wcsrchr; */
-/* using std::hel::wcsspn; */
-/* using std::hel::wcscspn; */
-/* using std::hel::wcspbrk; */
-/* using std::hel::wcsstr; */
-/* using std::hel::wcstok; */
-
-/* using std::hel::wmemcpy; */
-/* using std::hel::wmemmove; */
-/* using std::hel::wmemcmp; */
-/* using std::hel::wmemchr; */
-/* using std::hel::wmemset; */
-
-/* using std::hel::msbinit; */
-/* using std::hel::btowc; */
-/* using std::hel::wctob; */
-/* using std::hel::mbrlen; */
-/* using std::hel::mbrtowc; */
-/* using std::hel::wctomb; */
-/* using std::hel::mbsrtowcs; */
-/* using std::hel::wcsrtombs; */
-
-/* using std::hel::fgetwc; */
-/* using std::hel::getwc; */
-/* using std::hel::fgetws; */
-/* using std::hel::fputwc; */
-/* using std::hel::putwc; */
-/* using std::hel::fputws; */
-/* using std::hel::getwchar; */
-/* using std::hel::putwchar; */
-/* using std::hel::ungetwc; */
-/* using std::hel::fwide; */
-/* using std::hel::wscanf; */
-/* using std::hel::fwscanf; */
-/* using std::hel::swscanf; */
-/* using std::hel::vwscanf; */
-/* using std::hel::vfwscanf; */
-/* using std::hel::vswscanf; */
-/* using std::hel::wprintf; */
-/* using std::hel::fwprintf; */
-/* using std::hel::swprintf; */
-
-/* using std::hel::wcsftime; */
-/* using std::hel::wcstol; */
-/* using std::hel::wcstoll; */
-/* using std::hel::wcstoul; */
-/* using std::hel::wcstoull; */
-/* using std::hel::wcstof; */
-/* using std::hel::wcstod; */
-/* using std::hel::wcstold; */
-
 #endif
Index: uspace/lib/cpp/src/__bits/runtime.cpp
===================================================================
--- uspace/lib/cpp/src/__bits/runtime.cpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/src/__bits/runtime.cpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,4 +33,6 @@
 #include <mutex>
 
+void* __dso_handle = nullptr;
+
 namespace __cxxabiv1
 {
Index: uspace/lib/cpp/src/__bits/unwind.cpp
===================================================================
--- uspace/lib/cpp/src/__bits/unwind.cpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/src/__bits/unwind.cpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,4 +27,5 @@
  */
 
+#include <cassert>
 #include <cstdint>
 #include <cstdlib>
@@ -175,4 +176,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return nullptr;
     }
@@ -181,4 +183,5 @@
     {
         // TODO: implement
+        __unimplemented();
     }
 
@@ -186,4 +189,5 @@
     {
         // TODO: implement
+        __unimplemented();
     }
 
@@ -191,4 +195,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return nullptr;
     }
@@ -197,4 +202,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return nullptr;
     }
@@ -203,4 +209,5 @@
     {
         // TODO: implement
+        __unimplemented();
     }
 
@@ -208,4 +215,5 @@
     {
         // TODO: implement
+        __unimplemented();
     }
 
@@ -213,4 +221,5 @@
     {
         // TODO: implement
+        __unimplemented();
     }
 
@@ -218,4 +227,5 @@
     {
         // TODO: implement
+        __unimplemented();
     }
 
@@ -223,4 +233,5 @@
     {
         // TODO: implement
+        __unimplemented();
     }
 
@@ -231,4 +242,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return _URC_NO_REASON;
     }
Index: uspace/lib/cpp/src/condition_variable.cpp
===================================================================
--- uspace/lib/cpp/src/condition_variable.cpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/src/condition_variable.cpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,4 +27,5 @@
  */
 
+#include <cassert>
 #include <condition_variable>
 
@@ -88,4 +89,5 @@
     {
         // TODO: implement
+        __unimplemented();
     }
 }
Index: uspace/lib/cpp/src/stdexcept.cpp
===================================================================
--- uspace/lib/cpp/src/stdexcept.cpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/src/stdexcept.cpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,17 +31,18 @@
 #include <stdexcept>
 #include <string>
+#include <str.h>
 
 namespace std
 {
     logic_error::logic_error(const string& what)
-        : what_{hel::str_dup(what.c_str())}
+        : what_{::helenos::str_dup(what.c_str())}
     { /* DUMMY BODY */ }
 
     logic_error::logic_error(const char* what)
-        : what_{hel::str_dup(what)}
+        : what_{::helenos::str_dup(what)}
     { /* DUMMY BODY */ }
 
     logic_error::logic_error(const logic_error& other) noexcept
-        : exception{other}, what_{hel::str_dup(other.what_)}
+        : exception{other}, what_{::helenos::str_dup(other.what_)}
     { /* DUMMY BODY */ }
 
@@ -50,5 +51,5 @@
         if (what_)
             free(what_);
-        what_ = hel::str_dup(other.what_);
+        what_ = ::helenos::str_dup(other.what_);
 
         return *this;
@@ -114,13 +115,13 @@
 
     runtime_error::runtime_error(const string& what)
-        : what_{hel::str_dup(what.c_str())}
+        : what_{::helenos::str_dup(what.c_str())}
     { /* DUMMY BODY */ }
 
     runtime_error::runtime_error(const char* what)
-        : what_{hel::str_dup(what)}
+        : what_{::helenos::str_dup(what)}
     { /* DUMMY BODY */ }
 
     runtime_error::runtime_error(const runtime_error& other) noexcept
-        : exception{other}, what_{hel::str_dup(other.what_)}
+        : exception{other}, what_{::helenos::str_dup(other.what_)}
     { /* DUMMY BODY */ }
 
@@ -129,5 +130,5 @@
         if (what_)
             free(what_);
-        what_ = hel::str_dup(other.what_);
+        what_ = ::helenos::str_dup(other.what_);
 
         return *this;
Index: uspace/lib/cpp/src/string.cpp
===================================================================
--- uspace/lib/cpp/src/string.cpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/src/string.cpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,4 +27,5 @@
  */
 
+#include <cassert>
 #include <string>
 
@@ -34,4 +35,5 @@
     {
         // TODO: implement using stol once we have numeric limits
+        __unimplemented();
         return 0;
     }
@@ -40,5 +42,5 @@
     {
         char* end;
-        long result = hel::strtol(str.c_str(), &end, base);
+        long result = ::strtol(str.c_str(), &end, base);
 
         if (end != str.c_str())
@@ -56,5 +58,5 @@
     {
         char* end;
-        unsigned long result = hel::strtoul(str.c_str(), &end, base);
+        unsigned long result = ::strtoul(str.c_str(), &end, base);
 
         if (end != str.c_str())
@@ -72,4 +74,5 @@
     {
         // TODO: implement using stol once we have numeric limits
+        __unimplemented();
         return 0;
     }
@@ -78,4 +81,5 @@
     {
         // TODO: implement using stoul once we have numeric limits
+        __unimplemented();
         return 0;
     }
@@ -84,4 +88,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return 0.f;
     }
@@ -90,4 +95,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return 0.0;
     }
@@ -96,16 +102,12 @@
     {
         // TODO: implement
+        __unimplemented();
         return 0.0l;
     }
 
-    namespace hel
-    {
-        extern "C" int asprintf(char**, const char*, ...);
-    }
-
     string to_string(int val)
     {
         char* tmp;
-        hel::asprintf(&tmp, "%d", val);
+        ::asprintf(&tmp, "%d", val);
 
         std::string res{tmp};
@@ -118,5 +120,5 @@
     {
         char* tmp;
-        hel::asprintf(&tmp, "%u", val);
+        ::asprintf(&tmp, "%u", val);
 
         std::string res{tmp};
@@ -129,5 +131,5 @@
     {
         char* tmp;
-        hel::asprintf(&tmp, "%ld", val);
+        ::asprintf(&tmp, "%ld", val);
 
         std::string res{tmp};
@@ -140,5 +142,5 @@
     {
         char* tmp;
-        hel::asprintf(&tmp, "%lu", val);
+        ::asprintf(&tmp, "%lu", val);
 
         std::string res{tmp};
@@ -151,5 +153,5 @@
     {
         char* tmp;
-        hel::asprintf(&tmp, "%lld", val);
+        ::asprintf(&tmp, "%lld", val);
 
         std::string res{tmp};
@@ -162,5 +164,5 @@
     {
         char* tmp;
-        hel::asprintf(&tmp, "%llu", val);
+        ::asprintf(&tmp, "%llu", val);
 
         std::string res{tmp};
@@ -173,5 +175,5 @@
     {
         char* tmp;
-        hel::asprintf(&tmp, "%f", val);
+        ::asprintf(&tmp, "%f", val);
 
         std::string res{tmp};
@@ -184,5 +186,5 @@
     {
         char* tmp;
-        hel::asprintf(&tmp, "%f", val);
+        ::asprintf(&tmp, "%f", val);
 
         std::string res{tmp};
@@ -195,5 +197,5 @@
     {
         char* tmp;
-        hel::asprintf(&tmp, "%Lf", val);
+        ::asprintf(&tmp, "%Lf", val);
 
         std::string res{tmp};
@@ -206,4 +208,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return 0;
     }
@@ -212,4 +215,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return 0;
     }
@@ -218,4 +222,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return 0;
     }
@@ -224,4 +229,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return 0;
     }
@@ -230,4 +236,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return 0;
     }
@@ -236,4 +243,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return 0.f;
     }
@@ -242,4 +250,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return 0.0;
     }
@@ -248,4 +257,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return 0.0l;
     }
@@ -254,4 +264,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return wstring{};
     }
@@ -260,4 +271,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return wstring{};
     }
@@ -266,4 +278,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return wstring{};
     }
@@ -272,4 +285,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return wstring{};
     }
@@ -278,4 +292,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return wstring{};
     }
@@ -284,4 +299,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return wstring{};
     }
@@ -290,4 +306,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return wstring{};
     }
@@ -296,4 +313,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return wstring{};
     }
@@ -302,4 +320,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return wstring{};
     }
Index: uspace/lib/cpp/src/thread.cpp
===================================================================
--- uspace/lib/cpp/src/thread.cpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/src/thread.cpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,4 +27,5 @@
  */
 
+#include <cassert>
 #include <cstdlib>
 #include <exception>
@@ -120,4 +121,5 @@
     {
         // TODO:
+        __unimplemented();
         return 0;
     }
Index: uspace/lib/cpp/src/typeinfo.cpp
===================================================================
--- uspace/lib/cpp/src/typeinfo.cpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/src/typeinfo.cpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,6 +38,5 @@
     bool type_info::operator==(const type_info& other) const noexcept
     {
-        return (this == &other) ||
-               std::hel::str_cmp(name(), other.name());
+        return (this == &other) || ::strcmp(name(), other.name()) == 0;
     }
 
Index: uspace/lib/dltest/dltest.c
===================================================================
--- uspace/lib/dltest/dltest.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/dltest/dltest.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -60,4 +60,14 @@
 {
 	return dl_constant;
+}
+
+/** Return constant value by calling another function.
+ *
+ * This can be used to test dynamically linked call (via PLT) even in case
+ * binaries are statically linked.
+ */
+int dl_get_constant_via_call(void)
+{
+	return dl_get_constant();
 }
 
Index: uspace/lib/dltest/libdltest.h
===================================================================
--- uspace/lib/dltest/libdltest.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/dltest/libdltest.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -47,4 +47,5 @@
 
 extern int dl_get_constant(void);
+extern int dl_get_constant_via_call(void);
 extern int dl_get_private_var(void);
 extern int *dl_get_private_var_addr(void);
Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/drv/generic/driver.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -119,6 +119,6 @@
 static void driver_dev_add(ipc_call_t *icall)
 {
-	devman_handle_t dev_handle = IPC_GET_ARG1(*icall);
-	devman_handle_t parent_fun_handle = IPC_GET_ARG2(*icall);
+	devman_handle_t dev_handle = ipc_get_arg1(icall);
+	devman_handle_t parent_fun_handle = ipc_get_arg2(icall);
 
 	char *dev_name = NULL;
@@ -173,5 +173,5 @@
 static void driver_dev_remove(ipc_call_t *icall)
 {
-	devman_handle_t devh = IPC_GET_ARG1(*icall);
+	devman_handle_t devh = ipc_get_arg1(icall);
 
 	fibril_mutex_lock(&devices_mutex);
@@ -206,5 +206,5 @@
 static void driver_dev_gone(ipc_call_t *icall)
 {
-	devman_handle_t devh = IPC_GET_ARG1(*icall);
+	devman_handle_t devh = ipc_get_arg1(icall);
 
 	fibril_mutex_lock(&devices_mutex);
@@ -239,5 +239,5 @@
 static void driver_fun_online(ipc_call_t *icall)
 {
-	devman_handle_t funh = IPC_GET_ARG1(*icall);
+	devman_handle_t funh = ipc_get_arg1(icall);
 
 	/*
@@ -274,5 +274,5 @@
 static void driver_fun_offline(ipc_call_t *icall)
 {
-	devman_handle_t funh = IPC_GET_ARG1(*icall);
+	devman_handle_t funh = ipc_get_arg1(icall);
 
 	/*
@@ -343,10 +343,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case DRIVER_DEV_ADD:
 			driver_dev_add(&call);
@@ -385,5 +385,5 @@
 	 * the device to which the client connected.
 	 */
-	devman_handle_t handle = IPC_GET_ARG2(*icall);
+	devman_handle_t handle = ipc_get_arg2(icall);
 
 	fibril_mutex_lock(&functions_mutex);
@@ -429,5 +429,5 @@
 		async_get_call(&call);
 
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
@@ -483,5 +483,5 @@
 
 		/* get the method of the remote interface */
-		sysarg_t iface_method_idx = IPC_GET_ARG1(call);
+		sysarg_t iface_method_idx = ipc_get_arg1(&call);
 		remote_iface_func_ptr_t iface_method_ptr =
 		    get_remote_method(rem_iface, iface_method_idx);
@@ -526,4 +526,6 @@
 		return NULL;
 
+	refcount_init(&dev->refcnt);
+
 	return dev;
 }
@@ -541,4 +543,5 @@
 		return NULL;
 
+	refcount_init(&fun->refcnt);
 	init_match_ids(&fun->match_ids);
 	link_initialize(&fun->link);
Index: uspace/lib/drv/generic/remote_audio_pcm.c
===================================================================
--- uspace/lib/drv/generic/remote_audio_pcm.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/drv/generic/remote_audio_pcm.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -142,9 +142,9 @@
 audio_pcm_sess_t *audio_pcm_open(const char *name)
 {
-	devman_handle_t device_handle = 0;
-	const errno_t ret = devman_fun_get_handle(name, &device_handle, 0);
+	service_id_t sid;
+	const errno_t ret = loc_service_get_id(name, &sid, 0);
 	if (ret != EOK)
 		return NULL;
-	return devman_device_connect(device_handle, IPC_FLAG_BLOCKING);
+	return loc_service_connect(sid, INTERFACE_DDF, 0);
 }
 
Index: uspace/lib/drv/generic/remote_ieee80211.c
===================================================================
--- uspace/lib/drv/generic/remote_ieee80211.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/drv/generic/remote_ieee80211.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -276,5 +276,5 @@
 	memset(&scan_results, 0, sizeof(ieee80211_scan_results_t));
 
-	bool now = IPC_GET_ARG2(*call);
+	bool now = ipc_get_arg2(call);
 
 	errno_t rc = ieee80211_iface->get_scan_results(fun, &scan_results, now);
Index: uspace/lib/drv/generic/remote_nic.c
===================================================================
--- uspace/lib/drv/generic/remote_nic.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/drv/generic/remote_nic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1010,5 +1010,5 @@
 	async_wait_for(message_id, &res);
 
-	*id = IPC_GET_ARG1(result);
+	*id = ipc_get_arg1(&result);
 	return res;
 }
@@ -1385,5 +1385,5 @@
 	assert(nic_iface->set_state);
 
-	nic_device_state_t state = (nic_device_state_t) IPC_GET_ARG2(*call);
+	nic_device_state_t state = (nic_device_state_t) ipc_get_arg2(call);
 
 	errno_t rc = nic_iface->set_state(dev, state);
@@ -1569,7 +1569,7 @@
 	}
 
-	int speed = (int) IPC_GET_ARG2(*call);
-	nic_channel_mode_t duplex = (nic_channel_mode_t) IPC_GET_ARG3(*call);
-	nic_role_t role = (nic_role_t) IPC_GET_ARG4(*call);
+	int speed = (int) ipc_get_arg2(call);
+	nic_channel_mode_t duplex = (nic_channel_mode_t) ipc_get_arg3(call);
+	nic_role_t role = (nic_role_t) ipc_get_arg4(call);
 
 	errno_t rc = nic_iface->set_operation_mode(dev, speed, duplex, role);
@@ -1586,5 +1586,5 @@
 	}
 
-	uint32_t advertisement = (uint32_t) IPC_GET_ARG2(*call);
+	uint32_t advertisement = (uint32_t) ipc_get_arg2(call);
 
 	errno_t rc = nic_iface->autoneg_enable(dev, advertisement);
@@ -1664,7 +1664,7 @@
 	}
 
-	int allow_send = (int) IPC_GET_ARG2(*call);
-	int allow_receive = (int) IPC_GET_ARG3(*call);
-	uint16_t pause = (uint16_t) IPC_GET_ARG4(*call);
+	int allow_send = (int) ipc_get_arg2(call);
+	int allow_receive = (int) ipc_get_arg3(call);
+	uint16_t pause = (uint16_t) ipc_get_arg4(call);
 
 	errno_t rc = nic_iface->set_pause(dev, allow_send, allow_receive,
@@ -1682,5 +1682,5 @@
 	}
 
-	size_t max_count = IPC_GET_ARG2(*call);
+	size_t max_count = ipc_get_arg2(call);
 	nic_address_t *address_list = NULL;
 
@@ -1733,6 +1733,6 @@
 
 	size_t length;
-	nic_unicast_mode_t mode = IPC_GET_ARG2(*call);
-	size_t address_count = IPC_GET_ARG3(*call);
+	nic_unicast_mode_t mode = ipc_get_arg2(call);
+	size_t address_count = ipc_get_arg3(call);
 	nic_address_t *address_list = NULL;
 
@@ -1785,5 +1785,5 @@
 	}
 
-	size_t max_count = IPC_GET_ARG2(*call);
+	size_t max_count = ipc_get_arg2(call);
 	nic_address_t *address_list = NULL;
 
@@ -1835,6 +1835,6 @@
 	nic_iface_t *nic_iface = (nic_iface_t *) iface;
 
-	nic_multicast_mode_t mode = IPC_GET_ARG2(*call);
-	size_t address_count = IPC_GET_ARG3(*call);
+	nic_multicast_mode_t mode = ipc_get_arg2(call);
+	size_t address_count = ipc_get_arg3(call);
 	nic_address_t *address_list = NULL;
 
@@ -1903,5 +1903,5 @@
 	}
 
-	nic_broadcast_mode_t mode = IPC_GET_ARG2(*call);
+	nic_broadcast_mode_t mode = ipc_get_arg2(call);
 
 	errno_t rc = nic_iface->broadcast_set_mode(dev, mode);
@@ -1933,5 +1933,5 @@
 	}
 
-	uint32_t mode = IPC_GET_ARG2(*call);
+	uint32_t mode = ipc_get_arg2(call);
 
 	errno_t rc = nic_iface->defective_set_mode(dev, mode);
@@ -1948,5 +1948,5 @@
 	}
 
-	size_t max_count = IPC_GET_ARG2(*call);
+	size_t max_count = ipc_get_arg2(call);
 	nic_address_t *address_list = NULL;
 
@@ -1998,5 +1998,5 @@
 
 	size_t length;
-	size_t address_count = IPC_GET_ARG2(*call);
+	size_t address_count = ipc_get_arg2(call);
 	nic_address_t *address_list = NULL;
 
@@ -2081,5 +2081,5 @@
 	nic_vlan_mask_t vlan_mask;
 	nic_vlan_mask_t *vlan_mask_pointer = NULL;
-	bool vlan_mask_set = (bool) IPC_GET_ARG2(*call);
+	bool vlan_mask_set = (bool) ipc_get_arg2(call);
 
 	if (vlan_mask_set) {
@@ -2124,7 +2124,7 @@
 	}
 
-	uint16_t tag = (uint16_t) IPC_GET_ARG2(*call);
-	bool add = (int) IPC_GET_ARG3(*call);
-	bool strip = (int) IPC_GET_ARG4(*call);
+	uint16_t tag = (uint16_t) ipc_get_arg2(call);
+	bool add = (int) ipc_get_arg3(call);
+	bool strip = (int) ipc_get_arg4(call);
 
 	errno_t rc = nic_iface->vlan_set_tag(dev, tag, add, strip);
@@ -2137,5 +2137,5 @@
 	nic_iface_t *nic_iface = (nic_iface_t *) iface;
 
-	int send_data = (int) IPC_GET_ARG3(*call);
+	int send_data = (int) ipc_get_arg3(call);
 	ipc_call_t data;
 
@@ -2175,5 +2175,5 @@
 
 	nic_wv_id_t id = 0;
-	nic_wv_type_t type = (nic_wv_type_t) IPC_GET_ARG2(*call);
+	nic_wv_type_t type = (nic_wv_type_t) ipc_get_arg2(call);
 
 	errno_t rc = nic_iface->wol_virtue_add(dev, type, virtue, length, &id);
@@ -2192,5 +2192,5 @@
 	}
 
-	nic_wv_id_t id = (nic_wv_id_t) IPC_GET_ARG2(*call);
+	nic_wv_id_t id = (nic_wv_id_t) ipc_get_arg2(call);
 
 	errno_t rc = nic_iface->wol_virtue_remove(dev, id);
@@ -2208,6 +2208,6 @@
 	}
 
-	nic_wv_id_t id = (nic_wv_id_t) IPC_GET_ARG2(*call);
-	size_t max_length = IPC_GET_ARG3(*call);
+	nic_wv_id_t id = (nic_wv_id_t) ipc_get_arg2(call);
+	size_t max_length = ipc_get_arg3(call);
 	nic_wv_type_t type = NIC_WV_NONE;
 	size_t length = 0;
@@ -2259,6 +2259,6 @@
 	}
 
-	nic_wv_type_t type = (nic_wv_type_t) IPC_GET_ARG2(*call);
-	size_t max_count = IPC_GET_ARG3(*call);
+	nic_wv_type_t type = (nic_wv_type_t) ipc_get_arg2(call);
+	size_t max_count = ipc_get_arg3(call);
 	size_t count = 0;
 	nic_wv_id_t *id_list = NULL;
@@ -2310,5 +2310,5 @@
 
 	int count = -1;
-	nic_wv_type_t type = (nic_wv_type_t) IPC_GET_ARG2(*call);
+	nic_wv_type_t type = (nic_wv_type_t) ipc_get_arg2(call);
 
 	errno_t rc = nic_iface->wol_virtue_get_caps(dev, type, &count);
@@ -2325,5 +2325,5 @@
 	}
 
-	size_t max_length = (size_t) IPC_GET_ARG2(*call);
+	size_t max_length = (size_t) ipc_get_arg2(call);
 	size_t frame_length = 0;
 	nic_wv_type_t type = NIC_WV_NONE;
@@ -2386,6 +2386,6 @@
 	}
 
-	uint32_t mask = (uint32_t) IPC_GET_ARG2(*call);
-	uint32_t active = (uint32_t) IPC_GET_ARG3(*call);
+	uint32_t mask = (uint32_t) ipc_get_arg2(call);
+	uint32_t active = (uint32_t) ipc_get_arg3(call);
 
 	errno_t rc = nic_iface->offload_set(dev, mask, active);
@@ -2403,5 +2403,5 @@
 
 	nic_poll_mode_t mode = NIC_POLL_IMMEDIATE;
-	int request_data = IPC_GET_ARG2(*call);
+	int request_data = ipc_get_arg2(call);
 	struct timespec period = {
 		.tv_sec = 0,
@@ -2438,6 +2438,6 @@
 	nic_iface_t *nic_iface = (nic_iface_t *) iface;
 
-	nic_poll_mode_t mode = IPC_GET_ARG2(*call);
-	int has_period = IPC_GET_ARG3(*call);
+	nic_poll_mode_t mode = ipc_get_arg2(call);
+	int has_period = ipc_get_arg3(call);
 	struct timespec period_buf;
 	struct timespec *period = NULL;
Index: uspace/lib/drv/generic/remote_usbhc.c
===================================================================
--- uspace/lib/drv/generic/remote_usbhc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/drv/generic/remote_usbhc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -221,5 +221,5 @@
 
 	if (transferred)
-		*transferred = IPC_GET_ARG1(call);
+		*transferred = ipc_get_arg1(&call);
 
 	return (errno_t) opening_request_rc;
@@ -265,5 +265,5 @@
 	}
 
-	const bool reserve = IPC_GET_ARG2(*call);
+	const bool reserve = ipc_get_arg2(call);
 	const errno_t ret = usbhc_iface->default_address_reservation(fun, reserve);
 	async_answer_0(call, ret);
Index: uspace/lib/drv/generic/remote_usbhid.c
===================================================================
--- uspace/lib/drv/generic/remote_usbhid.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/drv/generic/remote_usbhid.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -190,5 +190,5 @@
 		return (errno_t) opening_request_rc;
 
-	size_t act_size = IPC_GET_ARG2(data_request_call);
+	size_t act_size = ipc_get_arg2(&data_request_call);
 
 	/* Copy the individual items. */
@@ -199,5 +199,5 @@
 
 	if (event_nr != NULL)
-		*event_nr = IPC_GET_ARG1(opening_request_call);
+		*event_nr = ipc_get_arg1(&opening_request_call);
 
 	return EOK;
@@ -275,5 +275,5 @@
 		return (errno_t) opening_request_rc;
 
-	size_t act_size = IPC_GET_ARG2(data_request_call);
+	size_t act_size = ipc_get_arg2(&data_request_call);
 
 	if (actual_size != NULL)
Index: uspace/lib/ext4/include/ext4/cfg.h
===================================================================
--- uspace/lib/ext4/include/ext4/cfg.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/ext4/include/ext4/cfg.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -53,4 +53,6 @@
 	/** Volume name encoded as UTF-8 string */
 	const char *volume_name;
+	/** Filesystem block size */
+	size_t bsize;
 } ext4_cfg_t;
 
Index: uspace/lib/ext4/include/ext4/superblock.h
===================================================================
--- uspace/lib/ext4/include/ext4/superblock.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/ext4/include/ext4/superblock.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -147,4 +147,5 @@
 extern void ext4_superblock_set_reserved_gdt_blocks(ext4_superblock_t *sb,
     uint32_t n);
+extern uint32_t ext4_superblock_get_flex_group_size(ext4_superblock_t *sb);
 
 /* More complex superblock functions */
Index: uspace/lib/ext4/src/balloc.c
===================================================================
--- uspace/lib/ext4/src/balloc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/ext4/src/balloc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -261,32 +261,28 @@
 		 * is always after the inode table.
 		 */
+		return itable + itable_sz;
+	}
+
+	uint32_t flex_group_size = ext4_superblock_get_flex_group_size(sb);
+	if ((bg_ref->index % flex_group_size) == 0) {
+		/* This is the base group */
+		uint32_t i;
+
 		r = itable + itable_sz;
-		return ext4_filesystem_blockaddr2_index_in_group(sb, r);
-	}
-
-	uint64_t bbmap = ext4_block_group_get_block_bitmap(bg_ref->block_group,
-	    sb);
-	uint64_t ibmap = ext4_block_group_get_inode_bitmap(bg_ref->block_group,
-	    sb);
-
-	r = ext4_filesystem_index_in_group2blockaddr(sb, 0, bg_ref->index);
-	r += ext4_filesystem_bg_get_backup_blocks(bg_ref);
-
-	if (ext4_filesystem_blockaddr2group(sb, bbmap) != bg_ref->index)
-		bbmap = -1; /* Invalid */
-
-	if (ext4_filesystem_blockaddr2group(sb, ibmap) != bg_ref->index)
-		ibmap = -1;
-
-	while (true) {
-		if (r == bbmap || r == ibmap)
-			r++;
-		else if (r >= itable && r < (itable + itable_sz))
-			r = itable + itable_sz;
-		else
-			break;
-	}
-
-	return r;
+
+		uint32_t total_groups = ext4_superblock_get_block_group_count(sb);
+		for (i = bg_ref->index + 1;
+		    i < min(total_groups, bg_ref->index + flex_group_size); ++i) {
+			r += ext4_filesystem_bg_get_itable_size(sb, i);
+		}
+
+		return r;
+	}
+
+	uint64_t base_addr = ext4_filesystem_index_in_group2blockaddr(sb, 0,
+	    bg_ref->index);
+	uint32_t reserved = ext4_filesystem_bg_get_backup_blocks(bg_ref);
+
+	return base_addr + reserved;
 }
 
Index: uspace/lib/ext4/src/filesystem.c
===================================================================
--- uspace/lib/ext4/src/filesystem.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/ext4/src/filesystem.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -421,4 +421,5 @@
     enum cache_mode cmode, aoff64_t *size, ext4_filesystem_t **rfs)
 {
+	int fs_inited = 0;
 	ext4_filesystem_t *fs = NULL;
 	fs_node_t *root_node = NULL;
@@ -437,4 +438,6 @@
 	if (rc != EOK)
 		goto error;
+
+	fs_inited = 1;
 
 	/* Read root node */
@@ -463,9 +466,7 @@
 		ext4_node_put(root_node);
 
-	if (fs != NULL) {
+	if (fs_inited)
 		ext4_filesystem_fini(fs);
-		free(fs);
-	}
-
+	free(fs);
 	return rc;
 }
@@ -714,6 +715,4 @@
 		/* One for block bitmap one for inode bitmap */
 		free_blocks = free_blocks - reserved - 2 - inode_table_blocks;
-		if (bg_index == 0)
-			++free_blocks; /* XXX Why? */
 
 		ext4_block_group_set_free_blocks_count(bg_ref->block_group,
Index: uspace/lib/ext4/src/ialloc.c
===================================================================
--- uspace/lib/ext4/src/ialloc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/ext4/src/ialloc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -176,10 +176,16 @@
 errno_t ext4_ialloc_alloc_inode(ext4_filesystem_t *fs, uint32_t *index, bool is_dir)
 {
+	int pick_first_free = 0;
 	ext4_superblock_t *sb = fs->superblock;
-
-	uint32_t bgid = 0;
-	uint32_t bg_count = ext4_superblock_get_block_group_count(sb);
-	uint32_t sb_free_inodes = ext4_superblock_get_free_inodes_count(sb);
-	uint32_t avg_free_inodes = sb_free_inodes / bg_count;
+	uint32_t bgid;
+	uint32_t sb_free_inodes;
+	uint32_t avg_free_inodes;
+	uint32_t const bg_count = ext4_superblock_get_block_group_count(sb);
+
+retry:
+
+	bgid = 0;
+	sb_free_inodes = ext4_superblock_get_free_inodes_count(sb);
+	avg_free_inodes = sb_free_inodes / bg_count;
 
 	/* Try to find free i-node in all block groups */
@@ -210,6 +216,6 @@
 		 * blocks.
 		 */
-		if (((free_inodes >= avg_free_inodes) || (bgid == bg_count - 1)) &&
-		    (free_blocks > 0)) {
+		if (((free_inodes >= avg_free_inodes) ||
+		    (bgid == bg_count - 1) || pick_first_free) && (free_blocks > 0)) {
 			/* Load block with bitmap */
 			uint32_t bitmap_block_addr = ext4_block_group_get_inode_bitmap(
@@ -307,4 +313,10 @@
 	}
 
+	/* Try again with less strict conditions */
+	if (pick_first_free == 0) {
+		pick_first_free = 1;
+		goto retry;
+	}
+
 	return ENOSPC;
 }
Index: uspace/lib/ext4/src/ops.c
===================================================================
--- uspace/lib/ext4/src/ops.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/ext4/src/ops.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -101,7 +101,7 @@
 } node_key_t;
 
-static size_t open_nodes_key_hash(void *key_arg)
-{
-	node_key_t *key = (node_key_t *)key_arg;
+static size_t open_nodes_key_hash(const void *key_arg)
+{
+	const node_key_t *key = key_arg;
 	return hash_combine(key->service_id, key->index);
 }
@@ -113,7 +113,7 @@
 }
 
-static bool open_nodes_key_equal(void *key_arg, const ht_link_t *item)
-{
-	node_key_t *key = (node_key_t *)key_arg;
+static bool open_nodes_key_equal(const void *key_arg, const ht_link_t *item)
+{
+	const node_key_t *key = key_arg;
 	ext4_node_t *enode = hash_table_get_inst(item, ext4_node_t, link);
 
Index: uspace/lib/ext4/src/superblock.c
===================================================================
--- uspace/lib/ext4/src/superblock.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/ext4/src/superblock.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1315,10 +1315,12 @@
 	    ext4_superblock_get_blocks_per_group(sb);
 	uint64_t total_blocks =
-	    ext4_superblock_get_blocks_count(sb) - 1;
+	    ext4_superblock_get_blocks_count(sb);
+	uint32_t first_block =
+	    ext4_superblock_get_first_data_block(sb);
 
 	if (bgid < block_group_count - 1)
 		return blocks_per_group;
 	else
-		return (total_blocks - ((block_group_count - 1) * blocks_per_group));
+		return (total_blocks - ((block_group_count - 1) * blocks_per_group)) - first_block;
 }
 
@@ -1392,4 +1394,15 @@
 {
 	sb->reserved_gdt_blocks = host2uint32_t_le(n);
+}
+
+/** Get the size of the flex groups
+ *
+ * @param sb	Pointer to the superblock
+ *
+ * @return	Size of the flex groups
+ */
+uint32_t ext4_superblock_get_flex_group_size(ext4_superblock_t *sb)
+{
+	return 2 << sb->log_groups_per_flex;
 }
 
@@ -1465,12 +1478,4 @@
 		 */
 
-		if (idx == 0 && block_size == 1024) {
-			/*
-			 * Special case for first group were the boot block
-			 * resides
-			 */
-			r++;
-		}
-
 		/* This accounts for the superblock */
 		r++;
@@ -1505,5 +1510,5 @@
 	uuid_t uuid;
 	uint32_t cur_ts;
-	uint64_t first_block;
+	uint64_t first_block = 0;
 	uint64_t fs_blocks;
 	uint32_t blocks_count;
@@ -1518,4 +1523,5 @@
 	uint32_t idx;
 	size_t fs_bsize;
+	size_t fs_bsize_log;
 	errno_t rc;
 	struct timespec ts;
@@ -1533,6 +1539,22 @@
 	cur_ts = ts.tv_sec;
 
-	fs_bsize = 1024;
-	first_block = 1; /* 1 for 1k block size, 0 otherwise */
+	fs_bsize = cfg->bsize;
+	switch (fs_bsize) {
+	case 1024:
+		first_block = 1;
+		fs_bsize_log = 0;
+		blocks_group = 8192;
+		break;
+	case 2048:
+		fs_bsize_log = 1;
+		blocks_group = 8192 * 2;
+		break;
+	case 4096:
+		fs_bsize_log = 2;
+		blocks_group = 8192 * 4;
+		break;
+	default:
+		return ENOTSUP;
+	}
 
 	if (fs_bsize % dev_bsize == 0) {
@@ -1543,7 +1565,4 @@
 		fs_blocks = dev_bcnt * (dev_bsize / fs_bsize);
 	}
-
-	/* FS blocks per group */
-	blocks_group = 8 * fs_bsize;
 
 	/* Inodes per group */
@@ -1581,8 +1600,7 @@
 	ext4_superblock_set_free_inodes_count(sb, inodes_count);
 	ext4_superblock_set_first_data_block(sb, first_block);
-	/* Block size will be 1024 bytes */
-	ext4_superblock_set_log_block_size(sb, 0);
+	ext4_superblock_set_log_block_size(sb, fs_bsize_log);
 	/* Fragment size should be equal to block size */
-	ext4_superblock_set_log_frag_size(sb, 0);
+	ext4_superblock_set_log_frag_size(sb, fs_bsize_log);
 	ext4_superblock_set_blocks_per_group(sb, blocks_group);
 	/* Should be the same as blocks per group. */
@@ -1634,5 +1652,4 @@
 	/* Compute free blocks */
 	free_blocks = blocks_count;
-	++free_blocks; // XXX Why?
 	for (idx = 0; idx < ngroups; idx++) {
 		free_blocks -= ext4_superblock_get_group_backup_blocks(sb, idx);
Index: uspace/lib/fs/libfs.c
===================================================================
--- uspace/lib/fs/libfs.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/fs/libfs.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -79,5 +79,5 @@
 static void vfs_out_fsprobe(ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
 	errno_t rc;
 	vfs_fs_probe_info_t info;
@@ -106,5 +106,5 @@
 static void vfs_out_mounted(ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
 	char *opts;
 	errno_t rc;
@@ -132,5 +132,5 @@
 static void vfs_out_unmounted(ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
 	errno_t rc;
 
@@ -152,8 +152,8 @@
 static void vfs_out_read(ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
-	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
-	aoff64_t pos = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req),
-	    IPC_GET_ARG4(*req));
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
+	fs_index_t index = (fs_index_t) ipc_get_arg2(req);
+	aoff64_t pos = (aoff64_t) MERGE_LOUP32(ipc_get_arg3(req),
+	    ipc_get_arg4(req));
 	size_t rbytes;
 	errno_t rc;
@@ -169,8 +169,8 @@
 static void vfs_out_write(ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
-	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
-	aoff64_t pos = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req),
-	    IPC_GET_ARG4(*req));
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
+	fs_index_t index = (fs_index_t) ipc_get_arg2(req);
+	aoff64_t pos = (aoff64_t) MERGE_LOUP32(ipc_get_arg3(req),
+	    ipc_get_arg4(req));
 	size_t wbytes;
 	aoff64_t nsize;
@@ -188,8 +188,8 @@
 static void vfs_out_truncate(ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
-	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
-	aoff64_t size = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req),
-	    IPC_GET_ARG4(*req));
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
+	fs_index_t index = (fs_index_t) ipc_get_arg2(req);
+	aoff64_t size = (aoff64_t) MERGE_LOUP32(ipc_get_arg3(req),
+	    ipc_get_arg4(req));
 	errno_t rc;
 
@@ -201,6 +201,6 @@
 static void vfs_out_close(ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
-	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
+	fs_index_t index = (fs_index_t) ipc_get_arg2(req);
 	errno_t rc;
 
@@ -212,6 +212,6 @@
 static void vfs_out_destroy(ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
-	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
+	fs_index_t index = (fs_index_t) ipc_get_arg2(req);
 
 	errno_t rc;
@@ -239,6 +239,6 @@
 static void vfs_out_sync(ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
-	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
+	fs_index_t index = (fs_index_t) ipc_get_arg2(req);
 	errno_t rc;
 
@@ -255,6 +255,6 @@
 static void vfs_out_is_empty(ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
-	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
+	fs_index_t index = (fs_index_t) ipc_get_arg2(req);
 	errno_t rc;
 
@@ -290,10 +290,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			return;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case VFS_OUT_FSPROBE:
 			vfs_out_fsprobe(&call);
@@ -424,7 +424,7 @@
 	 */
 	async_wait_for(req, NULL);
-	reg.fs_handle = (int) IPC_GET_ARG1(answer);
-
-	return IPC_GET_RETVAL(answer);
+	reg.fs_handle = (int) ipc_get_arg1(&answer);
+
+	return ipc_get_retval(&answer);
 }
 
@@ -490,7 +490,7 @@
 void libfs_link(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_call_t *req)
 {
-	service_id_t parent_sid = IPC_GET_ARG1(*req);
-	fs_index_t parent_index = IPC_GET_ARG2(*req);
-	fs_index_t child_index = IPC_GET_ARG3(*req);
+	service_id_t parent_sid = ipc_get_arg1(req);
+	fs_index_t parent_index = ipc_get_arg2(req);
+	fs_index_t child_index = ipc_get_arg3(req);
 
 	char component[NAME_MAX + 1];
@@ -536,9 +536,9 @@
 void libfs_lookup(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_call_t *req)
 {
-	unsigned first = IPC_GET_ARG1(*req);
-	unsigned len = IPC_GET_ARG2(*req);
-	service_id_t service_id = IPC_GET_ARG3(*req);
-	fs_index_t index = IPC_GET_ARG4(*req);
-	int lflag = IPC_GET_ARG5(*req);
+	unsigned first = ipc_get_arg1(req);
+	unsigned len = ipc_get_arg2(req);
+	service_id_t service_id = ipc_get_arg3(req);
+	fs_index_t index = ipc_get_arg4(req);
+	int lflag = ipc_get_arg5(req);
 
 	// TODO: Validate flags.
@@ -716,6 +716,6 @@
 void libfs_stat(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
-	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
+	fs_index_t index = (fs_index_t) ipc_get_arg2(req);
 
 	fs_node_t *fn;
@@ -753,6 +753,6 @@
 void libfs_statfs(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
-	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
+	fs_index_t index = (fs_index_t) ipc_get_arg2(req);
 
 	fs_node_t *fn;
@@ -810,6 +810,6 @@
 void libfs_open_node(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_call_t *req)
 {
-	service_id_t service_id = IPC_GET_ARG1(*req);
-	fs_index_t index = IPC_GET_ARG2(*req);
+	service_id_t service_id = ipc_get_arg1(req);
+	fs_index_t index = ipc_get_arg2(req);
 
 	fs_node_t *fn;
Index: uspace/lib/graph/graph.c
===================================================================
--- uspace/lib/graph/graph.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/graph/graph.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -243,5 +243,5 @@
 static void vs_claim(visualizer_t *vs, ipc_call_t *icall)
 {
-	vs->client_side_handle = IPC_GET_ARG1(*icall);
+	vs->client_side_handle = ipc_get_arg1(icall);
 	errno_t rc = vs->ops.claim(vs);
 	async_answer_0(icall, rc);
@@ -283,5 +283,5 @@
 
 	fibril_mutex_lock(&vs->mode_mtx);
-	link_t *link = list_nth(&vs->modes, IPC_GET_ARG1(*icall));
+	link_t *link = list_nth(&vs->modes, ipc_get_arg1(icall));
 
 	if (link != NULL) {
@@ -360,5 +360,5 @@
 	}
 
-	sysarg_t mode_idx = IPC_GET_ARG1(*icall);
+	sysarg_t mode_idx = ipc_get_arg1(icall);
 
 	fibril_mutex_lock(&vs->mode_mtx);
@@ -397,6 +397,6 @@
 
 	/* Retrieve mode index and version. */
-	sysarg_t mode_idx = IPC_GET_ARG1(*icall);
-	sysarg_t mode_version = IPC_GET_ARG2(*icall);
+	sysarg_t mode_idx = ipc_get_arg1(icall);
+	sysarg_t mode_version = ipc_get_arg2(icall);
 
 	/* Find mode in the list. */
@@ -470,10 +470,10 @@
 static void vs_update_damaged_region(visualizer_t *vs, ipc_call_t *icall)
 {
-	sysarg_t x_offset = (IPC_GET_ARG5(*icall) >> 16);
-	sysarg_t y_offset = (IPC_GET_ARG5(*icall) & 0x0000ffff);
+	sysarg_t x_offset = (ipc_get_arg5(icall) >> 16);
+	sysarg_t y_offset = (ipc_get_arg5(icall) & 0x0000ffff);
 
 	errno_t rc = vs->ops.handle_damage(vs,
-	    IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall),
-	    IPC_GET_ARG3(*icall), IPC_GET_ARG4(*icall),
+	    ipc_get_arg1(icall), ipc_get_arg2(icall),
+	    ipc_get_arg3(icall), ipc_get_arg4(icall),
 	    x_offset, y_offset);
 	async_answer_0(icall, rc);
@@ -516,10 +516,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case VISUALIZER_CLAIM:
 			vs_claim(vs, &call);
@@ -576,10 +576,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		default:
 			async_answer_0(&call, EINVAL);
@@ -595,6 +595,6 @@
 {
 	/* Find the visualizer or renderer with the given service ID. */
-	visualizer_t *vs = graph_get_visualizer(IPC_GET_ARG2(*icall));
-	renderer_t *rnd = graph_get_renderer(IPC_GET_ARG2(*icall));
+	visualizer_t *vs = graph_get_visualizer(ipc_get_arg2(icall));
+	renderer_t *rnd = graph_get_renderer(ipc_get_arg2(icall));
 
 	if (vs != NULL)
Index: uspace/lib/gui/terminal.c
===================================================================
--- uspace/lib/gui/terminal.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/gui/terminal.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -682,5 +682,5 @@
 
 	list_foreach(terms, link, terminal_t, cur) {
-		if (cur->dsid == (service_id_t) IPC_GET_ARG2(*icall)) {
+		if (cur->dsid == (service_id_t) ipc_get_arg2(icall)) {
 			term = cur;
 			break;
Index: uspace/lib/hound/src/protocol.c
===================================================================
--- uspace/lib/hound/src/protocol.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/hound/src/protocol.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -140,5 +140,5 @@
 	async_exchange_end(exch);
 	if (ret == EOK) {
-		*id = (hound_context_id_t) IPC_GET_ARG1(call);
+		*id = (hound_context_id_t) ipc_get_arg1(&call);
 	}
 
@@ -158,5 +158,5 @@
 	async_exch_t *exch = async_exchange_begin(sess);
 	const errno_t ret = async_req_1_0(exch, IPC_M_HOUND_CONTEXT_UNREGISTER,
-	    CAP_HANDLE_RAW(id));
+	    cap_handle_raw(id));
 	async_exchange_end(exch);
 	return ret;
@@ -203,5 +203,5 @@
 		return ret;
 	}
-	unsigned name_count = IPC_GET_ARG1(res_call);
+	unsigned name_count = ipc_get_arg1(&res_call);
 
 	/* Start receiving names */
@@ -315,5 +315,5 @@
 	};
 
-	return async_req_4_0(exch, IPC_M_HOUND_STREAM_ENTER, CAP_HANDLE_RAW(id),
+	return async_req_4_0(exch, IPC_M_HOUND_STREAM_ENTER, cap_handle_raw(id),
 	    flags, c.arg, bsize);
 }
@@ -406,5 +406,5 @@
 		async_get_call(&call);
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case IPC_M_HOUND_CONTEXT_REGISTER:
 			/* check interface functions */
@@ -413,5 +413,5 @@
 				break;
 			}
-			bool record = IPC_GET_ARG1(call);
+			bool record = ipc_get_arg1(&call);
 			void *name;
 
@@ -431,5 +431,5 @@
 				async_answer_0(&call, ret);
 			} else {
-				async_answer_1(&call, EOK, CAP_HANDLE_RAW(context));
+				async_answer_1(&call, EOK, cap_handle_raw(context));
 			}
 			break;
@@ -442,5 +442,5 @@
 
 			/* get id, 1st param */
-			context = (hound_context_id_t) IPC_GET_ARG1(call);
+			context = (hound_context_id_t) ipc_get_arg1(&call);
 			ret = server_iface->rem_context(server_iface->server,
 			    context);
@@ -455,7 +455,7 @@
 
 			char **list = NULL;
-			flags = IPC_GET_ARG1(call);
-			size_t count = IPC_GET_ARG2(call);
-			const bool conn = IPC_GET_ARG3(call);
+			flags = ipc_get_arg1(&call);
+			size_t count = ipc_get_arg2(&call);
+			const bool conn = ipc_get_arg3(&call);
 			char *conn_name = NULL;
 			ret = EOK;
@@ -568,7 +568,7 @@
 
 			/* get parameters */
-			context = (hound_context_id_t) IPC_GET_ARG1(call);
-			flags = IPC_GET_ARG2(call);
-			const format_convert_t c = { .arg = IPC_GET_ARG3(call) };
+			context = (hound_context_id_t) ipc_get_arg1(&call);
+			flags = ipc_get_arg2(&call);
+			const format_convert_t c = { .arg = ipc_get_arg3(&call) };
 			const pcm_format_t f = {
 				.sampling_rate = c.f.rate * 100,
@@ -576,5 +576,5 @@
 				.sample_format = c.f.format,
 			};
-			size_t bsize = IPC_GET_ARG4(call);
+			size_t bsize = ipc_get_arg4(&call);
 
 			void *stream;
@@ -640,7 +640,7 @@
 	/* accept data write or drain */
 	while (async_data_write_receive(&call, &size) ||
-	    (IPC_GET_IMETHOD(call) == IPC_M_HOUND_STREAM_DRAIN)) {
+	    (ipc_get_imethod(&call) == IPC_M_HOUND_STREAM_DRAIN)) {
 		/* check drain first */
-		if (IPC_GET_IMETHOD(call) == IPC_M_HOUND_STREAM_DRAIN) {
+		if (ipc_get_imethod(&call) == IPC_M_HOUND_STREAM_DRAIN) {
 			errno_t ret = ENOTSUP;
 			if (server_iface->drain_stream)
@@ -668,5 +668,5 @@
 		}
 	}
-	const errno_t ret = IPC_GET_IMETHOD(call) == IPC_M_HOUND_STREAM_EXIT ?
+	const errno_t ret = ipc_get_imethod(&call) == IPC_M_HOUND_STREAM_EXIT ?
 	    EOK : EINVAL;
 
@@ -687,7 +687,7 @@
 	/* accept data read and drain */
 	while (async_data_read_receive(&call, &size) ||
-	    (IPC_GET_IMETHOD(call) == IPC_M_HOUND_STREAM_DRAIN)) {
+	    (ipc_get_imethod(&call) == IPC_M_HOUND_STREAM_DRAIN)) {
 		/* drain does not make much sense but it is allowed */
-		if (IPC_GET_IMETHOD(call) == IPC_M_HOUND_STREAM_DRAIN) {
+		if (ipc_get_imethod(&call) == IPC_M_HOUND_STREAM_DRAIN) {
 			errno_t ret = ENOTSUP;
 			if (server_iface->drain_stream)
@@ -712,5 +712,5 @@
 		}
 	}
-	const errno_t ret = IPC_GET_IMETHOD(call) == IPC_M_HOUND_STREAM_EXIT ?
+	const errno_t ret = ipc_get_imethod(&call) == IPC_M_HOUND_STREAM_EXIT ?
 	    EOK : EINVAL;
 
Index: uspace/lib/http/src/headers.c
===================================================================
--- uspace/lib/http/src/headers.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/http/src/headers.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -85,10 +85,6 @@
 {
 	/* TODO properly split long header values */
-	if (buf == NULL) {
-		return printf_size(HTTP_HEADER_LINE, header->name, header->value);
-	} else {
-		return snprintf(buf, buf_size,
-		    HTTP_HEADER_LINE, header->name, header->value);
-	}
+	return snprintf(buf, buf_size,
+	    HTTP_HEADER_LINE, header->name, header->value);
 }
 
Index: uspace/lib/http/src/request.c
===================================================================
--- uspace/lib/http/src/request.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/http/src/request.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -82,9 +82,5 @@
     const char *method, const char *path)
 {
-	if (buf == NULL) {
-		return printf_size(HTTP_METHOD_LINE, method, path);
-	} else {
-		return snprintf(buf, buf_size, HTTP_METHOD_LINE, method, path);
-	}
+	return snprintf(buf, buf_size, HTTP_METHOD_LINE, method, path);
 }
 
Index: uspace/lib/ieee80211/src/ieee80211.c
===================================================================
--- uspace/lib/ieee80211/src/ieee80211.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/ieee80211/src/ieee80211.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -479,5 +479,5 @@
 }
 
-extern bool ieee80211_query_using_key(ieee80211_dev_t *ieee80211_dev)
+bool ieee80211_query_using_key(ieee80211_dev_t *ieee80211_dev)
 {
 	fibril_mutex_lock(&ieee80211_dev->gen_mutex);
@@ -803,4 +803,5 @@
 	if (rc != EOK) {
 		ddf_fun_unbind(fun);
+		ddf_fun_destroy(fun);
 		return rc;
 	}
@@ -809,4 +810,5 @@
 	if (rc != EOK) {
 		ddf_fun_unbind(fun);
+		ddf_fun_destroy(fun);
 		return rc;
 	}
Index: uspace/lib/nettl/include/nettl/amap.h
===================================================================
--- uspace/lib/nettl/include/nettl/amap.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/nettl/include/nettl/amap.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -82,5 +82,5 @@
 	/** Local links */
 	list_t llink; /* of amap_llink_t */
-	/** Nothing specified (listen on all local adresses) */
+	/** Nothing specified (listen on all local addresses) */
 	portrng_t *unspec;
 } amap_t;
Index: uspace/lib/nic/src/nic_addr_db.c
===================================================================
--- uspace/lib/nic/src/nic_addr_db.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/nic/src/nic_addr_db.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -62,7 +62,7 @@
 } addr_key_t;
 
-static bool nic_addr_key_equal(void *key_arg, const ht_link_t *item)
-{
-	addr_key_t *key = (addr_key_t *)key_arg;
+static bool nic_addr_key_equal(const void *key_arg, const ht_link_t *item)
+{
+	const addr_key_t *key = key_arg;
 	nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link);
 
@@ -81,7 +81,7 @@
 }
 
-static size_t nic_addr_key_hash(void *k)
-{
-	addr_key_t *key = (addr_key_t *)k;
+static size_t nic_addr_key_hash(const void *k)
+{
+	const addr_key_t *key = k;
 	return addr_hash(key->len, key->addr);
 }
@@ -163,5 +163,5 @@
  * @return EOK		If the address was inserted
  * @return ENOMEM	If there was not enough memory
- * @return EEXIST	If this adress already is in the db
+ * @return EEXIST	If this address already is in the db
  */
 errno_t nic_addr_db_insert(nic_addr_db_t *db, const uint8_t *addr)
Index: uspace/lib/nic/src/nic_driver.c
===================================================================
--- uspace/lib/nic/src/nic_driver.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/nic/src/nic_driver.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -418,5 +418,5 @@
 }
 
-/** Inform the NICF about device's MAC adress.
+/** Inform the NICF about device's MAC address.
  *
  * @return EOK On success
Index: uspace/lib/nic/src/nic_wol_virtues.c
===================================================================
--- uspace/lib/nic/src/nic_wol_virtues.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/nic/src/nic_wol_virtues.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -45,7 +45,8 @@
  */
 
-static size_t nic_wv_key_hash(void *key)
-{
-	return *(nic_wv_id_t *) key;
+static size_t nic_wv_key_hash(const void *key)
+{
+	const nic_wv_id_t *k = key;
+	return *k;
 }
 
@@ -56,8 +57,9 @@
 }
 
-static bool nic_wv_key_equal(void *key, const ht_link_t *item)
-{
-	nic_wol_virtue_t *virtue = (nic_wol_virtue_t *) item;
-	return (virtue->id == *(nic_wv_id_t *) key);
+static bool nic_wv_key_equal(const void *key, const ht_link_t *item)
+{
+	const nic_wv_id_t *k = key;
+	const nic_wol_virtue_t *virtue = (const nic_wol_virtue_t *) item;
+	return (virtue->id == *k);
 }
 
Index: uspace/lib/pcm/src/format.c
===================================================================
--- uspace/lib/pcm/src/format.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/pcm/src/format.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -40,4 +40,5 @@
 #include <stdio.h>
 #include <inttypes.h>
+#include <limits.h>
 
 #include "format.h"
Index: uspace/lib/pcut/Makefile
===================================================================
--- uspace/lib/pcut/Makefile	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/pcut/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -23,5 +23,5 @@
 	$(PCUT_TEST_PREFIX)testlist$(PCUT_TEST_SUFFIX) \
 	$(PCUT_TEST_PREFIX)timeout$(PCUT_TEST_SUFFIX) \
-	$(PCUT_TEST_PREFIX)xmlreport$(PCUT_TEST_SUFFIX) 
+	$(PCUT_TEST_PREFIX)xmlreport$(PCUT_TEST_SUFFIX)
 
 EXTRA_CLEAN = $(SELF_TESTS)
Index: uspace/lib/pcut/include/pcut/asserts.h
===================================================================
--- uspace/lib/pcut/include/pcut/asserts.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/pcut/include/pcut/asserts.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -186,10 +186,41 @@
 #define PCUT_ASSERT_INT_EQUALS(expected, actual) \
 	do {\
-		long pcut_expected_eval = (expected); \
-		long pcut_actual_eval = (actual); \
+		long long pcut_expected_eval = (expected); \
+		long long pcut_actual_eval = (actual); \
 		if (pcut_expected_eval != pcut_actual_eval) { \
-			PCUT_ASSERTION_FAILED("Expected <%ld> but got <%ld> (%s != %s)", \
+			PCUT_ASSERTION_FAILED("Expected <%lld> but got <%lld> (%s != %s)", \
 				pcut_expected_eval, pcut_actual_eval, \
 				#expected, #actual); \
+		} \
+	} while (0)
+
+/** Assertion for checking that two integers are equal.
+ *
+ * @param expected Expected (correct) value.
+ * @param actual Actually obtained (computed) value we wish to test.
+ */
+#define PCUT_ASSERT_UINT_EQUALS(expected, actual) \
+	do {\
+		unsigned long long pcut_expected_eval = (expected); \
+		unsigned long long pcut_actual_eval = (actual); \
+		if (pcut_expected_eval != pcut_actual_eval) { \
+			PCUT_ASSERTION_FAILED("Expected <%llu> but got <%llu> (%s != %s)", \
+				pcut_expected_eval, pcut_actual_eval, \
+				#expected, #actual); \
+		} \
+	} while (0)
+
+/** Assertion for checking that two pointers are equal.
+ *
+ * @param expected Expected (correct) value.
+ * @param actual Actually obtained (computed) value we wish to test.
+ */
+#define PCUT_ASSERT_PTR_EQUALS(expected, actual) \
+	do {\
+		const void *pcut_expected_eval = (expected); \
+		const void *pcut_actual_eval = (actual); \
+		if (pcut_expected_eval != pcut_actual_eval) { \
+			PCUT_ASSERTION_FAILED("Expected '" #actual "' = '" #expected "' = <%p> but got '" #actual "' = <%p>", \
+				pcut_expected_eval, pcut_actual_eval); \
 		} \
 	} while (0)
Index: uspace/lib/pcut/src/os/generic.c
===================================================================
--- uspace/lib/pcut/src/os/generic.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/pcut/src/os/generic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -121,5 +121,5 @@
 	FORMAT_COMMAND(command, PCUT_COMMAND_LINE_BUFFER_SIZE - 1,
 		self_path, (test)->id, tempfile_name);
-	
+
 	PCUT_DEBUG("Will execute <%s> (temp file <%s>) with system().",
 		command, tempfile_name);
Index: uspace/lib/pcut/src/os/helenos.c
===================================================================
--- uspace/lib/pcut/src/os/helenos.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/pcut/src/os/helenos.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -109,10 +109,8 @@
 
 /** Mutex guard for forced_termination_cv. */
-static fibril_mutex_t forced_termination_mutex
-	= FIBRIL_MUTEX_INITIALIZER(forced_termination_mutex);
+static FIBRIL_MUTEX_INITIALIZE(forced_termination_mutex);
 
 /** Condition-variable for checking whether test timed-out. */
-static fibril_condvar_t forced_termination_cv
-	= FIBRIL_CONDVAR_INITIALIZER(forced_termination_cv);
+static FIBRIL_CONDVAR_INITIALIZE(forced_termination_cv);
 
 /** Spawned task id. */
Index: uspace/lib/pcut/src/report/tap.c
===================================================================
--- uspace/lib/pcut/src/report/tap.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/pcut/src/report/tap.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,11 +35,10 @@
 #include "report.h"
 
-#ifndef __helenos__
+#ifdef __helenos__
+#define _REALLY_WANT_STRING_H
+#endif
+
 #pragma warning(push, 0)
 #include <string.h>
-#pragma warning(pop)
-#endif
-
-#pragma warning(push, 0)
 #include <stdio.h>
 #pragma warning(pop)
@@ -57,4 +56,7 @@
 /** Counter of failed tests in current suite. */
 static int failed_tests_in_suite;
+
+/** Comma-separated list of failed test names. */
+static char *failed_test_names;
 
 /** Initialize the TAP output.
@@ -170,4 +172,17 @@
 
 	print_by_lines(extra_output, "# stdio: ");
+
+	if (outcome != PCUT_OUTCOME_PASS) {
+		if (failed_test_names == NULL) {
+			failed_test_names = strdup(test_name);
+		} else {
+			char *fs = NULL;
+			if (asprintf(&fs, "%s, %s",
+			    failed_test_names, test_name) >= 0) {
+				free(failed_test_names);
+				failed_test_names = fs;
+			}
+		}
+	}
 }
 
@@ -178,4 +193,5 @@
 	} else {
 		printf("#> Done: %d of %d tests failed.\n", failed_test_counter, test_counter);
+		printf("#> Failed tests: %s\n", failed_test_names);
 	}
 }
Index: uspace/lib/pcut/update-from-master.sh
===================================================================
--- uspace/lib/pcut/update-from-master.sh	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/pcut/update-from-master.sh	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,3 +1,3 @@
-#!/bin/sh
+#!/bin/bash
 
 #
Index: uspace/lib/posix/Makefile
===================================================================
--- uspace/lib/posix/Makefile	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,5 +31,5 @@
 LIBRARY = libposix
 
-EXTRA_CFLAGS = -Iinclude/posix
+EXTRA_CFLAGS = -Iinclude/posix -D_XOPEN_SOURCE
 
 EXPORT_FILES = \
@@ -41,4 +41,5 @@
 	../hound/libhound.a \
 	../pcm/libpcm.a \
+	../cpp/libcpp.a \
 	$(LIBC_PREFIX)/libc.a \
 	$(LIBC_PREFIX)/crt0.o \
@@ -96,4 +97,7 @@
 	$(COMMON_CFLAGS)
 
+EXPORT_CXXFLAGS = \
+	$(COMMON_CXXFLAGS)
+
 include $(USPACE_PREFIX)/Makefile.common
 
@@ -109,5 +113,5 @@
 	echo 'HELENOS_CPPFLAGS="$(EXPORT_CPPFLAGS)"' >> $@.new
 	echo 'HELENOS_CFLAGS="$(EXPORT_CFLAGS)"' >> $@.new
-	echo 'HELENOS_CXXFLAGS="$(EXPORT_CFLAGS)"' >> $@.new
+	echo 'HELENOS_CXXFLAGS="$(EXPORT_CXXFLAGS)"' >> $@.new
 	echo 'HELENOS_LDFLAGS="$(EXPORT_LDFLAGS)"' >> $@.new
 	echo 'HELENOS_LDLIBS="$(EXPORT_LDLIBS)"' >> $@.new
@@ -146,3 +150,5 @@
 	mkdir -p $(EXPORT_DIR)/include.new/libpcm
 	cp -r -L -t $(EXPORT_DIR)/include.new/libpcm ../pcm/include/*
+	mkdir -p $(EXPORT_DIR)/include.new/libcpp
+	cp -r -L -t $(EXPORT_DIR)/include.new/libcpp ../cpp/include/*
 	mv $(EXPORT_DIR)/include.new $(EXPORT_DIR)/include
Index: uspace/lib/posix/include/posix/ctype.h
===================================================================
--- uspace/lib/posix/include/posix/ctype.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/ctype.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,4 +39,6 @@
 #include <libc/ctype.h>
 
+__C_DECLS_BEGIN;
+
 /* Obsolete Functions and Macros */
 extern int isascii(int c);
@@ -46,4 +48,6 @@
 #define _toupper(c) ((c) - 'a' + 'A')
 
+__C_DECLS_END;
+
 #endif /* POSIX_CTYPE_H_ */
 
Index: uspace/lib/posix/include/posix/dlfcn.h
===================================================================
--- uspace/lib/posix/include/posix/dlfcn.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/dlfcn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -41,8 +41,12 @@
 #define RTLD_LOCAL 0
 
+__C_DECLS_BEGIN;
+
 extern void *dlopen(const char *, int);
 extern void *dlsym(void *, const char *);
 extern int dlclose(void *);
 extern char *dlerror(void);
+
+__C_DECLS_END;
 
 #endif
Index: uspace/lib/posix/include/posix/fcntl.h
===================================================================
--- uspace/lib/posix/include/posix/fcntl.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/fcntl.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,11 +38,4 @@
 #include <sys/types.h>
 
-#undef O_CREAT
-#undef O_EXCL
-#undef O_TRUNC
-#undef O_APPEND
-#undef O_RDONLY
-#undef O_RDWR
-#undef O_WRONLY
 #define O_CREAT   1
 #define O_EXCL    2
@@ -54,23 +47,10 @@
 
 /* Mask for file access modes. */
-#undef O_ACCMODE
 #define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
 
 /* Dummy compatibility flag */
-#undef O_NOCTTY
 #define O_NOCTTY 0
 
 /* fcntl commands */
-#undef F_DUPFD
-#undef F_DUPFD_CLOEXEC
-#undef F_GETFD
-#undef F_SETFD
-#undef F_GETFL
-#undef F_SETFL
-#undef F_GETOWN
-#undef F_SETOWN
-#undef F_GETLK
-#undef F_SETLK
-#undef F_SETLKW
 #define F_DUPFD            0 /* Duplicate file descriptor. */
 #define F_DUPFD_CLOEXEC    1 /* Same as F_DUPFD but with FD_CLOEXEC flag set. */
@@ -86,9 +66,12 @@
 
 /* File descriptor flags used with F_GETFD and F_SETFD. */
-#undef FD_CLOEXEC
 #define FD_CLOEXEC         1 /* Close on exec. */
+
+__C_DECLS_BEGIN;
 
 extern int open(const char *pathname, int flags, ...);
 extern int fcntl(int fd, int cmd, ...);
+
+__C_DECLS_END;
 
 #endif /* POSIX_FCNTL_H_ */
Index: uspace/lib/posix/include/posix/fnmatch.h
===================================================================
--- uspace/lib/posix/include/posix/fnmatch.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/fnmatch.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -36,12 +36,10 @@
 #define POSIX_FNMATCH_H_
 
+#include <_bits/decls.h>
+
 /* Error Values */
-#undef FNM_NOMATCH
 #define FNM_NOMATCH 1
 
 /* Flags */
-#undef FNM_PATHNAME
-#undef FNM_PERIOD
-#undef FNM_NOESCAPE
 #define FNM_PATHNAME 1
 #define FNM_PERIOD 2
@@ -49,12 +47,13 @@
 
 /* GNU Extensions */
-#undef FNM_FILE_NAME
-#undef FNM_LEADING_DIR
-#undef FNM_CASEFOLD
 #define FNM_FILE_NAME FNM_PATHNAME
 #define FNM_LEADING_DIR 8
 #define FNM_CASEFOLD 16
 
+__C_DECLS_BEGIN;
+
 extern int fnmatch(const char *pattern, const char *string, int flags);
+
+__C_DECLS_END;
 
 #endif /* POSIX_FNMATCH_H_ */
Index: uspace/lib/posix/include/posix/locale.h
===================================================================
--- uspace/lib/posix/include/posix/locale.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/locale.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,17 +37,6 @@
 
 #include <stddef.h>
+#include <_bits/decls.h>
 
-#ifndef __locale_t_defined
-#define __locale_t_defined
-typedef struct __posix_locale *locale_t;
-#endif
-
-#undef LC_ALL
-#undef LC_COLLATE
-#undef LC_CTYPE
-#undef LC_MESSAGES
-#undef LC_MONETARY
-#undef LC_NUMERIC
-#undef LC_TIME
 #define LC_ALL 0
 #define LC_COLLATE 1
@@ -58,11 +47,4 @@
 #define LC_TIME 6
 
-#undef LC_COLLATE_MASK
-#undef LC_CTYPE_MASK
-#undef LC_MESSAGES_MASK
-#undef LC_MONETARY_MASK
-#undef LC_NUMERIC_MASK
-#undef LC_TIME_MASK
-#undef LC_ALL_MASK
 #define LC_COLLATE_MASK (1 << 0)
 #define LC_CTYPE_MASK (1 << 1)
@@ -74,6 +56,12 @@
     LC_MONETARY_MASK | LC_NUMERIC_MASK | LC_TIME_MASK)
 
-#undef LC_GLOBAL_LOCALE
 #define LC_GLOBAL_LOCALE NULL
+
+__C_DECLS_BEGIN;
+
+#ifndef __locale_t_defined
+#define __locale_t_defined
+typedef struct __posix_locale *locale_t;
+#endif
 
 struct lconv {
@@ -114,4 +102,6 @@
 extern locale_t uselocale(locale_t newloc);
 
+__C_DECLS_END;
+
 #endif /* POSIX_LOCALE_H_ */
 
Index: uspace/lib/posix/include/posix/pthread.h
===================================================================
--- uspace/lib/posix/include/posix/pthread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/pthread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,4 +34,13 @@
 
 #include <time.h>
+#include <_bits/decls.h>
+
+#define PTHREAD_MUTEX_RECURSIVE 1
+
+#define PTHREAD_MUTEX_INITIALIZER { 0 }
+
+#define PTHREAD_COND_INITIALIZER { 0 }
+
+__C_DECLS_BEGIN;
 
 typedef void *pthread_t;
@@ -43,11 +52,7 @@
 typedef int pthread_key_t;
 
-#define PTHREAD_MUTEX_RECURSIVE 1
-
 typedef struct pthread_mutex {
 	int dummy;
 } pthread_mutex_t;
-
-#define PTHREAD_MUTEX_INITIALIZER { 0 }
 
 typedef struct {
@@ -62,6 +67,4 @@
 	int dummy;
 } pthread_cond_t;
-
-#define PTHREAD_COND_INITIALIZER { 0 }
 
 extern pthread_t pthread_self(void);
@@ -106,4 +109,6 @@
 extern int pthread_key_create(pthread_key_t *, void (*)(void *));
 
+__C_DECLS_END;
+
 #endif
 
Index: uspace/lib/posix/include/posix/pwd.h
===================================================================
--- uspace/lib/posix/include/posix/pwd.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/pwd.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,4 +37,7 @@
 
 #include <sys/types.h>
+#include <_bits/decls.h>
+
+__C_DECLS_BEGIN;
 
 struct passwd {
@@ -58,4 +61,6 @@
     char *buffer, size_t bufsize, struct passwd **result);
 
+__C_DECLS_END;
+
 #endif /* POSIX_PWD_H_ */
 
Index: uspace/lib/posix/include/posix/signal.h
===================================================================
--- uspace/lib/posix/include/posix/signal.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/signal.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,67 +39,21 @@
 #include <ucontext.h>
 
-extern void __posix_default_signal_handler(int signo);
-extern void __posix_hold_signal_handler(int signo);
-extern void __posix_ignore_signal_handler(int signo);
-
-#undef SIG_DFL
 #define SIG_DFL ((void (*)(int)) __posix_default_signal_handler)
-#undef SIG_ERR
 #define SIG_ERR ((void (*)(int)) NULL)
-#undef SIG_HOLD
 #define SIG_HOLD ((void (*)(int)) __posix_hold_signal_handler)
-#undef SIG_IGN
 #define SIG_IGN ((void (*)(int)) __posix_ignore_signal_handler)
 
-typedef struct {
-	int si_signo;
-	int si_code;
-
-	int si_errno;
-
-	pid_t si_pid;
-	uid_t si_uid;
-	void *si_addr;
-	int si_status;
-
-	long si_band;
-
-	union sigval si_value;
-} siginfo_t;
-
-struct sigaction {
-	void (*sa_handler)(int);
-	sigset_t sa_mask;
-	int sa_flags;
-	void (*sa_sigaction)(int, siginfo_t *, void *);
-};
-
 /* Values of sigevent::sigev_notify */
-#undef SIGEV_NONE
-#undef SIGEV_SIGNAL
-#undef SIGEV_THREAD
 #define SIGEV_NONE 0
 #define SIGEV_SIGNAL 0
 #define SIGEV_THREAD 0
 
-#undef SIGRT_MIN
-#undef SIGRT_MAX
 #define SIGRT_MIN 0
 #define SIGRT_MAX 0
 
-#undef SIG_BLOCK
-#undef SIG_UNBLOCK
-#undef SIG_SETMASK
 #define SIG_BLOCK 0
 #define SIG_UNBLOCK 1
 #define SIG_SETMASK 2
 
-#undef SA_NOCLDSTOP
-#undef SA_ONSTACK
-#undef SA_RESETHAND
-#undef SA_RESTART
-#undef SA_SIGINFO
-#undef SA_NOCLDWAIT
-#undef SA_NODEFER
 #define SA_NOCLDSTOP (1 << 0)
 #define SA_ONSTACK (1 << 1)
@@ -110,13 +64,38 @@
 #define SA_NODEFER (1 << 6)
 
-#undef SS_ONSTACK
-#undef SS_DISABLE
 #define SS_ONSTACK 0
 #define SS_DISABLE 0
 
-#undef MINSIGSTKSZ
-#undef SIGSTKSZ
 #define MINSIGSTKSZ 0
 #define SIGSTKSZ 0
+
+__C_DECLS_BEGIN;
+
+extern void __posix_default_signal_handler(int signo);
+extern void __posix_hold_signal_handler(int signo);
+extern void __posix_ignore_signal_handler(int signo);
+
+typedef struct {
+	int si_signo;
+	int si_code;
+
+	int si_errno;
+
+	pid_t si_pid;
+	uid_t si_uid;
+	void *si_addr;
+	int si_status;
+
+	long si_band;
+
+	union sigval si_value;
+} siginfo_t;
+
+struct sigaction {
+	void (*sa_handler)(int);
+	sigset_t sa_mask;
+	int sa_flags;
+	void (*sa_sigaction)(int, siginfo_t *, void *);
+};
 
 /* Full POSIX set */
@@ -245,4 +224,6 @@
     sigset_t *__restrict__ oset);
 
+__C_DECLS_END;
+
 #endif /* POSIX_SIGNAL_H_ */
 
Index: uspace/lib/posix/include/posix/stdio.h
===================================================================
--- uspace/lib/posix/include/posix/stdio.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/stdio.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -45,12 +45,14 @@
 #include <limits.h>
 
+#define P_tmpdir "/tmp"
+
+#define L_ctermid PATH_MAX
+
+__C_DECLS_BEGIN;
+
 extern FILE *fdopen(int, const char *);
 extern int fileno(FILE *);
 
-#define P_tmpdir "/tmp"
-
 /* Identifying the Terminal */
-#undef L_ctermid
-#define L_ctermid PATH_MAX
 extern char *ctermid(char *s);
 
@@ -61,5 +63,5 @@
     FILE *__restrict__ stream);
 
-#ifdef _LARGEFILE64_SOURCE
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
 extern int fseeko64(FILE *stream, off64_t offset, int whence);
 extern off64_t ftello64(FILE *stream);
@@ -98,4 +100,6 @@
 extern char *tempnam(const char *dir, const char *pfx);
 
+__C_DECLS_END;
+
 #endif /* POSIX_STDIO_H_ */
 
Index: uspace/lib/posix/include/posix/stdlib.h
===================================================================
--- uspace/lib/posix/include/posix/stdlib.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/stdlib.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -42,4 +42,6 @@
 #include <stddef.h>
 
+__C_DECLS_BEGIN;
+
 /* Environment Access */
 extern int putenv(char *string);
@@ -60,4 +62,6 @@
 extern int bsd_getloadavg(double loadavg[], int nelem);
 
+__C_DECLS_END;
+
 #endif  // POSIX_STDLIB_H_
 
Index: uspace/lib/posix/include/posix/string.h
===================================================================
--- uspace/lib/posix/include/posix/string.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/string.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -47,11 +47,9 @@
 
 #include <libc/mem.h>
-#ifdef _HELENOS_SOURCE
-#undef _HELENOS_SOURCE
+
+#define _REALLY_WANT_STRING_H
 #include <libc/string.h>
-#define _HELENOS_SOURCE
-#else
-#include <libc/string.h>
-#endif
+
+__C_DECLS_BEGIN;
 
 /* Copying and Concatenation */
@@ -59,6 +57,4 @@
 extern char *stpncpy(char *__restrict__ dest, const char *__restrict__ src, size_t n);
 extern void *memccpy(void *__restrict__ dest, const void *__restrict__ src, int c, size_t n);
-extern char *strdup(const char *s);
-extern char *strndup(const char *s, size_t n);
 
 /* Search Functions */
@@ -71,16 +67,13 @@
 extern int strerror_r(int errnum, char *buf, size_t bufsz);
 
-/* String Length */
-extern size_t strnlen(const char *s, size_t n);
-
 /* Signal Messages */
 extern char *strsignal(int signum);
 
 /* Legacy Declarations */
-#ifndef POSIX_STRINGS_H_
 extern int ffs(int i);
 extern int strcasecmp(const char *s1, const char *s2);
 extern int strncasecmp(const char *s1, const char *s2, size_t n);
-#endif
+
+__C_DECLS_END;
 
 #endif  // POSIX_STRING_H_
Index: uspace/lib/posix/include/posix/strings.h
===================================================================
--- uspace/lib/posix/include/posix/strings.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/strings.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,14 +39,12 @@
 #include <types/common.h>
 
+__C_DECLS_BEGIN;
+
 /* Search Functions */
-#ifndef POSIX_STRING_H_
 extern int ffs(int i);
-#endif
 
 /* String/Array Comparison */
-#ifndef POSIX_STRING_H_
 extern int strcasecmp(const char *s1, const char *s2);
 extern int strncasecmp(const char *s1, const char *s2, size_t n);
-#endif
 
 /*
@@ -64,4 +62,6 @@
 extern char *rindex(const char *s, int c);
 
+__C_DECLS_END;
+
 #endif  // POSIX_STRINGS_H_
 
Index: uspace/lib/posix/include/posix/sys/mman.h
===================================================================
--- uspace/lib/posix/include/posix/sys/mman.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/sys/mman.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,7 +37,7 @@
 
 #include <sys/types.h>
-#include <abi/mm/as.h>
+#include <_bits/decls.h>
 
-#define MAP_FAILED ((void *) -1)
+#define MAP_FAILED  ((void *) -1)
 
 #define MAP_SHARED     (1 << 0)
@@ -45,14 +45,12 @@
 #define MAP_FIXED      (1 << 2)
 #define MAP_ANONYMOUS  (1 << 3)
-#define MAP_ANON MAP_ANONYMOUS
+#define MAP_ANON       MAP_ANONYMOUS
 
-#undef PROT_NONE
-#undef PROT_READ
-#undef PROT_WRITE
-#undef PROT_EXEC
-#define PROT_NONE  0
-#define PROT_READ  AS_AREA_READ
-#define PROT_WRITE AS_AREA_WRITE
-#define PROT_EXEC  AS_AREA_EXEC
+#define PROT_NONE   0
+#define PROT_READ   1
+#define PROT_WRITE  2
+#define PROT_EXEC   4
+
+__C_DECLS_BEGIN;
 
 extern void *mmap(void *start, size_t length, int prot, int flags, int fd,
@@ -60,4 +58,6 @@
 extern int munmap(void *start, size_t length);
 
+__C_DECLS_END;
+
 #endif /* POSIX_SYS_MMAN_H_ */
 
Index: uspace/lib/posix/include/posix/sys/stat.h
===================================================================
--- uspace/lib/posix/include/posix/sys/stat.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/sys/stat.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,15 +39,8 @@
 #include <sys/types.h>
 #include <time.h>
+#include <_bits/decls.h>
 
 /* values are the same as on Linux */
 
-#undef S_IFMT
-#undef S_IFSOCK
-#undef S_IFLNK
-#undef S_IFREG
-#undef S_IFBLK
-#undef S_IFDIR
-#undef S_IFCHR
-#undef S_IFIFO
 #define S_IFMT     0170000   /* all file types */
 #define S_IFSOCK   0140000   /* socket */
@@ -59,15 +52,8 @@
 #define S_IFIFO    0010000   /* FIFO */
 
-#undef S_ISUID
-#undef S_ISGID
-#undef S_ISVTX
 #define S_ISUID    0004000   /* SUID */
 #define S_ISGID    0002000   /* SGID */
 #define S_ISVTX    0001000   /* sticky */
 
-#undef S_IRWXU
-#undef S_IRUSR
-#undef S_IWUSR
-#undef S_IXUSR
 #define S_IRWXU    00700     /* owner permissions */
 #define S_IRUSR    00400
@@ -75,8 +61,4 @@
 #define S_IXUSR    00100
 
-#undef S_IRWXG
-#undef S_IRGRP
-#undef S_IWGRP
-#undef S_IXGRP
 #define S_IRWXG    00070     /* group permissions */
 #define S_IRGRP    00040
@@ -84,8 +66,4 @@
 #define S_IXGRP    00010
 
-#undef S_IRWXO
-#undef S_IROTH
-#undef S_IWOTH
-#undef S_IXOTH
 #define S_IRWXO    00007     /* other permissions */
 #define S_IROTH    00004
@@ -93,11 +71,4 @@
 #define S_IXOTH    00001
 
-#undef S_ISREG
-#undef S_ISDIR
-#undef S_ISCHR
-#undef S_ISBLK
-#undef S_ISFIFO
-#undef S_ISLNK
-#undef S_ISSOCK
 #define S_ISREG(m) ((m & S_IFREG) != 0)
 #define S_ISDIR(m) ((m & S_IFDIR) != 0)
@@ -107,4 +78,6 @@
 #define S_ISLNK(m) ((m & S_IFLNK) != 0) /* symbolic link? (Not in POSIX.1-1996.) */
 #define S_ISSOCK(m) ((m & S_IFSOCK) != 0) /* socket? (Not in POSIX.1-1996.) */
+
+__C_DECLS_BEGIN;
 
 struct stat {
@@ -131,4 +104,6 @@
 extern int mkdir(const char *path, mode_t mode);
 
+__C_DECLS_END;
+
 #endif /* POSIX_SYS_STAT_H */
 
Index: uspace/lib/posix/include/posix/sys/time.h
===================================================================
--- uspace/lib/posix/include/posix/sys/time.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/sys/time.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,4 +35,7 @@
 
 #include <time.h>
+#include <_bits/decls.h>
+
+__C_DECLS_BEGIN;
 
 struct timeval {
@@ -43,4 +46,6 @@
 extern int gettimeofday(struct timeval *, void *);
 
+__C_DECLS_END;
+
 #endif
 
Index: uspace/lib/posix/include/posix/sys/types.h
===================================================================
--- uspace/lib/posix/include/posix/sys/types.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/sys/types.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,5 +37,10 @@
 #define POSIX_SYS_TYPES_H_
 
-#include <types/common.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <_bits/ssize_t.h>
+#include <_bits/decls.h>
+
+__C_DECLS_BEGIN;
 
 typedef unsigned int ino_t;
@@ -46,5 +51,5 @@
 typedef long blkcnt_t;
 typedef int pid_t;
-typedef sysarg_t dev_t;
+typedef unsigned long dev_t;
 typedef unsigned int mode_t;
 
@@ -55,5 +60,5 @@
 #endif
 
-#ifdef _LARGEFILE64_SOURCE
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
 typedef int64_t off64_t;
 #endif
@@ -67,4 +72,6 @@
 typedef long suseconds_t;
 
+__C_DECLS_END;
+
 #endif /* POSIX_SYS_TYPES_H_ */
 
Index: uspace/lib/posix/include/posix/sys/wait.h
===================================================================
--- uspace/lib/posix/include/posix/sys/wait.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/sys/wait.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,13 +37,12 @@
 
 #include <sys/types.h>
+#include <_bits/decls.h>
 
-#undef WIFEXITED
-#undef WEXITSTATUS
-#undef WIFSIGNALED
-#undef WTERMSIG
 #define WIFEXITED(status) __posix_wifexited(status)
 #define WEXITSTATUS(status) __posix_wexitstatus(status)
 #define WIFSIGNALED(status) __posix_wifsignaled(status)
 #define WTERMSIG(status) __posix_wtermsig(status)
+
+__C_DECLS_BEGIN;
 
 extern int __posix_wifexited(int status);
@@ -55,4 +54,6 @@
 extern pid_t waitpid(pid_t pid, int *stat_ptr, int options);
 
+__C_DECLS_END;
+
 #endif /* POSIX_SYS_WAIT_H_ */
 
Index: uspace/lib/posix/include/posix/time.h
===================================================================
--- uspace/lib/posix/include/posix/time.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/time.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -41,4 +41,10 @@
 #include <libc/time.h>
 
+#define CLOCK_REALTIME ((clockid_t) 0)
+
+#define ASCTIME_BUF_LEN  26
+
+__C_DECLS_BEGIN;
+
 #ifndef __locale_t_defined
 #define __locale_t_defined
@@ -46,12 +52,5 @@
 #endif
 
-#ifndef POSIX_SIGNAL_H_
 struct sigevent;
-#endif
-
-#undef CLOCK_REALTIME
-#define CLOCK_REALTIME ((clockid_t) 0)
-
-#define ASCTIME_BUF_LEN  26
 
 struct itimerspec {
@@ -97,4 +96,6 @@
     const struct timespec *rqtp, struct timespec *rmtp);
 
+__C_DECLS_END;
+
 #endif  // POSIX_TIME_H_
 
Index: uspace/lib/posix/include/posix/ucontext.h
===================================================================
--- uspace/lib/posix/include/posix/ucontext.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/ucontext.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,4 +37,7 @@
 
 #include <sys/types.h>
+#include <_bits/decls.h>
+
+__C_DECLS_BEGIN;
 
 typedef int sig_atomic_t;
@@ -71,4 +74,6 @@
 } ucontext_t;
 
+__C_DECLS_END;
+
 #endif
 
Index: uspace/lib/posix/include/posix/unistd.h
===================================================================
--- uspace/lib/posix/include/posix/unistd.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/unistd.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -47,4 +47,16 @@
 #define _exit exit
 
+/* Standard Streams */
+#define STDIN_FILENO (fileno(stdin))
+#define STDOUT_FILENO (fileno(stdout))
+#define STDERR_FILENO (fileno(stderr))
+
+#define	F_OK 0 /* Test for existence. */
+#define	X_OK 1 /* Test for execute permission. */
+#define	W_OK 2 /* Test for write permission. */
+#define	R_OK 4 /* Test for read permission. */
+
+__C_DECLS_BEGIN;
+
 extern char *optarg;
 extern int optind, opterr, optopt;
@@ -86,5 +98,9 @@
 extern int dup2(int fildes, int fildes2);
 
-#ifdef _LARGEFILE64_SOURCE
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+// FIXME: this should just be defined in <sys/types.h>, but for some reason
+//        build of coastline binutils on mips32 doesn't see the definition there
+typedef int64_t off64_t;
+
 extern off64_t lseek64(int fildes, off64_t offset, int whence);
 extern int ftruncate64(int fildes, off64_t length);
@@ -106,21 +122,5 @@
 #endif
 
-/* Standard Streams */
-#undef STDIN_FILENO
-#define STDIN_FILENO (fileno(stdin))
-#undef STDOUT_FILENO
-#define STDOUT_FILENO (fileno(stdout))
-#undef STDERR_FILENO
-#define STDERR_FILENO (fileno(stderr))
-
 /* File Accessibility */
-#undef F_OK
-#undef X_OK
-#undef W_OK
-#undef R_OK
-#define	F_OK 0 /* Test for existence. */
-#define	X_OK 1 /* Test for execute permission. */
-#define	W_OK 2 /* Test for write permission. */
-#define	R_OK 4 /* Test for read permission. */
 extern int access(const char *path, int amode);
 
@@ -171,4 +171,6 @@
 extern unsigned int alarm(unsigned int);
 
+__C_DECLS_END;
+
 #endif /* POSIX_UNISTD_H_ */
 
Index: uspace/lib/posix/src/internal/common.h
===================================================================
--- uspace/lib/posix/src/internal/common.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/src/internal/common.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -67,4 +67,7 @@
 }
 
+// TODO: Remove this arbitrary limit.
+#define VFS_MAX_OPEN_FILES 128
+
 extern aoff64_t posix_pos[VFS_MAX_OPEN_FILES];
 
Index: uspace/lib/posix/src/string.c
===================================================================
--- uspace/lib/posix/src/string.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/src/string.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -135,38 +135,4 @@
 
 /**
- * Duplicate a string.
- *
- * @param s String to be duplicated.
- * @return Newly allocated copy of the string.
- */
-char *strdup(const char *s)
-{
-	return strndup(s, SIZE_MAX);
-}
-
-/**
- * Duplicate a specific number of bytes from a string.
- *
- * @param s String to be duplicated.
- * @param n Maximum length of the resulting string..
- * @return Newly allocated string copy of length at most n.
- */
-char *strndup(const char *s, size_t n)
-{
-	assert(s != NULL);
-
-	size_t len = strnlen(s, n);
-	char *dup = malloc(len + 1);
-	if (dup == NULL) {
-		return NULL;
-	}
-
-	memcpy(dup, s, len);
-	dup[len] = '\0';
-
-	return dup;
-}
-
-/**
  * Scan string for a first occurence of a character.
  *
@@ -225,25 +191,4 @@
 
 	return EOK;
-}
-
-/**
- * Get limited length of the string.
- *
- * @param s String which length shall be determined.
- * @param n Maximum number of bytes that can be examined to determine length.
- * @return The lower of either string length or n limit.
- */
-size_t strnlen(const char *s, size_t n)
-{
-	assert(s != NULL);
-
-	for (size_t sz = 0; sz < n; ++sz) {
-
-		if (s[sz] == '\0') {
-			return sz;
-		}
-	}
-
-	return n;
 }
 
Index: uspace/lib/posix/src/sys/mman.c
===================================================================
--- uspace/lib/posix/src/sys/mman.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/src/sys/mman.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,4 +39,20 @@
 #include <unistd.h>
 
+static int _prot_to_as(int prot)
+{
+	int ret = 0;
+
+	if (prot & PROT_READ)
+		ret |= AS_AREA_READ;
+
+	if (prot & PROT_WRITE)
+		ret |= AS_AREA_WRITE;
+
+	if (prot & PROT_EXEC)
+		ret |= AS_AREA_EXEC;
+
+	return ret;
+}
+
 void *mmap(void *start, size_t length, int prot, int flags, int fd,
     off_t offset)
@@ -53,5 +69,5 @@
 		return MAP_FAILED;
 
-	return as_area_create(start, length, prot, AS_AREA_UNPAGED);
+	return as_area_create(start, length, _prot_to_as(prot), AS_AREA_UNPAGED);
 }
 
Index: uspace/lib/posix/src/time.c
===================================================================
--- uspace/lib/posix/src/time.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/src/time.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -46,5 +46,5 @@
 #include <assert.h>
 
-#include <async.h>
+#include <fibril.h>
 #include <malloc.h>
 #include <task.h>
Index: uspace/lib/posix/src/unistd.c
===================================================================
--- uspace/lib/posix/src/unistd.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/src/unistd.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -47,4 +47,5 @@
 #include <fcntl.h>
 
+#include <fibril.h>
 #include <task.h>
 #include <stats.h>
Index: uspace/lib/sif/src/sif.c
===================================================================
--- uspace/lib/sif/src/sif.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/sif/src/sif.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -894,5 +894,5 @@
 	sif_node_t *node = NULL;
 	sif_node_t *child;
-	sif_attr_t *attr;
+	sif_attr_t *attr = NULL;
 	char *ntype;
 	int c;
Index: uspace/lib/untar/untar.c
===================================================================
--- uspace/lib/untar/untar.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/untar/untar.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -154,5 +154,5 @@
 		return rc;
 	}
-	
+
 	while (true) {
 		tar_header_raw_t header_raw;
Index: uspace/lib/usb/include/usb/request.h
===================================================================
--- uspace/lib/usb/include/usb/request.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/usb/include/usb/request.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -117,5 +117,5 @@
 } __attribute__((packed)) usb_device_request_setup_packet_t;
 
-static_assert(sizeof(usb_device_request_setup_packet_t) == USB_SETUP_PACKET_SIZE);
+static_assert(sizeof(usb_device_request_setup_packet_t) == USB_SETUP_PACKET_SIZE, "");
 
 #define GET_DEVICE_DESC(size) \
Index: uspace/lib/usbdev/src/request.c
===================================================================
--- uspace/lib/usbdev/src/request.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/usbdev/src/request.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -45,5 +45,5 @@
 #define MAX_DATA_LENGTH ((size_t)(0xFFFF))
 
-static_assert(sizeof(usb_device_request_setup_packet_t) == 8);
+static_assert(sizeof(usb_device_request_setup_packet_t) == 8, "");
 
 /** Generic wrapper for SET requests using standard control request format.
Index: uspace/lib/usbhost/include/usb/host/hcd.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/hcd.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/usbhost/include/usb/host/hcd.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,4 +38,5 @@
 #define LIBUSBHOST_HOST_HCD_H
 
+#include <fibril.h>
 #include <ddf/driver.h>
 #include <usb/request.h>
Index: uspace/lib/usbhost/src/hcd.c
===================================================================
--- uspace/lib/usbhost/src/hcd.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/usbhost/src/hcd.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -101,5 +101,5 @@
 	hc_device_t *hcd = dev_to_hcd(dev);
 
-	const uint32_t status = IPC_GET_ARG1(*call);
+	const uint32_t status = ipc_get_arg1(call);
 	hcd->bus->ops->interrupt(hcd->bus, status);
 }
Index: uspace/lib/usbvirt/src/device.c
===================================================================
--- uspace/lib/usbvirt/src/device.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/usbvirt/src/device.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -66,5 +66,5 @@
 		bool processed = usbvirt_ipc_handle_call(DEV, &call);
 		if (!processed) {
-			if (!IPC_GET_IMETHOD(call)) {
+			if (!ipc_get_imethod(&call)) {
 				async_answer_0(&call, EOK);
 				return;
Index: uspace/lib/usbvirt/src/ipc_dev.c
===================================================================
--- uspace/lib/usbvirt/src/ipc_dev.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/usbvirt/src/ipc_dev.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -133,5 +133,5 @@
 static void ipc_control_write(usbvirt_device_t *dev, ipc_call_t *icall)
 {
-	size_t data_buffer_len = IPC_GET_ARG1(*icall);
+	size_t data_buffer_len = ipc_get_arg1(icall);
 	errno_t rc;
 
@@ -177,5 +177,5 @@
     usb_transfer_type_t transfer_type, ipc_call_t *icall)
 {
-	usb_endpoint_t endpoint = IPC_GET_ARG1(*icall);
+	usb_endpoint_t endpoint = ipc_get_arg1(icall);
 
 	errno_t rc;
@@ -220,5 +220,5 @@
     usb_transfer_type_t transfer_type, ipc_call_t *icall)
 {
-	usb_endpoint_t endpoint = IPC_GET_ARG1(*icall);
+	usb_endpoint_t endpoint = ipc_get_arg1(icall);
 
 	void *data_buffer = NULL;
@@ -250,5 +250,5 @@
 bool usbvirt_ipc_handle_call(usbvirt_device_t *dev, ipc_call_t *call)
 {
-	switch (IPC_GET_IMETHOD(*call)) {
+	switch (ipc_get_imethod(call)) {
 	case IPC_M_USBVIRT_GET_NAME:
 		ipc_get_name(dev, call);
Index: uspace/lib/usbvirt/src/ipc_hc.c
===================================================================
--- uspace/lib/usbvirt/src/ipc_hc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/usbvirt/src/ipc_hc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -113,5 +113,5 @@
 
 	if (data_transferred_size != NULL)
-		*data_transferred_size = IPC_GET_ARG2(data_request_call);
+		*data_transferred_size = ipc_get_arg2(&data_request_call);
 
 	return EOK;
@@ -250,5 +250,5 @@
 
 	if (act_size != NULL)
-		*act_size = IPC_GET_ARG2(data_request_call);
+		*act_size = ipc_get_arg2(&data_request_call);
 
 	return EOK;
Index: uspace/lib/virtio/virtio-pci.h
===================================================================
--- uspace/lib/virtio/virtio-pci.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/virtio/virtio-pci.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -60,4 +60,7 @@
 
 #define VIRTIO_FEATURES_0_31	0
+#define VIRTIO_FEATURES_32_63	1
+
+#define VIRTIO_F_VERSION_1	1
 
 /** Common configuration structure layout according to VIRTIO version 1.0 */
Index: uspace/lib/virtio/virtio.c
===================================================================
--- uspace/lib/virtio/virtio.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/virtio/virtio.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -50,5 +50,5 @@
  *                     buffers.
  *
- * The buffers can be deallocated by virtio_net_teardown_bufs().
+ * The buffers can be deallocated by virtio_teardown_dma_bufs().
  *
  * @return  EOK on success or error code.
@@ -63,5 +63,6 @@
 	uintptr_t phys;
 	errno_t rc = dmamem_map_anonymous(buffers * size, 0,
-	    write ? AS_AREA_WRITE : AS_AREA_READ, 0, &phys, &virt);
+	    write ? AS_AREA_WRITE | AS_AREA_READ : AS_AREA_READ, 0, &phys,
+	    &virt);
 	if (rc != EOK)
 		return rc;
@@ -83,7 +84,7 @@
  *
  * @param buf[in]  Array holding the virtual addresses of the DMA buffers
- *                 previously allocated by virtio_net_setup_bufs().
- */
-extern void virtio_teardown_dma_bufs(void *buf[])
+ *                 previously allocated by virtio_setup_dma_bufs().
+ */
+void virtio_teardown_dma_bufs(void *buf[])
 {
 	if (buf[0]) {
@@ -319,5 +320,10 @@
 	uint32_t device_features = pio_read_le32(&cfg->device_feature);
 
-	ddf_msg(LVL_NOTE, "offered features %x", device_features);
+	uint32_t reserved_features = VIRTIO_F_VERSION_1;
+	pio_write_le32(&cfg->device_feature_select, VIRTIO_FEATURES_32_63);
+	uint32_t device_reserved_features = pio_read_le32(&cfg->device_feature);
+
+	ddf_msg(LVL_NOTE, "offered features %x, reserved features %x",
+	    device_features, device_reserved_features);
 
 	if (features != (features & device_features))
@@ -325,9 +331,16 @@
 	features &= device_features;
 
+	if (reserved_features != (reserved_features & device_reserved_features))
+		return ENOTSUP;
+	reserved_features &= device_reserved_features;
+
 	/* 4. Write the accepted feature flags */
 	pio_write_le32(&cfg->driver_feature_select, VIRTIO_FEATURES_0_31);
 	pio_write_le32(&cfg->driver_feature, features);
-
-	ddf_msg(LVL_NOTE, "accepted features %x", features);
+	pio_write_le32(&cfg->driver_feature_select, VIRTIO_FEATURES_32_63);
+	pio_write_le32(&cfg->driver_feature, reserved_features);
+
+	ddf_msg(LVL_NOTE, "accepted features %x, reserved features %x",
+	    features, reserved_features);
 
 	/* 5. Set FEATURES_OK */
Index: uspace/srv/audio/hound/audio_device.c
===================================================================
--- uspace/srv/audio/hound/audio_device.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/audio/hound/audio_device.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -275,5 +275,5 @@
 		async_answer_0(&call, EOK);
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case PCM_EVENT_FRAMES_PLAYED:
 			getuptime(&time1);
Index: uspace/srv/audio/hound/hound.c
===================================================================
--- uspace/srv/audio/hound/hound.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/audio/hound/hound.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -146,4 +146,5 @@
 static void hound_remove_source_internal(hound_t *hound, audio_source_t *source)
 {
+	assert(fibril_mutex_is_locked(&hound->list_guard));
 	log_verbose("Removing source '%s'.", source->name);
 	if (!list_empty(&source->connections))
Index: uspace/srv/bd/sata_bd/sata_bd.c
===================================================================
--- uspace/srv/bd/sata_bd/sata_bd.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/bd/sata_bd/sata_bd.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -173,5 +173,5 @@
 
 	/* Get the device service ID. */
-	dsid = IPC_GET_ARG2(*icall);
+	dsid = ipc_get_arg2(icall);
 
 	/* Determine which disk device is the client connecting to. */
Index: uspace/srv/bd/vbd/disk.c
===================================================================
--- uspace/srv/bd/vbd/disk.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/bd/vbd/disk.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1077,5 +1077,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_bd_conn()");
 
-	svcid = IPC_GET_ARG2(*icall);
+	svcid = ipc_get_arg2(icall);
 
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_bd_conn() - svcid=%zu", svcid);
Index: uspace/srv/bd/vbd/vbd.c
===================================================================
--- uspace/srv/bd/vbd/vbd.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/bd/vbd/vbd.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -129,5 +129,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_disk_info_srv()");
 
-	disk_sid = IPC_GET_ARG1(*icall);
+	disk_sid = ipc_get_arg1(icall);
 	rc = vbds_disk_info(disk_sid, &dinfo);
 	if (rc != EOK) {
@@ -169,6 +169,6 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_label_create_srv()");
 
-	disk_sid = IPC_GET_ARG1(*icall);
-	ltype = IPC_GET_ARG2(*icall);
+	disk_sid = ipc_get_arg1(icall);
+	ltype = ipc_get_arg2(icall);
 	rc = vbds_label_create(disk_sid, ltype);
 	async_answer_0(icall, rc);
@@ -182,5 +182,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_label_delete_srv()");
 
-	disk_sid = IPC_GET_ARG1(*icall);
+	disk_sid = ipc_get_arg1(icall);
 	rc = vbds_label_delete(disk_sid);
 	async_answer_0(icall, rc);
@@ -203,5 +203,5 @@
 	}
 
-	sid = IPC_GET_ARG1(*icall);
+	sid = ipc_get_arg1(icall);
 
 	category_id_t *id_buf = (category_id_t *) malloc(size);
@@ -233,5 +233,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_part_get_info_srv()");
 
-	part = IPC_GET_ARG1(*icall);
+	part = ipc_get_arg1(icall);
 	rc = vbds_part_get_info(part, &pinfo);
 	if (rc != EOK) {
@@ -274,5 +274,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_part_create_srv()");
 
-	disk_sid = IPC_GET_ARG1(*icall);
+	disk_sid = ipc_get_arg1(icall);
 
 	ipc_call_t call;
@@ -313,5 +313,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_part_delete_srv()");
 
-	part = IPC_GET_ARG1(*icall);
+	part = ipc_get_arg1(icall);
 	rc = vbds_part_delete(part);
 	async_answer_0(icall, rc);
@@ -327,6 +327,6 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_suggest_ptype_srv()");
 
-	disk_sid = IPC_GET_ARG1(*icall);
-	pcnt = IPC_GET_ARG2(*icall);
+	disk_sid = ipc_get_arg1(icall);
+	pcnt = ipc_get_arg2(icall);
 
 	rc = vbds_suggest_ptype(disk_sid, pcnt, &ptype);
@@ -370,5 +370,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
@@ -418,5 +418,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_client_conn()");
 
-	sid = (service_id_t) IPC_GET_ARG2(*icall);
+	sid = (service_id_t) ipc_get_arg2(icall);
 
 	if (sid == ctl_sid)
Index: uspace/srv/clipboard/clipboard.c
===================================================================
--- uspace/srv/clipboard/clipboard.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/clipboard/clipboard.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -53,5 +53,5 @@
 	size_t size;
 
-	switch (IPC_GET_ARG1(*req)) {
+	switch (ipc_get_arg1(req)) {
 	case CLIPBOARD_TAG_NONE:
 		fibril_mutex_lock(&clip_mtx);
@@ -99,5 +99,5 @@
 
 	/* Check for clipboard data tag compatibility */
-	switch (IPC_GET_ARG1(*req)) {
+	switch (ipc_get_arg1(req)) {
 	case CLIPBOARD_TAG_DATA:
 		if (!async_data_read_receive(&call, &size)) {
@@ -161,10 +161,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case CLIPBOARD_PUT_DATA:
 			clip_put_data(&call);
Index: uspace/srv/devman/client_conn.c
===================================================================
--- uspace/srv/devman/client_conn.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/devman/client_conn.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -102,6 +102,6 @@
 static void devman_fun_get_match_id(ipc_call_t *icall)
 {
-	devman_handle_t handle = IPC_GET_ARG1(*icall);
-	size_t index = IPC_GET_ARG2(*icall);
+	devman_handle_t handle = ipc_get_arg1(icall);
+	size_t index = ipc_get_arg2(icall);
 	void *buffer = NULL;
 
@@ -165,5 +165,5 @@
 static void devman_fun_get_name(ipc_call_t *icall)
 {
-	devman_handle_t handle = IPC_GET_ARG1(*icall);
+	devman_handle_t handle = ipc_get_arg1(icall);
 
 	fun_node_t *fun = find_fun_node(&device_tree, handle);
@@ -218,5 +218,5 @@
 static void devman_fun_get_driver_name(ipc_call_t *icall)
 {
-	devman_handle_t handle = IPC_GET_ARG1(*icall);
+	devman_handle_t handle = ipc_get_arg1(icall);
 
 	fun_node_t *fun = find_fun_node(&device_tree, handle);
@@ -283,5 +283,5 @@
 static void devman_fun_get_path(ipc_call_t *icall)
 {
-	devman_handle_t handle = IPC_GET_ARG1(*icall);
+	devman_handle_t handle = ipc_get_arg1(icall);
 
 	fun_node_t *fun = find_fun_node(&device_tree, handle);
@@ -340,5 +340,5 @@
 	fibril_rwlock_read_lock(&device_tree.rwlock);
 
-	dev = find_dev_node_no_lock(&device_tree, IPC_GET_ARG1(*icall));
+	dev = find_dev_node_no_lock(&device_tree, ipc_get_arg1(icall));
 	if (dev == NULL || dev->state == DEVICE_REMOVED) {
 		fibril_rwlock_read_unlock(&device_tree.rwlock);
@@ -374,5 +374,5 @@
 
 	dev_node_t *dev = find_dev_node_no_lock(&device_tree,
-	    IPC_GET_ARG1(*icall));
+	    ipc_get_arg1(icall));
 	if (dev == NULL || dev->state == DEVICE_REMOVED) {
 		fibril_rwlock_read_unlock(&device_tree.rwlock);
@@ -413,5 +413,5 @@
 	fibril_rwlock_read_lock(&device_tree.rwlock);
 
-	fun = find_fun_node_no_lock(&device_tree, IPC_GET_ARG1(*icall));
+	fun = find_fun_node_no_lock(&device_tree, ipc_get_arg1(icall));
 	if (fun == NULL || fun->state == FUN_REMOVED) {
 		fibril_rwlock_read_unlock(&device_tree.rwlock);
@@ -442,5 +442,5 @@
 	errno_t rc;
 
-	fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));
+	fun = find_fun_node(&device_tree, ipc_get_arg1(icall));
 	if (fun == NULL) {
 		async_answer_0(icall, ENOENT);
@@ -467,5 +467,5 @@
 	errno_t rc;
 
-	fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));
+	fun = find_fun_node(&device_tree, ipc_get_arg1(icall));
 	if (fun == NULL) {
 		async_answer_0(icall, ENOENT);
@@ -484,5 +484,5 @@
 	fun_node_t *fun;
 
-	fun = find_loc_tree_function(&device_tree, IPC_GET_ARG1(*icall));
+	fun = find_loc_tree_function(&device_tree, ipc_get_arg1(icall));
 
 	if (fun == NULL) {
@@ -550,5 +550,5 @@
 	}
 
-	driver_t *drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall));
+	driver_t *drv = driver_find(&drivers_list, ipc_get_arg1(icall));
 	if (drv == NULL) {
 		async_answer_0(&call, ENOENT);
@@ -604,6 +604,6 @@
 static void devman_driver_get_match_id(ipc_call_t *icall)
 {
-	devman_handle_t handle = IPC_GET_ARG1(*icall);
-	size_t index = IPC_GET_ARG2(*icall);
+	devman_handle_t handle = ipc_get_arg1(icall);
+	size_t index = ipc_get_arg2(icall);
 
 	driver_t *drv = driver_find(&drivers_list, handle);
@@ -655,5 +655,5 @@
 static void devman_driver_get_name(ipc_call_t *icall)
 {
-	devman_handle_t handle = IPC_GET_ARG1(*icall);
+	devman_handle_t handle = ipc_get_arg1(icall);
 
 	driver_t *drv = driver_find(&drivers_list, handle);
@@ -697,5 +697,5 @@
 	driver_t *drv;
 
-	drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall));
+	drv = driver_find(&drivers_list, ipc_get_arg1(icall));
 	if (drv == NULL) {
 		async_answer_0(icall, ENOENT);
@@ -712,5 +712,5 @@
 	errno_t rc;
 
-	drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall));
+	drv = driver_find(&drivers_list, ipc_get_arg1(icall));
 	if (drv == NULL) {
 		async_answer_0(icall, ENOENT);
@@ -731,5 +731,5 @@
 	errno_t rc;
 
-	drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall));
+	drv = driver_find(&drivers_list, ipc_get_arg1(icall));
 	if (drv == NULL) {
 		async_answer_0(icall, ENOENT);
@@ -754,10 +754,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case DEVMAN_DEVICE_GET_HANDLE:
 			devman_function_get_handle(&call);
Index: uspace/srv/devman/devtree.c
===================================================================
--- uspace/srv/devman/devtree.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/devman/devtree.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -42,8 +42,8 @@
 /* hash table operations */
 
-static inline size_t handle_key_hash(void *key)
-{
-	devman_handle_t handle = *(devman_handle_t *)key;
-	return handle;
+static inline size_t handle_key_hash(const void *key)
+{
+	const devman_handle_t *handle = key;
+	return *handle;
 }
 
@@ -60,22 +60,22 @@
 }
 
-static bool devman_devices_key_equal(void *key, const ht_link_t *item)
-{
-	devman_handle_t handle = *(devman_handle_t *)key;
+static bool devman_devices_key_equal(const void *key, const ht_link_t *item)
+{
+	const devman_handle_t *handle = key;
 	dev_node_t *dev = hash_table_get_inst(item, dev_node_t, devman_dev);
-	return dev->handle == handle;
-}
-
-static bool devman_functions_key_equal(void *key, const ht_link_t *item)
-{
-	devman_handle_t handle = *(devman_handle_t *)key;
+	return dev->handle == *handle;
+}
+
+static bool devman_functions_key_equal(const void *key, const ht_link_t *item)
+{
+	const devman_handle_t *handle = key;
 	fun_node_t *fun = hash_table_get_inst(item, fun_node_t, devman_fun);
-	return fun->handle == handle;
-}
-
-static inline size_t service_id_key_hash(void *key)
-{
-	service_id_t service_id = *(service_id_t *)key;
-	return service_id;
+	return fun->handle == *handle;
+}
+
+static inline size_t service_id_key_hash(const void *key)
+{
+	const service_id_t *service_id = key;
+	return *service_id;
 }
 
@@ -86,9 +86,9 @@
 }
 
-static bool loc_functions_key_equal(void *key, const ht_link_t *item)
-{
-	service_id_t service_id = *(service_id_t *)key;
+static bool loc_functions_key_equal(const void *key, const ht_link_t *item)
+{
+	const service_id_t *service_id = key;
 	fun_node_t *fun = hash_table_get_inst(item, fun_node_t, loc_fun);
-	return fun->service_id == service_id;
+	return fun->service_id == *service_id;
 }
 
Index: uspace/srv/devman/drv_conn.c
===================================================================
--- uspace/srv/devman/drv_conn.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/devman/drv_conn.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -169,5 +169,5 @@
 
 	async_get_call(&call);
-	if (DEVMAN_ADD_MATCH_ID != IPC_GET_IMETHOD(call)) {
+	if (DEVMAN_ADD_MATCH_ID != ipc_get_imethod(&call)) {
 		log_msg(LOG_DEFAULT, LVL_ERROR,
 		    "Invalid protocol when trying to receive match id.");
@@ -185,5 +185,5 @@
 	async_answer_0(&call, EOK);
 
-	match_id->score = IPC_GET_ARG1(call);
+	match_id->score = ipc_get_arg1(&call);
 
 	char *match_id_str;
@@ -230,7 +230,7 @@
 static void devman_add_function(ipc_call_t *call)
 {
-	fun_type_t ftype = (fun_type_t) IPC_GET_ARG1(*call);
-	devman_handle_t dev_handle = IPC_GET_ARG2(*call);
-	sysarg_t match_count = IPC_GET_ARG3(*call);
+	fun_type_t ftype = (fun_type_t) ipc_get_arg1(call);
+	devman_handle_t dev_handle = ipc_get_arg2(call);
+	sysarg_t match_count = ipc_get_arg3(call);
 	dev_tree_t *tree = &device_tree;
 
@@ -330,5 +330,5 @@
 static void devman_add_function_to_cat(ipc_call_t *call)
 {
-	devman_handle_t handle = IPC_GET_ARG1(*call);
+	devman_handle_t handle = ipc_get_arg1(call);
 	category_id_t cat_id;
 	errno_t rc;
@@ -385,5 +385,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "devman_drv_fun_online()");
 
-	fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));
+	fun = find_fun_node(&device_tree, ipc_get_arg1(icall));
 	if (fun == NULL) {
 		async_answer_0(icall, ENOENT);
@@ -425,5 +425,5 @@
 	errno_t rc;
 
-	fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));
+	fun = find_fun_node(&device_tree, ipc_get_arg1(icall));
 	if (fun == NULL) {
 		async_answer_0(icall, ENOENT);
@@ -458,5 +458,5 @@
 static void devman_remove_function(ipc_call_t *call)
 {
-	devman_handle_t fun_handle = IPC_GET_ARG1(*call);
+	devman_handle_t fun_handle = ipc_get_arg1(call);
 	dev_tree_t *tree = &device_tree;
 	errno_t rc;
@@ -602,10 +602,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		if (IPC_GET_IMETHOD(call) != DEVMAN_DRIVER_REGISTER) {
+		if (ipc_get_imethod(&call) != DEVMAN_DRIVER_REGISTER) {
 			fibril_mutex_lock(&client->mutex);
 			driver = client->driver;
@@ -618,5 +618,5 @@
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case DEVMAN_DRIVER_REGISTER:
 			fibril_mutex_lock(&client->mutex);
Index: uspace/srv/devman/main.c
===================================================================
--- uspace/srv/devman/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/devman/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -67,5 +67,5 @@
 static void devman_connection_device(ipc_call_t *icall, void *arg)
 {
-	devman_handle_t handle = IPC_GET_ARG2(*icall);
+	devman_handle_t handle = ipc_get_arg2(icall);
 	dev_node_t *dev = NULL;
 
@@ -136,5 +136,5 @@
 
 	async_exch_t *exch = async_exchange_begin(driver->sess);
-	async_forward_fast(icall, exch, INTERFACE_DDF_CLIENT, handle, 0, IPC_FF_NONE);
+	async_forward_1(icall, exch, INTERFACE_DDF_CLIENT, handle, IPC_FF_NONE);
 	async_exchange_end(exch);
 
@@ -149,5 +149,5 @@
 static void devman_connection_parent(ipc_call_t *icall, void *arg)
 {
-	devman_handle_t handle = IPC_GET_ARG2(*icall);
+	devman_handle_t handle = ipc_get_arg2(icall);
 	dev_node_t *dev = NULL;
 
@@ -215,5 +215,5 @@
 
 	async_exch_t *exch = async_exchange_begin(driver->sess);
-	async_forward_fast(icall, exch, INTERFACE_DDF_DRIVER, fun_handle, 0, IPC_FF_NONE);
+	async_forward_1(icall, exch, INTERFACE_DDF_DRIVER, fun_handle, IPC_FF_NONE);
 	async_exchange_end(exch);
 
@@ -228,6 +228,6 @@
 static void devman_forward(ipc_call_t *icall, void *arg)
 {
-	iface_t iface = IPC_GET_ARG1(*icall);
-	service_id_t service_id = IPC_GET_ARG2(*icall);
+	iface_t iface = ipc_get_arg1(icall);
+	service_id_t service_id = ipc_get_arg2(icall);
 
 	fun_node_t *fun = find_loc_tree_function(&device_tree, service_id);
@@ -250,5 +250,5 @@
 
 	async_exch_t *exch = async_exchange_begin(driver->sess);
-	async_forward_fast(icall, exch, iface, handle, 0, IPC_FF_NONE);
+	async_forward_1(icall, exch, iface, handle, IPC_FF_NONE);
 	async_exchange_end(exch);
 
Index: uspace/srv/fs/cdfs/cdfs_ops.c
===================================================================
--- uspace/srv/fs/cdfs/cdfs_ops.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/cdfs/cdfs_ops.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -285,7 +285,7 @@
 } ht_key_t;
 
-static size_t nodes_key_hash(void *k)
-{
-	ht_key_t *key = (ht_key_t *)k;
+static size_t nodes_key_hash(const void *k)
+{
+	const ht_key_t *key = k;
 	return hash_combine(key->service_id, key->index);
 }
@@ -297,8 +297,8 @@
 }
 
-static bool nodes_key_equal(void *k, const ht_link_t *item)
+static bool nodes_key_equal(const void *k, const ht_link_t *item)
 {
 	cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link);
-	ht_key_t *key = (ht_key_t *)k;
+	const ht_key_t *key = k;
 
 	return key->service_id == node->fs->service_id && key->index == node->index;
Index: uspace/srv/fs/exfat/exfat_idx.c
===================================================================
--- uspace/srv/fs/exfat/exfat_idx.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/exfat/exfat_idx.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -117,7 +117,7 @@
 } pos_key_t;
 
-static inline size_t pos_key_hash(void *key)
-{
-	pos_key_t *pos = (pos_key_t *)key;
+static inline size_t pos_key_hash(const void *key)
+{
+	const pos_key_t *pos = key;
 
 	size_t hash = 0;
@@ -139,7 +139,7 @@
 }
 
-static bool pos_key_equal(void *key, const ht_link_t *item)
-{
-	pos_key_t *pos = (pos_key_t *)key;
+static bool pos_key_equal(const void *key, const ht_link_t *item)
+{
+	const pos_key_t *pos = key;
 	exfat_idx_t *fidx = hash_table_get_inst(item, exfat_idx_t, uph_link);
 
@@ -168,7 +168,7 @@
 } idx_key_t;
 
-static size_t idx_key_hash(void *key_arg)
-{
-	idx_key_t *key = (idx_key_t *)key_arg;
+static size_t idx_key_hash(const void *key_arg)
+{
+	const idx_key_t *key = key_arg;
 	return hash_combine(key->service_id, key->index);
 }
@@ -180,8 +180,8 @@
 }
 
-static bool idx_key_equal(void *key_arg, const ht_link_t *item)
+static bool idx_key_equal(const void *key_arg, const ht_link_t *item)
 {
 	exfat_idx_t *fidx = hash_table_get_inst(item, exfat_idx_t, uih_link);
-	idx_key_t *key = (idx_key_t *)key_arg;
+	const idx_key_t *key = key_arg;
 
 	return key->index == fidx->index && key->service_id == fidx->service_id;
Index: uspace/srv/fs/fat/fat_idx.c
===================================================================
--- uspace/srv/fs/fat/fat_idx.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/fat/fat_idx.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -117,7 +117,7 @@
 } pos_key_t;
 
-static inline size_t pos_key_hash(void *key)
-{
-	pos_key_t *pos = (pos_key_t *)key;
+static inline size_t pos_key_hash(const void *key)
+{
+	const pos_key_t *pos = key;
 
 	size_t hash = 0;
@@ -139,7 +139,7 @@
 }
 
-static bool pos_key_equal(void *key, const ht_link_t *item)
-{
-	pos_key_t *pos = (pos_key_t *)key;
+static bool pos_key_equal(const void *key, const ht_link_t *item)
+{
+	const pos_key_t *pos = key;
 	fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uph_link);
 
@@ -168,7 +168,7 @@
 } idx_key_t;
 
-static size_t idx_key_hash(void *key_arg)
-{
-	idx_key_t *key = (idx_key_t *)key_arg;
+static size_t idx_key_hash(const void *key_arg)
+{
+	const idx_key_t *key = key_arg;
 	return hash_combine(key->service_id, key->index);
 }
@@ -180,8 +180,8 @@
 }
 
-static bool idx_key_equal(void *key_arg, const ht_link_t *item)
+static bool idx_key_equal(const void *key_arg, const ht_link_t *item)
 {
 	fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uih_link);
-	idx_key_t *key = (idx_key_t *)key_arg;
+	const idx_key_t *key = key_arg;
 
 	return key->index == fidx->index && key->service_id == fidx->service_id;
Index: uspace/srv/fs/locfs/locfs_ops.c
===================================================================
--- uspace/srv/fs/locfs/locfs_ops.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/locfs/locfs_ops.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -71,7 +71,8 @@
 /* Implementation of hash table interface for the nodes hash table. */
 
-static size_t services_key_hash(void *key)
-{
-	return *(service_id_t *)key;
+static size_t services_key_hash(const void *key)
+{
+	const service_id_t *k = key;
+	return *k;
 }
 
@@ -82,8 +83,9 @@
 }
 
-static bool services_key_equal(void *key, const ht_link_t *item)
-{
+static bool services_key_equal(const void *key, const ht_link_t *item)
+{
+	const service_id_t *k = key;
 	service_t *dev = hash_table_get_inst(item, service_t, link);
-	return (dev->service_id == *(service_id_t *)key);
+	return (dev->service_id == *k);
 }
 
@@ -583,5 +585,5 @@
 
 		/* Forward the IPC_M_DATA_READ request to the driver */
-		async_forward_fast(&call, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
+		async_forward_0(&call, exch, 0, IPC_FF_ROUTE_FROM_ME);
 
 		async_exchange_end(exch);
@@ -597,5 +599,5 @@
 			rc = ENOTSUP;
 
-		*rbytes = IPC_GET_ARG1(answer);
+		*rbytes = ipc_get_arg1(&answer);
 		return rc;
 	}
@@ -647,5 +649,5 @@
 
 		/* Forward the IPC_M_DATA_WRITE request to the driver */
-		async_forward_fast(&call, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
+		async_forward_0(&call, exch, 0, IPC_FF_ROUTE_FROM_ME);
 
 		async_exchange_end(exch);
@@ -661,5 +663,5 @@
 			rc = ENOTSUP;
 
-		*wbytes = IPC_GET_ARG1(answer);
+		*wbytes = ipc_get_arg1(&answer);
 		*nsize = 0;
 		return rc;
Index: uspace/srv/fs/mfs/mfs_ops.c
===================================================================
--- uspace/srv/fs/mfs/mfs_ops.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/mfs/mfs_ops.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -100,7 +100,7 @@
 
 static size_t
-open_nodes_key_hash(void *key)
-{
-	node_key_t *node_key = (node_key_t *)key;
+open_nodes_key_hash(const void *key)
+{
+	const node_key_t *node_key = key;
 	return hash_combine(node_key->service_id, node_key->index);
 }
@@ -114,7 +114,7 @@
 
 static bool
-open_nodes_key_equal(void *key, const ht_link_t *item)
-{
-	node_key_t *node_key = (node_key_t *)key;
+open_nodes_key_equal(const void *key, const ht_link_t *item)
+{
+	const node_key_t *node_key = key;
 	struct mfs_node *mnode = hash_table_get_inst(item, struct mfs_node, link);
 
Index: uspace/srv/fs/tmpfs/tmpfs_ops.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -147,7 +147,7 @@
 } node_key_t;
 
-static size_t nodes_key_hash(void *k)
-{
-	node_key_t *key = (node_key_t *)k;
+static size_t nodes_key_hash(const void *k)
+{
+	const node_key_t *key = k;
 	return hash_combine(key->service_id, key->index);
 }
@@ -159,8 +159,8 @@
 }
 
-static bool nodes_key_equal(void *key_arg, const ht_link_t *item)
+static bool nodes_key_equal(const void *key_arg, const ht_link_t *item)
 {
 	tmpfs_node_t *node = hash_table_get_inst(item, tmpfs_node_t, nh_link);
-	node_key_t *key = (node_key_t *)key_arg;
+	const node_key_t *key = key_arg;
 
 	return key->service_id == node->service_id && key->index == node->index;
Index: uspace/srv/fs/udf/udf.h
===================================================================
--- uspace/srv/fs/udf/udf.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/udf/udf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -70,5 +70,5 @@
 	uint32_t access_type;
 	uint32_t start;
-	uint32_t lenght;
+	uint32_t length;
 } udf_partition_t;
 
@@ -91,5 +91,5 @@
 	udf_unallocated_space_descriptor_t *uasd;
 	uint64_t uaspace_start;
-	uint64_t uaspace_lenght;
+	uint64_t uaspace_length;
 	uint8_t space_type;
 } udf_instance_t;
Index: uspace/srv/fs/udf/udf_file.c
===================================================================
--- uspace/srv/fs/udf/udf_file.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/udf/udf_file.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -114,5 +114,5 @@
 			if ((node->index >= node->instance->partitions[i].start) &&
 			    (node->index < node->instance->partitions[i].start +
-			    node->instance->partitions[i].lenght)) {
+			    node->instance->partitions[i].length)) {
 				if (node->instance->partitions[i].start >= min_start) {
 					min_start = node->instance->partitions[i].start;
@@ -258,9 +258,9 @@
 			    (udf_file_entry_descriptor_t *) block->data;
 			uint16_t icb_flag = FLE16(file->icbtag.flags) & UDF_ICBFLAG_MASK;
-			node->data_size = FLE64(file->info_lenght);
+			node->data_size = FLE64(file->info_length);
 			node->type = (file->icbtag.file_type == UDF_ICBTYPE_DIR) ? NODE_DIR : NODE_FILE;
 
 			rc = udf_read_allocation_sequence(node, (uint8_t *) file, icb_flag,
-			    FLE32(file->ea_lenght) + UDF_FE_OFFSET, FLE32(file->ad_lenght));
+			    FLE32(file->ea_length) + UDF_FE_OFFSET, FLE32(file->ad_length));
 			block_put(block);
 			return rc;
@@ -272,9 +272,9 @@
 			    (udf_extended_file_entry_descriptor_t *) block->data;
 			icb_flag = FLE16(efile->icbtag.flags) & UDF_ICBFLAG_MASK;
-			node->data_size = FLE64(efile->info_lenght);
+			node->data_size = FLE64(efile->info_length);
 			node->type = (efile->icbtag.file_type == UDF_ICBTYPE_DIR) ? NODE_DIR : NODE_FILE;
 
 			rc = udf_read_allocation_sequence(node, (uint8_t *) efile, icb_flag,
-			    FLE32(efile->ea_lenght) + UDF_EFE_OFFSET, FLE32(efile->ad_lenght));
+			    FLE32(efile->ea_length) + UDF_EFE_OFFSET, FLE32(efile->ad_length));
 			block_put(block);
 			return rc;
@@ -338,14 +338,14 @@
 
 		/* According to ECMA 167 4/14.4.9 */
-		size_t padding = 4 * (((*fid)->lenght_file_id +
-		    FLE16((*fid)->lenght_iu) + 38 + 3) / 4) -
-		    ((*fid)->lenght_file_id + FLE16((*fid)->lenght_iu) + 38);
-		size_t size_fid = (*fid)->lenght_file_id +
-		    FLE16((*fid)->lenght_iu) + padding + 38;
+		size_t padding = 4 * (((*fid)->length_file_id +
+		    FLE16((*fid)->length_iu) + 38 + 3) / 4) -
+		    ((*fid)->length_file_id + FLE16((*fid)->length_iu) + 38);
+		size_t size_fid = (*fid)->length_file_id +
+		    FLE16((*fid)->length_iu) + padding + 38;
 
 		fid_sum += size_fid;
 
 		/* aAcording to ECMA 167 4/8.6 */
-		if (((*fid)->lenght_file_id != 0) &&
+		if (((*fid)->length_file_id != 0) &&
 		    (((*fid)->file_characteristics & 4) == 0)) {
 			n++;
@@ -516,9 +516,9 @@
 
 			/* According to ECMA 167 4/14.4.9 */
-			size_t padding = 4 * (((*fid)->lenght_file_id +
-			    FLE16((*fid)->lenght_iu) + 38 + 3) / 4) -
-			    ((*fid)->lenght_file_id + FLE16((*fid)->lenght_iu) + 38);
-			size_t size_fid = (*fid)->lenght_file_id +
-			    FLE16((*fid)->lenght_iu) + padding + 38;
+			size_t padding = 4 * (((*fid)->length_file_id +
+			    FLE16((*fid)->length_iu) + 38 + 3) / 4) -
+			    ((*fid)->length_file_id + FLE16((*fid)->length_iu) + 38);
+			size_t size_fid = (*fid)->length_file_id +
+			    FLE16((*fid)->length_iu) + padding + 38;
 			if (buf_flag)
 				fid_sum += size_fid - *len;
@@ -527,5 +527,5 @@
 
 			/* According to ECMA 167 4/8.6 */
-			if (((*fid)->lenght_file_id != 0) &&
+			if (((*fid)->length_file_id != 0) &&
 			    (((*fid)->file_characteristics & 4) == 0)) {
 				(*n)++;
Index: uspace/srv/fs/udf/udf_file.h
===================================================================
--- uspace/srv/fs/udf/udf_file.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/udf/udf_file.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -99,7 +99,7 @@
 	uint16_t file_version_number;
 	uint8_t file_characteristics;
-	uint8_t lenght_file_id;
+	uint8_t length_file_id;
 	udf_long_ad_t icb;
-	uint16_t lenght_iu;
+	uint16_t length_iu;
 	uint8_t implementation_use[0];
 	udf_dstring file_id[0];
@@ -128,6 +128,6 @@
 	uint8_t record_format;
 	uint8_t record_display_attributes;
-	uint32_t record_lenght;
-	uint64_t info_lenght;
+	uint32_t record_length;
+	uint64_t info_length;
 	uint64_t lblocks_recorded;
 	udf_timestamp_t access_data_and_time;
@@ -138,6 +138,6 @@
 	udf_regid_t implementation_id;
 	uint64_t unique_id;
-	uint32_t ea_lenght;
-	uint32_t ad_lenght;
+	uint32_t ea_length;
+	uint32_t ad_length;
 	uint8_t extended_attributes [0];
 	uint8_t allocation_descriptors[0];
@@ -154,6 +154,6 @@
 	uint8_t record_format;
 	uint8_t record_display_attributes;
-	uint32_t record_lenght;
-	uint64_t info_lenght;
+	uint32_t record_length;
+	uint64_t info_length;
 	uint64_t object_size;
 	uint64_t lblocks_recorded;
@@ -166,6 +166,6 @@
 	udf_regid_t implementation_id;
 	uint64_t unique_id;
-	uint32_t ea_lenght;
-	uint32_t ad_lenght;
+	uint32_t ea_length;
+	uint32_t ad_length;
 	uint8_t extended_attributes [0];
 	uint8_t allocation_descriptors[0];
@@ -182,5 +182,5 @@
 	udf_descriptor_tag_t tag;
 	udf_icbtag_t icbtag;
-	uint32_t ad_lenght;
+	uint32_t ad_length;
 	uint8_t allocation_descriptors[0];
 } __attribute__((packed)) udf_unallocated_space_entry_descriptor_t;
Index: uspace/srv/fs/udf/udf_idx.c
===================================================================
--- uspace/srv/fs/udf/udf_idx.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/udf/udf_idx.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -63,13 +63,13 @@
 }
 
-static size_t udf_idx_key_hash(void *k)
-{
-	udf_ht_key_t *key = (udf_ht_key_t *) k;
+static size_t udf_idx_key_hash(const void *k)
+{
+	const udf_ht_key_t *key = k;
 	return hash_combine(key->service_id, key->index);
 }
 
-static bool udf_idx_key_equal(void *k, const ht_link_t *item)
-{
-	udf_ht_key_t *key = (udf_ht_key_t *) k;
+static bool udf_idx_key_equal(const void *k, const ht_link_t *item)
+{
+	const udf_ht_key_t *key = k;
 	udf_node_t *node = hash_table_get_inst(item, udf_node_t, link);
 
Index: uspace/srv/fs/udf/udf_ops.c
===================================================================
--- uspace/srv/fs/udf/udf_ops.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/udf/udf_ops.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -62,7 +62,4 @@
 #include "udf_osta.h"
 
-/** Mutex protecting the list of cached free nodes. */
-static FIBRIL_MUTEX_INITIALIZE(ffn_mutex);
-
 /** List of cached free nodes. */
 static LIST_INITIALIZE(ffn_list);
@@ -128,6 +125,6 @@
 
 		udf_to_unix_name(name, MAX_FILE_NAME_LEN,
-		    (char *) fid->implementation_use + FLE16(fid->lenght_iu),
-		    fid->lenght_file_id, &UDF_NODE(pfn)->instance->charset);
+		    (char *) fid->implementation_use + FLE16(fid->length_iu),
+		    fid->length_file_id, &UDF_NODE(pfn)->instance->charset);
 
 		if (str_casecmp(name, component) == 0) {
@@ -502,6 +499,6 @@
 
 			udf_to_unix_name(name, MAX_FILE_NAME_LEN,
-			    (char *) fid->implementation_use + FLE16(fid->lenght_iu),
-			    fid->lenght_file_id, &node->instance->charset);
+			    (char *) fid->implementation_use + FLE16(fid->length_iu),
+			    fid->length_file_id, &node->instance->charset);
 
 			async_data_read_finalize(&call, name, str_size(name) + 1);
Index: uspace/srv/fs/udf/udf_volume.c
===================================================================
--- uspace/srv/fs/udf/udf_volume.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/udf/udf_volume.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -386,9 +386,9 @@
 		udf_file_entry_descriptor_t *fed =
 		    (udf_file_entry_descriptor_t *) block->data;
-		uint32_t start_alloc = FLE32(fed->ea_lenght) + UDF_FE_OFFSET;
+		uint32_t start_alloc = FLE32(fed->ea_length) + UDF_FE_OFFSET;
 		udf_short_ad_t *short_d =
 		    (udf_short_ad_t *) ((uint8_t *) fed + start_alloc);
 		instance->partitions[id].start = FLE32(short_d->position);
-		instance->partitions[id].lenght = FLE32(short_d->length);
+		instance->partitions[id].length = FLE32(short_d->length);
 		break;
 
@@ -398,8 +398,8 @@
 		udf_extended_file_entry_descriptor_t *efed =
 		    (udf_extended_file_entry_descriptor_t *) block->data;
-		start_alloc = FLE32(efed->ea_lenght) + UDF_EFE_OFFSET;
+		start_alloc = FLE32(efed->ea_length) + UDF_EFE_OFFSET;
 		short_d = (udf_short_ad_t *) ((uint8_t *) efed + start_alloc);
 		instance->partitions[id].start = FLE32(short_d->position);
-		instance->partitions[id].lenght = FLE32(short_d->length);
+		instance->partitions[id].length = FLE32(short_d->length);
 		break;
 	}
@@ -503,5 +503,5 @@
 				instance->partitions[j].access_type =
 				    FLE32(pd[pd_num].access_type);
-				instance->partitions[j].lenght =
+				instance->partitions[j].length =
 				    FLE32(pd[pd_num].length);
 				instance->partitions[j].number =
@@ -518,5 +518,5 @@
 
 				instance->volumes[i].partition_cnt++;
-				idx += pm1->partition_map_lenght;
+				idx += pm1->partition_map_length;
 				continue;
 			}
@@ -586,5 +586,5 @@
 			    "found and skipped", i, pm->partition_map_type);
 
-			idx += pm->partition_map_lenght;
+			idx += pm->partition_map_length;
 		}
 	}
@@ -710,5 +710,5 @@
 				    FLE32(vol->partition.starting_location) +
 				    FLE32(phd->unallocated_space_table.position);
-				instance->uaspace_lenght =
+				instance->uaspace_length =
 				    FLE32(phd->unallocated_space_table.length);
 			}
@@ -724,5 +724,5 @@
 				    FLE32(vol->partition.starting_location) +
 				    FLE32(phd->unallocated_space_bitmap.position);
-				instance->uaspace_lenght =
+				instance->uaspace_length =
 				    FLE32(phd->unallocated_space_bitmap.length);
 			}
@@ -773,5 +773,5 @@
 			    sizeof(udf_extent_t)), sizeof(udf_common_descriptor_t));
 			instance->uaspace_start = pos;
-			instance->uaspace_lenght = sct;
+			instance->uaspace_length = sct;
 			instance->uasd = (udf_unallocated_space_descriptor_t *)
 			    malloc(sct * instance->sector_size);
Index: uspace/srv/fs/udf/udf_volume.h
===================================================================
--- uspace/srv/fs/udf/udf_volume.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/udf/udf_volume.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -49,5 +49,5 @@
 #define UDF_TAG_LVID  0x0009  /* Logical Volume Integrity Descriptor */
 
-/* Start adress of Anchor Volume Descriptor */
+/* Start address of Anchor Volume Descriptor */
 #define UDF_AVDP_SECTOR  256
 
@@ -165,10 +165,10 @@
 typedef struct udf_general_type {
 	uint8_t partition_map_type;
-	uint8_t partition_map_lenght;
+	uint8_t partition_map_length;
 } __attribute__((packed)) udf_general_type_t;
 
 typedef struct udf_type1_partition_map {
 	uint8_t partition_map_type;
-	uint8_t partition_map_lenght;
+	uint8_t partition_map_length;
 	uint16_t volume_sequence_number;
 	uint16_t partition_number;
Index: uspace/srv/hid/compositor/compositor.c
===================================================================
--- uspace/srv/hid/compositor/compositor.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/compositor/compositor.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -224,4 +224,5 @@
 
 	link_initialize(&win->link);
+	/* One initial reference will be for being in the window list */
 	refcount_init(&win->ref_cnt);
 	prodcons_initialize(&win->queue);
@@ -241,5 +242,8 @@
 static void window_destroy(window_t *win)
 {
-	if (!win || !refcount_down(&win->ref_cnt))
+	if (win == NULL)
+		return;
+
+	if (!refcount_down(&win->ref_cnt))
 		return;
 
@@ -630,8 +634,8 @@
 static void comp_window_damage(window_t *win, ipc_call_t *icall)
 {
-	double x = IPC_GET_ARG1(*icall);
-	double y = IPC_GET_ARG2(*icall);
-	double width = IPC_GET_ARG3(*icall);
-	double height = IPC_GET_ARG4(*icall);
+	double x = ipc_get_arg1(icall);
+	double y = ipc_get_arg2(icall);
+	double width = ipc_get_arg3(icall);
+	double height = ipc_get_arg4(icall);
 
 	if ((width == 0) || (height == 0)) {
@@ -651,6 +655,6 @@
 static void comp_window_grab(window_t *win, ipc_call_t *icall)
 {
-	sysarg_t pos_id = IPC_GET_ARG1(*icall);
-	sysarg_t grab_flags = IPC_GET_ARG2(*icall);
+	sysarg_t pos_id = ipc_get_arg1(icall);
+	sysarg_t grab_flags = ipc_get_arg2(icall);
 
 	/*
@@ -728,6 +732,6 @@
 
 	/* Create new surface for the resized window. */
-	surface_t *new_surface = surface_create(IPC_GET_ARG3(*icall),
-	    IPC_GET_ARG4(*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);
@@ -736,8 +740,8 @@
 	}
 
-	sysarg_t offset_x = IPC_GET_ARG1(*icall);
-	sysarg_t offset_y = IPC_GET_ARG2(*icall);
+	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);
+	    (window_placement_flags_t) ipc_get_arg5(icall);
 
 	comp_update_viewport_bound_rect();
@@ -892,4 +896,7 @@
 	}
 
+	/* Down refcount for removing from the window list */
+	window_destroy(win);
+
 	comp_damage(x, y, width, height);
 	async_answer_0(icall, EOK);
@@ -914,5 +921,5 @@
 {
 	ipc_call_t call;
-	service_id_t service_id = (service_id_t) IPC_GET_ARG2(*icall);
+	service_id_t service_id = (service_id_t) ipc_get_arg2(icall);
 
 	/* Allocate resources for new window and register it to the location service. */
@@ -921,5 +928,5 @@
 
 		async_get_call(&call);
-		if (IPC_GET_IMETHOD(call) == WINDOW_REGISTER) {
+		if (ipc_get_imethod(&call) == WINDOW_REGISTER) {
 			fibril_mutex_lock(&window_list_mtx);
 
@@ -931,5 +938,5 @@
 			}
 
-			win->flags = IPC_GET_ARG1(call);
+			win->flags = ipc_get_arg1(&call);
 
 			char name_in[LOC_NAME_MAXLEN + 1];
@@ -1007,5 +1014,5 @@
 			async_get_call(&call);
 
-			if (!IPC_GET_IMETHOD(call)) {
+			if (!ipc_get_imethod(&call)) {
 				async_answer_0(&call, EOK);
 				window_destroy(win);
@@ -1013,5 +1020,5 @@
 			}
 
-			switch (IPC_GET_IMETHOD(call)) {
+			switch (ipc_get_imethod(&call)) {
 			case WINDOW_GET_EVENT:
 				comp_window_get_event(win, &call);
@@ -1025,5 +1032,5 @@
 			async_get_call(&call);
 
-			if (!IPC_GET_IMETHOD(call)) {
+			if (!ipc_get_imethod(&call)) {
 				comp_window_close(win, &call);
 				window_destroy(win);
@@ -1031,5 +1038,5 @@
 			}
 
-			switch (IPC_GET_IMETHOD(call)) {
+			switch (ipc_get_imethod(&call)) {
 			case WINDOW_DAMAGE:
 				comp_window_damage(win, &call);
@@ -1060,5 +1067,5 @@
 static void comp_mode_change(viewport_t *vp, ipc_call_t *icall)
 {
-	sysarg_t mode_idx = IPC_GET_ARG2(*icall);
+	sysarg_t mode_idx = ipc_get_arg2(icall);
 	fibril_mutex_lock(&viewport_list_mtx);
 
@@ -1158,5 +1165,5 @@
 	fibril_mutex_lock(&viewport_list_mtx);
 	list_foreach(viewport_list, link, viewport_t, cur) {
-		if (cur->dsid == (service_id_t) IPC_GET_ARG1(*icall)) {
+		if (cur->dsid == (service_id_t) ipc_get_arg1(icall)) {
 			vp = cur;
 			break;
@@ -1173,10 +1180,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_hangup(vp->sess);
 			return;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case VISUALIZER_MODE_CHANGE:
 			comp_mode_change(vp, &call);
Index: uspace/srv/hid/console/console.c
===================================================================
--- uspace/srv/hid/console/console.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/console/console.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -513,5 +513,5 @@
 
 	for (size_t i = 0; i < CONSOLE_COUNT; i++) {
-		if (consoles[i].dsid == (service_id_t) IPC_GET_ARG2(*icall)) {
+		if (consoles[i].dsid == (service_id_t) ipc_get_arg2(icall)) {
 			cons = &consoles[i];
 			break;
Index: uspace/srv/hid/input/ctl/kbdev.c
===================================================================
--- uspace/srv/hid/input/ctl/kbdev.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/input/ctl/kbdev.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -160,5 +160,5 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			kbdev_destroy(kbdev);
@@ -166,10 +166,10 @@
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case KBDEV_EVENT:
 			/* Got event from keyboard device */
 			retval = 0;
-			type = IPC_GET_ARG1(call);
-			key = IPC_GET_ARG2(call);
+			type = ipc_get_arg1(&call);
+			key = ipc_get_arg2(&call);
 			kbd_push_event(kbdev->kbd_dev, type, key);
 			break;
Index: uspace/srv/hid/input/ctl/stty.c
===================================================================
--- uspace/srv/hid/input/ctl/stty.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/input/ctl/stty.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -228,4 +228,29 @@
 	0,	KC_RIGHT,	0x1b, 0x5b, 0x43, GSP_END,
 
+	KM_CTRL, 	KC_Q,		0x11, GSP_END,
+	KM_CTRL, 	KC_W,		0x17, GSP_END,
+	KM_CTRL, 	KC_E,		0x05, GSP_END,
+	KM_CTRL, 	KC_R,		0x12, GSP_END,
+	KM_CTRL,	KC_T,		0x14, GSP_END,
+	KM_CTRL,	KC_Y,		0x19, GSP_END,
+	KM_CTRL,	KC_U,		0x15, GSP_END,
+	KM_CTRL,	KC_O,		0x0f, GSP_END,
+	KM_CTRL,	KC_P,		0x10, GSP_END,
+
+	KM_CTRL,	KC_A,		0x01, GSP_END,
+	KM_CTRL,	KC_S,		0x13, GSP_END,
+	KM_CTRL,	KC_D,		0x04, GSP_END,
+	KM_CTRL,	KC_F,		0x06, GSP_END,
+	KM_CTRL,	KC_G,		0x07, GSP_END,
+	KM_CTRL,	KC_K,		0x0b, GSP_END,
+	KM_CTRL,	KC_L,		0x0c, GSP_END,
+
+	KM_CTRL,	KC_Z,		0x1a, GSP_END,
+	KM_CTRL,	KC_X,		0x18, GSP_END,
+	KM_CTRL,	KC_C,		0x03, GSP_END,
+	KM_CTRL,	KC_V,		0x16, GSP_END,
+	KM_CTRL,	KC_B,		0x02, GSP_END,
+	KM_CTRL,	KC_N,		0x0e, GSP_END,
+
 	/*
 	 * Sequences specific to Gnome terminal
Index: uspace/srv/hid/input/gsp.c
===================================================================
--- uspace/srv/hid/input/gsp.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/input/gsp.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -64,7 +64,7 @@
 } trans_key_t;
 
-static size_t trans_key_hash(void *key)
-{
-	trans_key_t *trans_key = (trans_key_t *)key;
+static size_t trans_key_hash(const void *key)
+{
+	const trans_key_t *trans_key = key;
 	return hash_combine(trans_key->input, trans_key->old_state);
 }
@@ -76,7 +76,7 @@
 }
 
-static bool trans_key_equal(void *key, const ht_link_t *item)
-{
-	trans_key_t *trans_key = (trans_key_t *)key;
+static bool trans_key_equal(const void *key, const ht_link_t *item)
+{
+	const trans_key_t *trans_key = key;
 	gsp_trans_t *t = hash_table_get_inst(item, gsp_trans_t, link);
 
Index: uspace/srv/hid/input/input.c
===================================================================
--- uspace/srv/hid/input/input.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/input/input.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -334,5 +334,5 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			if (client->sess != NULL) {
 				async_hangup(client->sess);
@@ -353,5 +353,5 @@
 				async_answer_0(&call, ELIMIT);
 		} else {
-			switch (IPC_GET_IMETHOD(call)) {
+			switch (ipc_get_imethod(&call)) {
 			case INPUT_ACTIVATE:
 				active_client = client;
@@ -368,5 +368,5 @@
 static void kconsole_event_handler(ipc_call_t *call, void *arg)
 {
-	if (IPC_GET_ARG1(*call)) {
+	if (ipc_get_arg1(call)) {
 		/* Kernel console activated */
 		active = false;
@@ -539,5 +539,6 @@
 		size_t nread;
 
-		chardev_read(sdev->chardev, &data, sizeof(data), &nread);
+		chardev_read(sdev->chardev, &data, sizeof(data), &nread,
+		    chardev_f_none);
 		/* XXX Handle error */
 		kbd_push_data(sdev->kdev, data);
@@ -629,4 +630,7 @@
 	kbd_add_dev(&chardev_port, &stty_ctl);
 #endif
+#if defined(UARCH_arm64) && defined(MACHINE_virt)
+	kbd_add_dev(&chardev_port, &stty_ctl);
+#endif
 	/* Silence warning on abs32le about kbd_add_dev() being unused */
 	(void) kbd_add_dev;
Index: uspace/srv/hid/input/port/chardev.c
===================================================================
--- uspace/srv/hid/input/port/chardev.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/input/port/chardev.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -64,5 +64,7 @@
 	"char/s3c24xx_uart",
 	/** Ski console, MSIM console, Sun4v console */
-	"devices/\\hw\\console\\a"
+	"devices/\\hw\\console\\a",
+	/** PL011 serial console */
+	"devices/\\hw\\uart\\a"
 };
 
@@ -138,5 +140,6 @@
 
 	while (true) {
-		rc = chardev_read(chardev, &b, sizeof(b), &nread);
+		rc = chardev_read(chardev, &b, sizeof(b), &nread,
+		    chardev_f_none);
 		if (rc != EOK || nread != sizeof(b)) {
 			printf("%s: Error reading data", NAME);
Index: uspace/srv/hid/input/proto/mousedev.c
===================================================================
--- uspace/srv/hid/input/proto/mousedev.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/input/proto/mousedev.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -79,5 +79,5 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			mousedev_destroy(mousedev);
@@ -87,20 +87,20 @@
 		errno_t retval;
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case MOUSEEV_MOVE_EVENT:
 			mouse_push_event_move(mousedev->mouse_dev,
-			    IPC_GET_ARG1(call), IPC_GET_ARG2(call),
-			    IPC_GET_ARG3(call));
+			    ipc_get_arg1(&call), ipc_get_arg2(&call),
+			    ipc_get_arg3(&call));
 			retval = EOK;
 			break;
 		case MOUSEEV_ABS_MOVE_EVENT:
 			mouse_push_event_abs_move(mousedev->mouse_dev,
-			    IPC_GET_ARG1(call), IPC_GET_ARG2(call),
-			    IPC_GET_ARG3(call), IPC_GET_ARG4(call));
+			    ipc_get_arg1(&call), ipc_get_arg2(&call),
+			    ipc_get_arg3(&call), ipc_get_arg4(&call));
 			retval = EOK;
 			break;
 		case MOUSEEV_BUTTON_EVENT:
 			mouse_push_event_button(mousedev->mouse_dev,
-			    IPC_GET_ARG1(call), IPC_GET_ARG2(call));
+			    ipc_get_arg1(&call), ipc_get_arg2(&call));
 			retval = EOK;
 			break;
Index: uspace/srv/hid/input/stroke.c
===================================================================
--- uspace/srv/hid/input/stroke.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/input/stroke.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -48,4 +48,5 @@
 static unsigned int mods_keys[][2] = {
 	{ KM_LSHIFT, KC_LSHIFT },
+	{ KM_LCTRL, KC_LCTRL },
 	{ 0, 0 }
 };
Index: uspace/srv/hid/isdv4_tablet/isdv4.c
===================================================================
--- uspace/srv/hid/isdv4_tablet/isdv4.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/isdv4_tablet/isdv4.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,6 +27,6 @@
  */
 
-#include <async.h>
 #include <errno.h>
+#include <fibril.h>
 #include <io/chardev.h>
 #include <mem.h>
@@ -293,5 +293,5 @@
 
 		rc = chardev_read(state->chardev, state->buf + state->buf_end,
-		    state->buf_size - state->buf_end, &nread);
+		    state->buf_size - state->buf_end, &nread, chardev_f_none);
 		if (rc != EOK && nread == 0)
 			return EIO;
Index: uspace/srv/hid/isdv4_tablet/main.c
===================================================================
--- uspace/srv/hid/isdv4_tablet/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/isdv4_tablet/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -81,5 +81,5 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
Index: uspace/srv/hid/output/output.c
===================================================================
--- uspace/srv/hid/output/output.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/output/output.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -187,5 +187,5 @@
 static void srv_frontbuf_destroy(ipc_call_t *icall)
 {
-	frontbuf_t *frontbuf = resolve_frontbuf(IPC_GET_ARG1(*icall), icall);
+	frontbuf_t *frontbuf = resolve_frontbuf(ipc_get_arg1(icall), icall);
 	if (frontbuf == NULL)
 		return;
@@ -200,5 +200,5 @@
 static void srv_cursor_update(ipc_call_t *icall)
 {
-	frontbuf_t *frontbuf = resolve_frontbuf(IPC_GET_ARG1(*icall), icall);
+	frontbuf_t *frontbuf = resolve_frontbuf(ipc_get_arg1(icall), icall);
 	if (frontbuf == NULL)
 		return;
@@ -235,5 +235,5 @@
 		dev->attrs.type = CHAR_ATTR_STYLE;
 		dev->attrs.val.style =
-		    (console_style_t) IPC_GET_ARG1(*icall);
+		    (console_style_t) ipc_get_arg1(icall);
 	}
 
@@ -246,9 +246,9 @@
 		dev->attrs.type = CHAR_ATTR_INDEX;
 		dev->attrs.val.index.bgcolor =
-		    (console_color_t) IPC_GET_ARG1(*icall);
+		    (console_color_t) ipc_get_arg1(icall);
 		dev->attrs.val.index.fgcolor =
-		    (console_color_t) IPC_GET_ARG2(*icall);
+		    (console_color_t) ipc_get_arg2(icall);
 		dev->attrs.val.index.attr =
-		    (console_color_attr_t) IPC_GET_ARG3(*icall);
+		    (console_color_attr_t) ipc_get_arg3(icall);
 	}
 
@@ -260,6 +260,6 @@
 	list_foreach(outdevs, link, outdev_t, dev) {
 		dev->attrs.type = CHAR_ATTR_RGB;
-		dev->attrs.val.rgb.bgcolor = IPC_GET_ARG1(*icall);
-		dev->attrs.val.rgb.fgcolor = IPC_GET_ARG2(*icall);
+		dev->attrs.val.rgb.bgcolor = ipc_get_arg1(icall);
+		dev->attrs.val.rgb.fgcolor = ipc_get_arg2(icall);
 	}
 
@@ -308,5 +308,5 @@
 static void srv_update(ipc_call_t *icall)
 {
-	frontbuf_t *frontbuf = resolve_frontbuf(IPC_GET_ARG1(*icall), icall);
+	frontbuf_t *frontbuf = resolve_frontbuf(ipc_get_arg1(icall), icall);
 	if (frontbuf == NULL)
 		return;
@@ -357,5 +357,5 @@
 static void srv_damage(ipc_call_t *icall)
 {
-	frontbuf_t *frontbuf = resolve_frontbuf(IPC_GET_ARG1(*icall), icall);
+	frontbuf_t *frontbuf = resolve_frontbuf(ipc_get_arg1(icall), icall);
 	if (frontbuf == NULL)
 		return;
@@ -369,9 +369,9 @@
 			continue;
 
-		sysarg_t col = IPC_GET_ARG2(*icall);
-		sysarg_t row = IPC_GET_ARG3(*icall);
-
-		sysarg_t cols = IPC_GET_ARG4(*icall);
-		sysarg_t rows = IPC_GET_ARG5(*icall);
+		sysarg_t col = ipc_get_arg2(icall);
+		sysarg_t row = ipc_get_arg3(icall);
+
+		sysarg_t cols = ipc_get_arg4(icall);
+		sysarg_t rows = ipc_get_arg5(icall);
 
 		for (sysarg_t y = 0; y < rows; y++) {
@@ -404,10 +404,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case OUTPUT_YIELD:
 			srv_yield(&call);
Index: uspace/srv/hid/output/port/chardev.c
===================================================================
--- uspace/srv/hid/output/port/chardev.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/output/port/chardev.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -216,4 +216,6 @@
 #elif defined(MACHINE_msim)
 		/* OK */
+#elif defined(UARCH_arm64) && defined(MACHINE_virt)
+		/* OK */
 #else
 		return EOK;
Index: uspace/srv/hid/remcons/remcons.c
===================================================================
--- uspace/srv/hid/remcons/remcons.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/remcons/remcons.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -219,5 +219,5 @@
 {
 	/* Find the user. */
-	telnet_user_t *user = telnet_user_get_for_client_connection(IPC_GET_ARG2(*icall));
+	telnet_user_t *user = telnet_user_get_for_client_connection(ipc_get_arg2(icall));
 	if (user == NULL) {
 		async_answer_0(icall, ENOENT);
Index: uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c
===================================================================
--- uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -378,5 +378,5 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			if (ts->client_sess != NULL) {
 				async_hangup(ts->client_sess);
Index: uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c
===================================================================
--- uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -69,5 +69,6 @@
 static void s3c24xx_uart_sendb(s3c24xx_uart_t *, uint8_t);
 
-static errno_t s3c24xx_uart_read(chardev_srv_t *, void *, size_t, size_t *);
+static errno_t s3c24xx_uart_read(chardev_srv_t *, void *, size_t, size_t *,
+    chardev_flags_t);
 static errno_t s3c24xx_uart_write(chardev_srv_t *, const void *, size_t, size_t *);
 
@@ -199,5 +200,5 @@
 
 static errno_t s3c24xx_uart_read(chardev_srv_t *srv, void *buf, size_t size,
-    size_t *nread)
+    size_t *nread, chardev_flags_t flags)
 {
 	s3c24xx_uart_t *uart = (s3c24xx_uart_t *) srv->srvs->sarg;
@@ -208,5 +209,6 @@
 	fibril_mutex_lock(&uart->buf_lock);
 
-	while (circ_buf_nused(&uart->cbuf) == 0)
+	while ((flags & chardev_f_nonblock) == 0 &&
+	    circ_buf_nused(&uart->cbuf) == 0)
 		fibril_condvar_wait(&uart->buf_cv, &uart->buf_lock);
 
Index: uspace/srv/loader/main.c
===================================================================
--- uspace/srv/loader/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/loader/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -290,6 +290,6 @@
 	DPRINTF("LOADER_LOAD()\n");
 
-	int rc = elf_load(program_fd, &prog_info);
-	if (rc != EE_OK) {
+	errno_t rc = elf_load(program_fd, &prog_info);
+	if (rc != EOK) {
 		DPRINTF("Failed to load executable for '%s'.\n", progname);
 		async_answer_0(req, EINVAL);
@@ -353,5 +353,5 @@
 	 */
 	async_get_call(req);
-	assert(!IPC_GET_IMETHOD(*req));
+	assert(!ipc_get_imethod(req));
 	async_answer_0(req, EOK);
 
@@ -392,10 +392,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			exit(0);
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case LOADER_GET_TASKID:
 			ldr_get_taskid(&call);
Index: uspace/srv/locsrv/locsrv.c
===================================================================
--- uspace/srv/locsrv/locsrv.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/locsrv/locsrv.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -342,5 +342,5 @@
 	async_get_call(&icall);
 
-	if (IPC_GET_IMETHOD(icall) != LOC_SERVER_REGISTER) {
+	if (ipc_get_imethod(&icall) != LOC_SERVER_REGISTER) {
 		async_answer_0(&icall, EREFUSED);
 		return NULL;
@@ -547,5 +547,5 @@
 
 	fibril_mutex_lock(&services_list_mutex);
-	svc = loc_service_find_id(IPC_GET_ARG1(*icall));
+	svc = loc_service_find_id(ipc_get_arg1(icall));
 	if (svc == NULL) {
 		fibril_mutex_unlock(&services_list_mutex);
@@ -583,5 +583,5 @@
 	fibril_mutex_lock(&cdir.mutex);
 
-	cat = category_get(&cdir, IPC_GET_ARG1(*icall));
+	cat = category_get(&cdir, ipc_get_arg1(icall));
 	if (cat == NULL) {
 		fibril_mutex_unlock(&cdir.mutex);
@@ -623,5 +623,5 @@
 	fibril_mutex_lock(&services_list_mutex);
 
-	svc = loc_service_find_id(IPC_GET_ARG1(*icall));
+	svc = loc_service_find_id(ipc_get_arg1(icall));
 	if (svc == NULL) {
 		fibril_mutex_unlock(&services_list_mutex);
@@ -671,5 +671,5 @@
 	fibril_mutex_lock(&services_list_mutex);
 
-	svc = loc_service_find_id(IPC_GET_ARG1(*icall));
+	svc = loc_service_find_id(ipc_get_arg1(icall));
 	if (svc == NULL) {
 		fibril_mutex_unlock(&services_list_mutex);
@@ -715,6 +715,6 @@
 	 * Get ID from request
 	 */
-	iface_t iface = IPC_GET_ARG1(*call);
-	service_id_t id = IPC_GET_ARG2(*call);
+	iface_t iface = ipc_get_arg1(call);
+	service_id_t id = ipc_get_arg2(call);
 	loc_service_t *svc = loc_service_find_id(id);
 
@@ -726,5 +726,5 @@
 
 	async_exch_t *exch = async_exchange_begin(svc->server->sess);
-	async_forward_fast(call, exch, iface, svc->id, 0, IPC_FF_NONE);
+	async_forward_1(call, exch, iface, svc->id, IPC_FF_NONE);
 	async_exchange_end(exch);
 
@@ -774,5 +774,5 @@
 	 */
 	if (svc == NULL) {
-		if (IPC_GET_ARG1(*icall) & IPC_FLAG_BLOCKING) {
+		if (ipc_get_arg1(icall) & IPC_FLAG_BLOCKING) {
 			/* Blocking lookup */
 			fibril_condvar_wait(&services_list_cv,
@@ -827,5 +827,5 @@
 	 */
 	if (namespace == NULL) {
-		if (IPC_GET_ARG1(*icall) & IPC_FLAG_BLOCKING) {
+		if (ipc_get_arg1(icall) & IPC_FLAG_BLOCKING) {
 			/* Blocking lookup */
 			fibril_condvar_wait(&services_list_cv,
@@ -932,8 +932,8 @@
 
 	loc_namespace_t *namespace =
-	    loc_namespace_find_id(IPC_GET_ARG1(*icall));
+	    loc_namespace_find_id(ipc_get_arg1(icall));
 	if (namespace == NULL) {
 		loc_service_t *svc =
-		    loc_service_find_id(IPC_GET_ARG1(*icall));
+		    loc_service_find_id(ipc_get_arg1(icall));
 		if (svc == NULL)
 			async_answer_1(icall, EOK, LOC_OBJECT_NONE);
@@ -958,5 +958,5 @@
 
 	loc_namespace_t *namespace =
-	    loc_namespace_find_id(IPC_GET_ARG1(*icall));
+	    loc_namespace_find_id(ipc_get_arg1(icall));
 	if (namespace == NULL)
 		async_answer_0(icall, EEXIST);
@@ -1079,5 +1079,5 @@
 
 	loc_namespace_t *namespace =
-	    loc_namespace_find_id(IPC_GET_ARG1(*icall));
+	    loc_namespace_find_id(ipc_get_arg1(icall));
 	if (namespace == NULL) {
 		fibril_mutex_unlock(&services_list_mutex);
@@ -1135,5 +1135,5 @@
 	fibril_mutex_lock(&cdir.mutex);
 
-	category_t *cat = category_get(&cdir, IPC_GET_ARG1(*icall));
+	category_t *cat = category_get(&cdir, ipc_get_arg1(icall));
 	if (cat == NULL) {
 		fibril_mutex_unlock(&cdir.mutex);
@@ -1247,5 +1247,5 @@
 static void loc_null_destroy(ipc_call_t *icall)
 {
-	sysarg_t i = IPC_GET_ARG1(*icall);
+	sysarg_t i = ipc_get_arg1(icall);
 	if (i >= NULL_SERVICES) {
 		async_answer_0(icall, ELIMIT);
@@ -1281,6 +1281,6 @@
 	errno_t retval;
 
-	svc_id = IPC_GET_ARG1(*icall);
-	cat_id = IPC_GET_ARG2(*icall);
+	svc_id = ipc_get_arg1(icall);
+	cat_id = ipc_get_arg2(icall);
 
 	fibril_mutex_lock(&services_list_mutex);
@@ -1387,4 +1387,10 @@
 	categ_dir_add_cat(&cdir, cat);
 
+	cat = category_new("printer-port");
+	categ_dir_add_cat(&cdir, cat);
+
+	cat = category_new("pci");
+	categ_dir_add_cat(&cdir, cat);
+
 	return true;
 }
@@ -1403,5 +1409,5 @@
 	 */
 	static_assert((INTERFACE_LOC_SUPPLIER & IFACE_EXCHANGE_MASK) ==
-	    IFACE_EXCHANGE_SERIALIZE);
+	    IFACE_EXCHANGE_SERIALIZE, "");
 
 	loc_server_t *server = loc_server_register();
@@ -1413,10 +1419,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case LOC_SERVER_UNREGISTER:
 			if (server == NULL)
@@ -1469,10 +1475,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case LOC_SERVICE_GET_ID:
 			loc_service_get_id(&call);
Index: uspace/srv/logger/ctl.c
===================================================================
--- uspace/srv/logger/ctl.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/logger/ctl.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -75,16 +75,16 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case LOGGER_CONTROL_SET_DEFAULT_LEVEL:
-			rc = set_default_logging_level(IPC_GET_ARG1(call));
+			rc = set_default_logging_level(ipc_get_arg1(&call));
 			async_answer_0(&call, rc);
 			break;
 		case LOGGER_CONTROL_SET_LOG_LEVEL:
-			rc = handle_log_level_change(IPC_GET_ARG1(call));
+			rc = handle_log_level_change(ipc_get_arg1(&call));
 			async_answer_0(&call, rc);
 			break;
Index: uspace/srv/logger/logs.c
===================================================================
--- uspace/srv/logger/logs.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/logger/logs.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -198,5 +198,5 @@
 }
 
-/** Decreases reference counter on the log and destory the log if
+/** Decreases reference counter on the log and destroy the log if
  * necessary.
  *
Index: uspace/srv/logger/writer.c
===================================================================
--- uspace/srv/logger/writer.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/logger/writer.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -109,12 +109,12 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case LOGGER_WRITER_CREATE_LOG:
-			log = handle_create_log(IPC_GET_ARG1(call));
+			log = handle_create_log(ipc_get_arg1(&call));
 			if (log == NULL) {
 				async_answer_0(&call, ENOMEM);
@@ -130,6 +130,6 @@
 			break;
 		case LOGGER_WRITER_MESSAGE:
-			rc = handle_receive_message(IPC_GET_ARG1(call),
-			    IPC_GET_ARG2(call));
+			rc = handle_receive_message(ipc_get_arg1(&call),
+			    ipc_get_arg2(&call));
 			async_answer_0(&call, rc);
 			break;
Index: uspace/srv/net/dhcp/main.c
===================================================================
--- uspace/srv/net/dhcp/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/dhcp/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -91,5 +91,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcp_link_add_srv()");
 
-	link_id = IPC_GET_ARG1(*call);
+	link_id = ipc_get_arg1(call);
 
 	rc = dhcpsrv_link_add(link_id);
@@ -104,5 +104,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcp_link_remove_srv()");
 
-	link_id = IPC_GET_ARG1(*call);
+	link_id = ipc_get_arg1(call);
 
 	rc = dhcpsrv_link_remove(link_id);
@@ -117,5 +117,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcp_discover_srv()");
 
-	link_id = IPC_GET_ARG1(*call);
+	link_id = ipc_get_arg1(call);
 
 	rc = dhcpsrv_discover(link_id);
@@ -133,5 +133,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: uspace/srv/net/dnsrsrv/dns_msg.c
===================================================================
--- uspace/srv/net/dnsrsrv/dns_msg.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/dnsrsrv/dns_msg.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -52,5 +52,5 @@
 /** Extend dynamically allocated string with suffix.
  *
- * @a *dstr points to a dynamically alocated buffer containing a string.
+ * @a *dstr points to a dynamically allocated buffer containing a string.
  * Reallocate this buffer so that concatenation of @a *dstr and @a suff can
  * fit in and append @a suff.
Index: uspace/srv/net/dnsrsrv/dnsrsrv.c
===================================================================
--- uspace/srv/net/dnsrsrv/dnsrsrv.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/dnsrsrv/dnsrsrv.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -90,5 +90,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_get_srvaddr_srv()");
 
-	ip_ver_t ver = IPC_GET_ARG1(*icall);
+	ip_ver_t ver = ipc_get_arg1(icall);
 
 	char *name;
@@ -219,5 +219,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: uspace/srv/net/ethip/ethip.c
===================================================================
--- uspace/srv/net/ethip/ethip.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/ethip/ethip.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -147,5 +147,5 @@
 	service_id_t sid;
 
-	sid = (service_id_t) IPC_GET_ARG2(*icall);
+	sid = (service_id_t) ipc_get_arg2(icall);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_client_conn(%u)", (unsigned)sid);
 	nic = ethip_nic_find_by_iplink_sid(sid);
Index: uspace/srv/net/ethip/ethip_nic.c
===================================================================
--- uspace/srv/net/ethip/ethip_nic.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/ethip/ethip_nic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -299,10 +299,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			return;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case NIC_EV_ADDR_CHANGED:
 			ethip_nic_addr_changed(nic, &call);
@@ -315,5 +315,5 @@
 			break;
 		default:
-			log_msg(LOG_DEFAULT, LVL_DEBUG, "unknown IPC method: %" PRIun, IPC_GET_IMETHOD(call));
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "unknown IPC method: %" PRIun, ipc_get_imethod(&call));
 			async_answer_0(&call, ENOTSUP);
 		}
Index: uspace/srv/net/inetsrv/icmp.c
===================================================================
--- uspace/srv/net/inetsrv/icmp.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/inetsrv/icmp.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -133,5 +133,5 @@
 	sdu.dest = dgram->dest;
 	sdu.seq_no = uint16_t_be2host(reply->seq_no);
-	sdu.data = reply + sizeof(icmp_echo_t);
+	sdu.data = dgram->data + sizeof(icmp_echo_t);
 	sdu.size = dgram->size - sizeof(icmp_echo_t);
 
Index: uspace/srv/net/inetsrv/icmpv6.c
===================================================================
--- uspace/srv/net/inetsrv/icmpv6.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/inetsrv/icmpv6.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -124,5 +124,5 @@
 
 	sdu.seq_no = uint16_t_be2host(reply->un.echo.seq_no);
-	sdu.data = reply + sizeof(icmpv6_message_t);
+	sdu.data = dgram->data + sizeof(icmpv6_message_t);
 	sdu.size = dgram->size - sizeof(icmpv6_message_t);
 
Index: uspace/srv/net/inetsrv/inetcfg.c
===================================================================
--- uspace/srv/net/inetsrv/inetcfg.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/inetsrv/inetcfg.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -257,5 +257,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_create_static_srv()");
 
-	sysarg_t link_id = IPC_GET_ARG1(*icall);
+	sysarg_t link_id = ipc_get_arg1(icall);
 
 	ipc_call_t call;
@@ -302,5 +302,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_delete_srv()");
 
-	addr_id = IPC_GET_ARG1(*call);
+	addr_id = ipc_get_arg1(call);
 
 	rc = inetcfg_addr_delete(addr_id);
@@ -312,5 +312,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_get_srv()");
 
-	sysarg_t addr_id = IPC_GET_ARG1(*icall);
+	sysarg_t addr_id = ipc_get_arg1(icall);
 
 	inet_addr_info_t ainfo;
@@ -375,5 +375,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_get_id_srv()");
 
-	link_id = IPC_GET_ARG1(*call);
+	link_id = ipc_get_arg1(call);
 
 	rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
@@ -499,5 +499,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_link_add_srv()");
 
-	link_id = IPC_GET_ARG1(*call);
+	link_id = ipc_get_arg1(call);
 
 	rc = inetcfg_link_add(link_id);
@@ -516,5 +516,5 @@
 	errno_t rc;
 
-	link_id = IPC_GET_ARG1(*call);
+	link_id = ipc_get_arg1(call);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_link_get_srv()");
 
@@ -566,5 +566,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_link_remove_srv()");
 
-	link_id = IPC_GET_ARG1(*call);
+	link_id = ipc_get_arg1(call);
 
 	rc = inetcfg_link_remove(link_id);
@@ -639,5 +639,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_delete_srv()");
 
-	sroute_id = IPC_GET_ARG1(*call);
+	sroute_id = ipc_get_arg1(call);
 
 	rc = inetcfg_sroute_delete(sroute_id);
@@ -649,5 +649,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_get_srv()");
 
-	sysarg_t sroute_id = IPC_GET_ARG1(*icall);
+	sysarg_t sroute_id = ipc_get_arg1(icall);
 
 	inet_sroute_info_t srinfo;
@@ -747,5 +747,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		log_msg(LOG_DEFAULT, LVL_DEBUG, "method %d", (int)method);
Index: uspace/srv/net/inetsrv/inetping.c
===================================================================
--- uspace/srv/net/inetsrv/inetping.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/inetsrv/inetping.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -143,5 +143,5 @@
 	errno_t rc;
 
-	sdu.seq_no = IPC_GET_ARG1(*icall);
+	sdu.seq_no = ipc_get_arg1(icall);
 
 	ipc_call_t call;
@@ -294,5 +294,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: uspace/srv/net/inetsrv/inetsrv.c
===================================================================
--- uspace/srv/net/inetsrv/inetsrv.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/inetsrv/inetsrv.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -233,5 +233,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_get_srcaddr_srv()");
 
-	uint8_t tos = IPC_GET_ARG1(*icall);
+	uint8_t tos = ipc_get_arg1(icall);
 
 	ipc_call_t call;
@@ -291,9 +291,9 @@
 	inet_dgram_t dgram;
 
-	dgram.iplink = IPC_GET_ARG1(*icall);
-	dgram.tos = IPC_GET_ARG2(*icall);
-
-	uint8_t ttl = IPC_GET_ARG3(*icall);
-	int df = IPC_GET_ARG4(*icall);
+	dgram.iplink = ipc_get_arg1(icall);
+	dgram.tos = ipc_get_arg2(icall);
+
+	uint8_t ttl = ipc_get_arg3(icall);
+	int df = ipc_get_arg4(icall);
 
 	ipc_call_t call;
@@ -352,5 +352,5 @@
 	sysarg_t proto;
 
-	proto = IPC_GET_ARG1(*call);
+	proto = ipc_get_arg1(call);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_set_proto_srv(%lu)", (unsigned long) proto);
 
@@ -397,5 +397,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: uspace/srv/net/inetsrv/pdu.c
===================================================================
--- uspace/srv/net/inetsrv/pdu.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/inetsrv/pdu.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -224,5 +224,5 @@
 		return EINVAL;
 
-	static_assert(sizeof(ip6_header_t) % 8 == 0);
+	static_assert(sizeof(ip6_header_t) % 8 == 0, "");
 	assert(hdr_size % 8 == 0);
 	assert(offs % FRAG_OFFS_UNIT == 0);
Index: uspace/srv/net/slip/slip.c
===================================================================
--- uspace/srv/net/slip/slip.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/slip/slip.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -212,5 +212,5 @@
 
 		rc = chardev_read(chardev, slip_recv_buf,
-		    sizeof(slip_recv_buf), &nread);
+		    sizeof(slip_recv_buf), &nread, chardev_f_none);
 		if (rc != EOK) {
 			log_msg(LOG_DEFAULT, LVL_ERROR,
Index: uspace/srv/net/tcp/service.c
===================================================================
--- uspace/srv/net/tcp/service.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/tcp/service.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -806,5 +806,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_destroy_srv()");
 
-	conn_id = IPC_GET_ARG1(*icall);
+	conn_id = ipc_get_arg1(icall);
 	rc = tcp_conn_destroy_impl(client, conn_id);
 	async_answer_0(icall, rc);
@@ -872,5 +872,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_listener_destroy_srv()");
 
-	lst_id = IPC_GET_ARG1(*icall);
+	lst_id = ipc_get_arg1(icall);
 	rc = tcp_listener_destroy_impl(client, lst_id);
 	async_answer_0(icall, rc);
@@ -892,5 +892,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_send_fin_srv()");
 
-	conn_id = IPC_GET_ARG1(*icall);
+	conn_id = ipc_get_arg1(icall);
 	rc = tcp_conn_send_fin_impl(client, conn_id);
 	async_answer_0(icall, rc);
@@ -912,5 +912,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_push_srv()");
 
-	conn_id = IPC_GET_ARG1(*icall);
+	conn_id = ipc_get_arg1(icall);
 	rc = tcp_conn_push_impl(client, conn_id);
 	async_answer_0(icall, rc);
@@ -932,5 +932,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_reset_srv()");
 
-	conn_id = IPC_GET_ARG1(*icall);
+	conn_id = ipc_get_arg1(icall);
 	rc = tcp_conn_reset_impl(client, conn_id);
 	async_answer_0(icall, rc);
@@ -984,5 +984,5 @@
 	}
 
-	conn_id = IPC_GET_ARG1(*icall);
+	conn_id = ipc_get_arg1(icall);
 
 	rc = tcp_conn_send_impl(client, conn_id, data, size);
@@ -1015,5 +1015,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_recv_srv()");
 
-	conn_id = IPC_GET_ARG1(*icall);
+	conn_id = ipc_get_arg1(icall);
 
 	if (!async_data_read_receive(&call, &size)) {
@@ -1070,5 +1070,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_recv_wait_srv()");
 
-	conn_id = IPC_GET_ARG1(*icall);
+	conn_id = ipc_get_arg1(icall);
 
 	if (!async_data_read_receive(&call, &size)) {
@@ -1180,5 +1180,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_client_conn: method=%d",
Index: uspace/srv/net/udp/service.c
===================================================================
--- uspace/srv/net/udp/service.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/udp/service.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -405,5 +405,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_destroy_srv()");
 
-	assoc_id = IPC_GET_ARG1(*icall);
+	assoc_id = ipc_get_arg1(icall);
 	rc = udp_assoc_destroy_impl(client, assoc_id);
 	async_answer_0(icall, rc);
@@ -425,5 +425,5 @@
 	log_msg(LOG_DEFAULT, LVL_NOTE, "udp_assoc_set_nolocal_srv()");
 
-	assoc_id = IPC_GET_ARG1(*icall);
+	assoc_id = ipc_get_arg1(icall);
 	rc = udp_assoc_set_nolocal_impl(client, assoc_id);
 	async_answer_0(icall, rc);
@@ -498,5 +498,5 @@
 	}
 
-	assoc_id = IPC_GET_ARG1(*icall);
+	assoc_id = ipc_get_arg1(icall);
 
 	rc = udp_assoc_send_msg_impl(client, assoc_id, &dest, data, size);
@@ -592,5 +592,5 @@
 
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_rmsg_read_srv()");
-	off = IPC_GET_ARG1(*icall);
+	off = ipc_get_arg1(icall);
 
 	enext = udp_rmsg_get_next(client);
@@ -679,5 +679,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_client_conn: method=%d",
Index: uspace/srv/ns/clonable.c
===================================================================
--- uspace/srv/ns/clonable.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/ns/clonable.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -94,6 +94,6 @@
 
 	async_exch_t *exch = async_exchange_begin(sess);
-	async_forward_fast(&csr->call, exch, csr->iface,
-	    IPC_GET_ARG3(csr->call), 0, IPC_FF_NONE);
+	async_forward_1(&csr->call, exch, csr->iface,
+	    ipc_get_arg3(&csr->call), IPC_FF_NONE);
 	async_exchange_end(exch);
 
Index: uspace/srv/ns/ns.c
===================================================================
--- uspace/srv/ns/ns.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/ns/ns.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -55,6 +55,6 @@
 	service_t service;
 
-	iface = IPC_GET_ARG1(*icall);
-	service = IPC_GET_ARG2(*icall);
+	iface = ipc_get_arg1(icall);
+	service = ipc_get_arg2(icall);
 	if (service != 0) {
 		/*
@@ -76,5 +76,5 @@
 
 		async_get_call(&call);
-		if (!IPC_GET_IMETHOD(call))
+		if (!ipc_get_imethod(&call))
 			break;
 
@@ -84,8 +84,8 @@
 		service_t service;
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case NS_REGISTER:
-			service = IPC_GET_ARG1(call);
-			iface = IPC_GET_ARG2(call);
+			service = ipc_get_arg1(&call);
+			iface = ipc_get_arg2(&call);
 
 			/*
@@ -101,5 +101,5 @@
 			break;
 		case NS_REGISTER_BROKER:
-			service = IPC_GET_ARG1(call);
+			service = ipc_get_arg1(&call);
 			retval = ns_service_register_broker(service);
 			break;
@@ -109,5 +109,5 @@
 		case NS_TASK_WAIT:
 			id = (task_id_t)
-			    MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
+			    MERGE_LOUP32(ipc_get_arg1(&call), ipc_get_arg2(&call));
 			wait_for_task(id, &call);
 			continue;
@@ -120,5 +120,5 @@
 		default:
 			printf("%s: Method not supported (%" PRIun ")\n",
-			    NAME, IPC_GET_IMETHOD(call));
+			    NAME, ipc_get_imethod(&call));
 			retval = ENOTSUP;
 			break;
Index: uspace/srv/ns/service.c
===================================================================
--- uspace/srv/ns/service.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/ns/service.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -65,7 +65,8 @@
 } hashed_iface_t;
 
-static size_t service_key_hash(void *key)
-{
-	return *(service_t *) key;
+static size_t service_key_hash(const void *key)
+{
+	const service_t *srv = key;
+	return *srv;
 }
 
@@ -78,15 +79,17 @@
 }
 
-static bool service_key_equal(void *key, const ht_link_t *item)
-{
+static bool service_key_equal(const void *key, const ht_link_t *item)
+{
+	const service_t *srv = key;
 	hashed_service_t *service =
 	    hash_table_get_inst(item, hashed_service_t, link);
 
-	return service->service == *(service_t *) key;
-}
-
-static size_t iface_key_hash(void *key)
-{
-	return *(iface_t *) key;
+	return service->service == *srv;
+}
+
+static size_t iface_key_hash(const void *key)
+{
+	const iface_t *iface = key;
+	return *iface;
 }
 
@@ -99,10 +102,11 @@
 }
 
-static bool iface_key_equal(void *key, const ht_link_t *item)
-{
+static bool iface_key_equal(const void *key, const ht_link_t *item)
+{
+	const iface_t *kiface = key;
 	hashed_iface_t *iface =
 	    hash_table_get_inst(item, hashed_iface_t, link);
 
-	return iface->iface == *(iface_t *) key;
+	return iface->iface == *kiface;
 }
 
@@ -154,6 +158,5 @@
 {
 	async_exch_t *exch = async_exchange_begin(sess);
-	async_forward_fast(call, exch, iface, IPC_GET_ARG3(*call), 0,
-	    IPC_FF_NONE);
+	async_forward_1(call, exch, iface, ipc_get_arg3(call), IPC_FF_NONE);
 	async_exchange_end(exch);
 }
@@ -367,5 +370,5 @@
 void ns_service_forward(service_t service, iface_t iface, ipc_call_t *call)
 {
-	sysarg_t flags = IPC_GET_ARG4(*call);
+	sysarg_t flags = ipc_get_arg4(call);
 	errno_t retval;
 
Index: uspace/srv/ns/task.c
===================================================================
--- uspace/srv/ns/task.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/ns/task.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -54,10 +54,11 @@
 } hashed_task_t;
 
-static size_t task_key_hash(void *key)
-{
-	return *(task_id_t *)key;
-}
-
-static size_t task_hash(const ht_link_t  *item)
+static size_t task_key_hash(const void *key)
+{
+	const task_id_t *tid = key;
+	return *tid;
+}
+
+static size_t task_hash(const ht_link_t *item)
 {
 	hashed_task_t *ht = hash_table_get_inst(item, hashed_task_t, link);
@@ -65,8 +66,9 @@
 }
 
-static bool task_key_equal(void *key, const ht_link_t *item)
-{
+static bool task_key_equal(const void *key, const ht_link_t *item)
+{
+	const task_id_t *tid = key;
 	hashed_task_t *ht = hash_table_get_inst(item, hashed_task_t, link);
-	return ht->id == *(task_id_t *)key;
+	return ht->id == *tid;
 }
 
@@ -97,8 +99,8 @@
 /* label-to-id hash table operations */
 
-static size_t p2i_key_hash(void *key)
-{
-	sysarg_t label = *(sysarg_t *)key;
-	return label;
+static size_t p2i_key_hash(const void *key)
+{
+	const sysarg_t *label = key;
+	return *label;
 }
 
@@ -109,10 +111,10 @@
 }
 
-static bool p2i_key_equal(void *key, const ht_link_t *item)
-{
-	sysarg_t label = *(sysarg_t *)key;
+static bool p2i_key_equal(const void *key, const ht_link_t *item)
+{
+	const sysarg_t *label = key;
 	p2i_entry_t *entry = hash_table_get_inst(item, p2i_entry_t, link);
 
-	return (label == entry->label);
+	return (*label == entry->label);
 }
 
@@ -225,5 +227,5 @@
 errno_t ns_task_id_intro(ipc_call_t *call)
 {
-	task_id_t id = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
+	task_id_t id = MERGE_LOUP32(ipc_get_arg1(call), ipc_get_arg2(call));
 
 	ht_link_t *link = hash_table_find(&phone_to_id, &call->request_label);
@@ -289,5 +291,5 @@
 	ht->finished = true;
 	ht->have_rval = true;
-	ht->retval = IPC_GET_ARG1(*call);
+	ht->retval = ipc_get_arg1(call);
 
 	process_pending_wait();
Index: uspace/srv/taskmon/taskmon.c
===================================================================
--- uspace/srv/taskmon/taskmon.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/taskmon/taskmon.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -61,6 +61,6 @@
 	uintptr_t thread;
 
-	taskid = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
-	thread = IPC_GET_ARG3(*call);
+	taskid = MERGE_LOUP32(ipc_get_arg1(call), ipc_get_arg2(call));
+	thread = ipc_get_arg3(call);
 
 	if (asprintf(&s_taskid, "%" PRIu64, taskid) < 0) {
@@ -101,5 +101,5 @@
 static void corecfg_set_enable_srv(ipc_call_t *icall)
 {
-	write_core_files = IPC_GET_ARG1(*icall);
+	write_core_files = ipc_get_arg1(icall);
 	async_answer_0(icall, EOK);
 }
@@ -113,5 +113,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: uspace/srv/test/chardev-test/main.c
===================================================================
--- uspace/srv/test/chardev-test/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/test/chardev-test/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -50,15 +50,18 @@
 static errno_t smallx_close(chardev_srv_t *);
 static errno_t smallx_write(chardev_srv_t *, const void *, size_t, size_t *);
-static errno_t smallx_read(chardev_srv_t *, void *, size_t, size_t *);
+static errno_t smallx_read(chardev_srv_t *, void *, size_t, size_t *,
+    chardev_flags_t);
 
 static errno_t largex_open(chardev_srvs_t *, chardev_srv_t *);
 static errno_t largex_close(chardev_srv_t *);
 static errno_t largex_write(chardev_srv_t *, const void *, size_t, size_t *);
-static errno_t largex_read(chardev_srv_t *, void *, size_t, size_t *);
+static errno_t largex_read(chardev_srv_t *, void *, size_t, size_t *,
+    chardev_flags_t);
 
 static errno_t partialx_open(chardev_srvs_t *, chardev_srv_t *);
 static errno_t partialx_close(chardev_srv_t *);
 static errno_t partialx_write(chardev_srv_t *, const void *, size_t, size_t *);
-static errno_t partialx_read(chardev_srv_t *, void *, size_t, size_t *);
+static errno_t partialx_read(chardev_srv_t *, void *, size_t, size_t *,
+    chardev_flags_t);
 
 static service_id_t smallx_svc_id;
@@ -97,5 +100,5 @@
 	sysarg_t svcid;
 
-	svcid = IPC_GET_ARG2(*icall);
+	svcid = ipc_get_arg2(icall);
 	if (svcid == smallx_svc_id) {
 		svc = &smallx_srvs;
@@ -186,5 +189,5 @@
 
 static errno_t smallx_read(chardev_srv_t *srv, void *buf, size_t size,
-    size_t *nread)
+    size_t *nread, chardev_flags_t flags)
 {
 	if (size < 1) {
@@ -221,5 +224,5 @@
 
 static errno_t largex_read(chardev_srv_t *srv, void *buf, size_t size,
-    size_t *nread)
+    size_t *nread, chardev_flags_t flags)
 {
 	if (size < 1) {
@@ -256,5 +259,5 @@
 
 static errno_t partialx_read(chardev_srv_t *srv, void *buf, size_t size,
-    size_t *nread)
+    size_t *nread, chardev_flags_t flags)
 {
 	if (size < 1) {
Index: uspace/srv/test/ipc-test/main.c
===================================================================
--- uspace/srv/test/ipc-test/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/test/ipc-test/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -191,10 +191,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case IPC_TEST_PING:
 			async_answer_0(&call, EOK);
Index: uspace/srv/vfs/vfs.c
===================================================================
--- uspace/srv/vfs/vfs.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/vfs/vfs.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -62,10 +62,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case IPC_M_PAGE_IN:
 			vfs_page_in(&call);
@@ -80,9 +80,9 @@
 static void notification_handler(ipc_call_t *call, void *arg)
 {
-	if (IPC_GET_ARG1(*call) == VFS_PASS_HANDLE)
+	if (ipc_get_arg1(call) == VFS_PASS_HANDLE)
 		vfs_op_pass_handle(
-		    (task_id_t) MERGE_LOUP32(IPC_GET_ARG4(*call),
-		    IPC_GET_ARG5(*call)), call->task_id,
-		    (int) IPC_GET_ARG2(*call));
+		    (task_id_t) MERGE_LOUP32(ipc_get_arg4(call),
+		    ipc_get_arg5(call)), call->task_id,
+		    (int) ipc_get_arg2(call));
 }
 
Index: uspace/srv/vfs/vfs.h
===================================================================
--- uspace/srv/vfs/vfs.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/vfs/vfs.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -49,4 +49,8 @@
 #define dprintf(...)
 #endif
+
+// TODO: Remove this arbitrary limit.
+/** Maximum number of open files per client. */
+#define VFS_MAX_OPEN_FILES  128
 
 /**
Index: uspace/srv/vfs/vfs_file.c
===================================================================
--- uspace/srv/vfs/vfs_file.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/vfs/vfs_file.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -148,5 +148,5 @@
 	async_wait_for(msg, &rc);
 
-	return IPC_GET_RETVAL(answer);
+	return ipc_get_retval(&answer);
 }
 
Index: uspace/srv/vfs/vfs_ipc.c
===================================================================
--- uspace/srv/vfs/vfs_ipc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/vfs/vfs_ipc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,7 +37,7 @@
 static void vfs_in_clone(ipc_call_t *req)
 {
-	int oldfd = IPC_GET_ARG1(*req);
-	int newfd = IPC_GET_ARG2(*req);
-	bool desc = IPC_GET_ARG3(*req);
+	int oldfd = ipc_get_arg1(req);
+	int newfd = ipc_get_arg2(req);
+	bool desc = ipc_get_arg3(req);
 
 	int outfd = -1;
@@ -48,5 +48,5 @@
 static void vfs_in_fsprobe(ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
 	char *fs_name = NULL;
 	vfs_fs_probe_info_t info;
@@ -113,5 +113,5 @@
 static void vfs_in_mount(ipc_call_t *req)
 {
-	int mpfd = IPC_GET_ARG1(*req);
+	int mpfd = ipc_get_arg1(req);
 
 	/*
@@ -120,8 +120,8 @@
 	 * in the request.
 	 */
-	service_id_t service_id = (service_id_t) IPC_GET_ARG2(*req);
-
-	unsigned int flags = (unsigned int) IPC_GET_ARG3(*req);
-	unsigned int instance = IPC_GET_ARG4(*req);
+	service_id_t service_id = (service_id_t) ipc_get_arg2(req);
+
+	unsigned int flags = (unsigned int) ipc_get_arg3(req);
+	unsigned int instance = ipc_get_arg4(req);
 
 	char *opts = NULL;
@@ -159,6 +159,6 @@
 static void vfs_in_open(ipc_call_t *req)
 {
-	int fd = IPC_GET_ARG1(*req);
-	int mode = IPC_GET_ARG2(*req);
+	int fd = ipc_get_arg1(req);
+	int mode = ipc_get_arg2(req);
 
 	errno_t rc = vfs_op_open(fd, mode);
@@ -168,5 +168,5 @@
 static void vfs_in_put(ipc_call_t *req)
 {
-	int fd = IPC_GET_ARG1(*req);
+	int fd = ipc_get_arg1(req);
 	errno_t rc = vfs_op_put(fd);
 	async_answer_0(req, rc);
@@ -175,7 +175,7 @@
 static void vfs_in_read(ipc_call_t *req)
 {
-	int fd = IPC_GET_ARG1(*req);
-	aoff64_t pos = MERGE_LOUP32(IPC_GET_ARG2(*req),
-	    IPC_GET_ARG3(*req));
+	int fd = ipc_get_arg1(req);
+	aoff64_t pos = MERGE_LOUP32(ipc_get_arg2(req),
+	    ipc_get_arg3(req));
 
 	size_t bytes = 0;
@@ -192,5 +192,5 @@
 	errno_t rc;
 
-	basefd = IPC_GET_ARG1(*req);
+	basefd = ipc_get_arg1(req);
 
 	/* Retrieve the old path. */
@@ -230,6 +230,6 @@
 static void vfs_in_resize(ipc_call_t *req)
 {
-	int fd = IPC_GET_ARG1(*req);
-	int64_t size = MERGE_LOUP32(IPC_GET_ARG2(*req), IPC_GET_ARG3(*req));
+	int fd = ipc_get_arg1(req);
+	int64_t size = MERGE_LOUP32(ipc_get_arg2(req), ipc_get_arg3(req));
 	errno_t rc = vfs_op_resize(fd, size);
 	async_answer_0(req, rc);
@@ -238,5 +238,5 @@
 static void vfs_in_stat(ipc_call_t *req)
 {
-	int fd = IPC_GET_ARG1(*req);
+	int fd = ipc_get_arg1(req);
 	errno_t rc = vfs_op_stat(fd);
 	async_answer_0(req, rc);
@@ -245,5 +245,5 @@
 static void vfs_in_statfs(ipc_call_t *req)
 {
-	int fd = (int) IPC_GET_ARG1(*req);
+	int fd = (int) ipc_get_arg1(req);
 
 	errno_t rc = vfs_op_statfs(fd);
@@ -253,5 +253,5 @@
 static void vfs_in_sync(ipc_call_t *req)
 {
-	int fd = IPC_GET_ARG1(*req);
+	int fd = ipc_get_arg1(req);
 	errno_t rc = vfs_op_sync(fd);
 	async_answer_0(req, rc);
@@ -260,6 +260,6 @@
 static void vfs_in_unlink(ipc_call_t *req)
 {
-	int parentfd = IPC_GET_ARG1(*req);
-	int expectfd = IPC_GET_ARG2(*req);
+	int parentfd = ipc_get_arg1(req);
+	int expectfd = ipc_get_arg2(req);
 
 	char *path;
@@ -273,5 +273,5 @@
 static void vfs_in_unmount(ipc_call_t *req)
 {
-	int mpfd = IPC_GET_ARG1(*req);
+	int mpfd = ipc_get_arg1(req);
 	errno_t rc = vfs_op_unmount(mpfd);
 	async_answer_0(req, rc);
@@ -280,5 +280,5 @@
 static void vfs_in_wait_handle(ipc_call_t *req)
 {
-	bool high_fd = IPC_GET_ARG1(*req);
+	bool high_fd = ipc_get_arg1(req);
 	int fd = -1;
 	errno_t rc = vfs_op_wait_handle(high_fd, &fd);
@@ -292,6 +292,6 @@
 	 * For defined flags, see <ipc/vfs.h>.
 	 */
-	int parentfd = IPC_GET_ARG1(*req);
-	int flags = IPC_GET_ARG2(*req);
+	int parentfd = ipc_get_arg1(req);
+	int flags = ipc_get_arg2(req);
 
 	int fd = 0;
@@ -307,7 +307,7 @@
 static void vfs_in_write(ipc_call_t *req)
 {
-	int fd = IPC_GET_ARG1(*req);
-	aoff64_t pos = MERGE_LOUP32(IPC_GET_ARG2(*req),
-	    IPC_GET_ARG3(*req));
+	int fd = ipc_get_arg1(req);
+	aoff64_t pos = MERGE_LOUP32(ipc_get_arg2(req),
+	    ipc_get_arg3(req));
 
 	size_t bytes = 0;
@@ -330,10 +330,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case VFS_IN_CLONE:
 			vfs_in_clone(&call);
Index: uspace/srv/vfs/vfs_lookup.c
===================================================================
--- uspace/srv/vfs/vfs_lookup.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/vfs/vfs_lookup.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -226,12 +226,12 @@
 
 	unsigned last = *pfirst + *plen;
-	*pfirst = IPC_GET_ARG3(answer) & 0xffff;
+	*pfirst = ipc_get_arg3(&answer) & 0xffff;
 	*plen = last - *pfirst;
 
-	result->triplet.fs_handle = (fs_handle_t) IPC_GET_ARG1(answer);
+	result->triplet.fs_handle = (fs_handle_t) ipc_get_arg1(&answer);
 	result->triplet.service_id = base->service_id;
-	result->triplet.index = (fs_index_t) IPC_GET_ARG2(answer);
-	result->size = MERGE_LOUP32(IPC_GET_ARG4(answer), IPC_GET_ARG5(answer));
-	result->type = (IPC_GET_ARG3(answer) >> 16) ?
+	result->triplet.index = (fs_index_t) ipc_get_arg2(&answer);
+	result->size = MERGE_LOUP32(ipc_get_arg4(&answer), ipc_get_arg5(&answer));
+	result->type = (ipc_get_arg3(&answer) >> 16) ?
 	    VFS_NODE_DIRECTORY : VFS_NODE_FILE;
 	return EOK;
Index: uspace/srv/vfs/vfs_node.c
===================================================================
--- uspace/srv/vfs/vfs_node.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/vfs/vfs_node.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -60,7 +60,7 @@
 #define KEY_INDEX	2
 
-static size_t nodes_key_hash(void *);
+static size_t nodes_key_hash(const void *);
 static size_t nodes_hash(const ht_link_t *);
-static bool nodes_key_equal(void *, const ht_link_t *);
+static bool nodes_key_equal(const void *, const ht_link_t *);
 static vfs_triplet_t node_triplet(vfs_node_t *node);
 
@@ -280,7 +280,7 @@
 }
 
-static size_t nodes_key_hash(void *key)
-{
-	vfs_triplet_t *tri = key;
+static size_t nodes_key_hash(const void *key)
+{
+	const vfs_triplet_t *tri = key;
 	size_t hash = hash_combine(tri->fs_handle, tri->index);
 	return hash_combine(hash, tri->service_id);
@@ -294,7 +294,7 @@
 }
 
-static bool nodes_key_equal(void *key, const ht_link_t *item)
-{
-	vfs_triplet_t *tri = key;
+static bool nodes_key_equal(const void *key, const ht_link_t *item)
+{
+	const vfs_triplet_t *tri = key;
 	vfs_node_t *node = hash_table_get_inst(item, vfs_node_t, nh_link);
 	return node->fs_handle == tri->fs_handle &&
Index: uspace/srv/vfs/vfs_ops.c
===================================================================
--- uspace/srv/vfs/vfs_ops.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/vfs/vfs_ops.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -90,8 +90,4 @@
 	errno_t rc;
 
-	/* If the file descriptors are the same, do nothing. */
-	if (oldfd == newfd)
-		return EOK;
-
 	/* Lookup the file structure corresponding to fd. */
 	vfs_file_t *oldfile = vfs_file_get(oldfd);
@@ -100,4 +96,10 @@
 
 	assert(oldfile->node != NULL);
+
+	/* If the file descriptors are the same, do nothing. */
+	if (oldfd == newfd) {
+		vfs_file_put(oldfile);
+		return EOK;
+	}
 
 	if (newfd != -1) {
@@ -168,7 +170,7 @@
 	res.triplet.fs_handle = fs_handle;
 	res.triplet.service_id = service_id;
-	res.triplet.index = (fs_index_t) IPC_GET_ARG1(answer);
-	res.size = (int64_t) MERGE_LOUP32(IPC_GET_ARG2(answer),
-	    IPC_GET_ARG3(answer));
+	res.triplet.index = (fs_index_t) ipc_get_arg1(&answer);
+	res.size = (int64_t) MERGE_LOUP32(ipc_get_arg2(&answer),
+	    ipc_get_arg3(&answer));
 	res.type = VFS_NODE_DIRECTORY;
 
@@ -374,5 +376,5 @@
 	}
 
-	*bytes = IPC_GET_ARG1(*answer);
+	*bytes = ipc_get_arg1(answer);
 	return rc;
 }
@@ -401,5 +403,5 @@
 	async_wait_for(msg, &rc);
 
-	chunk->size = IPC_GET_ARG1(*answer);
+	chunk->size = ipc_get_arg1(answer);
 
 	return (errno_t) rc;
@@ -488,6 +490,6 @@
 		/* Update the cached version of node's size. */
 		if (rc == EOK) {
-			file->node->size = MERGE_LOUP32(IPC_GET_ARG2(answer),
-			    IPC_GET_ARG3(answer));
+			file->node->size = MERGE_LOUP32(ipc_get_arg2(&answer),
+			    ipc_get_arg3(&answer));
 		}
 		fibril_rwlock_write_unlock(&file->node->contents_rwlock);
@@ -616,4 +618,9 @@
 		return EBADF;
 
+	if (!file->open_write || file->node->type != VFS_NODE_FILE) {
+		vfs_file_put(file);
+		return EINVAL;
+	}
+
 	fibril_rwlock_write_lock(&file->node->contents_rwlock);
 
@@ -637,6 +644,6 @@
 
 	async_exch_t *exch = vfs_exchange_grab(node->fs_handle);
-	errno_t rc = async_data_read_forward_fast(exch, VFS_OUT_STAT,
-	    node->service_id, node->index, true, 0, NULL);
+	errno_t rc = async_data_read_forward_3_0(exch, VFS_OUT_STAT,
+	    node->service_id, node->index, true);
 	vfs_exchange_release(exch);
 
@@ -654,6 +661,6 @@
 
 	async_exch_t *exch = vfs_exchange_grab(node->fs_handle);
-	errno_t rc = async_data_read_forward_fast(exch, VFS_OUT_STATFS,
-	    node->service_id, node->index, false, 0, NULL);
+	errno_t rc = async_data_read_forward_3_0(exch, VFS_OUT_STATFS,
+	    node->service_id, node->index, false);
 	vfs_exchange_release(exch);
 
@@ -892,4 +899,5 @@
 	rc = vfs_fd_alloc(&file, false, out_fd);
 	if (rc != EOK) {
+		fibril_rwlock_read_unlock(&namespace_rwlock);
 		vfs_node_put(node);
 		vfs_file_put(parent);
Index: uspace/srv/vfs/vfs_pager.c
===================================================================
--- uspace/srv/vfs/vfs_pager.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/vfs/vfs_pager.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -44,7 +44,7 @@
 void vfs_page_in(ipc_call_t *req)
 {
-	aoff64_t offset = IPC_GET_ARG1(*req);
-	size_t page_size = IPC_GET_ARG2(*req);
-	int fd = IPC_GET_ARG3(*req);
+	aoff64_t offset = ipc_get_arg1(req);
+	size_t page_size = ipc_get_arg2(req);
+	int fd = ipc_get_arg3(req);
 	void *page;
 	errno_t rc;
Index: uspace/srv/volsrv/volsrv.c
===================================================================
--- uspace/srv/volsrv/volsrv.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/volsrv/volsrv.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -138,5 +138,5 @@
 	errno_t rc;
 
-	sid = IPC_GET_ARG1(*icall);
+	sid = ipc_get_arg1(icall);
 
 	rc = vol_part_add_part(parts, sid);
@@ -156,5 +156,5 @@
 	errno_t rc;
 
-	sid = IPC_GET_ARG1(*icall);
+	sid = ipc_get_arg1(icall);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_info_srv(%zu)",
 	    sid);
@@ -204,5 +204,5 @@
 	errno_t rc;
 
-	sid = IPC_GET_ARG1(*icall);
+	sid = ipc_get_arg1(icall);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_eject_srv(%zu)", sid);
 
@@ -230,5 +230,5 @@
 	errno_t rc;
 
-	sid = IPC_GET_ARG1(*icall);
+	sid = ipc_get_arg1(icall);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_insert_srv(%zu)", sid);
 
@@ -294,5 +294,5 @@
 	errno_t rc;
 
-	sid = IPC_GET_ARG1(*icall);
+	sid = ipc_get_arg1(icall);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_empty_srv(%zu)", sid);
 
@@ -320,5 +320,5 @@
 	errno_t rc;
 
-	fstype = IPC_GET_ARG1(*icall);
+	fstype = ipc_get_arg1(icall);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_get_lsupp_srv(%u)",
 	    fstype);
@@ -362,6 +362,6 @@
 	log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_mkfs_srv()");
 
-	sid = IPC_GET_ARG1(*icall);
-	fstype = IPC_GET_ARG2(*icall);
+	sid = ipc_get_arg1(icall);
+	fstype = ipc_get_arg2(icall);
 
 	rc = async_data_write_accept((void **)&label, true, 0, VOL_LABEL_MAXLEN,
@@ -424,5 +424,5 @@
 	log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_set_mountp_srv()");
 
-	sid = IPC_GET_ARG1(*icall);
+	sid = ipc_get_arg1(icall);
 
 	rc = async_data_write_accept((void **)&mountp, true, 0,
@@ -499,5 +499,5 @@
 	errno_t rc;
 
-	vid.id = IPC_GET_ARG1(*icall);
+	vid.id = ipc_get_arg1(icall);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_info_srv(%zu)", vid.id);
 
@@ -556,5 +556,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: version
===================================================================
--- version	(revision c878693123930f0906703462cf2807430679517e)
+++ version	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -36,6 +36,6 @@
 
 VERSION = 0
-PATCHLEVEL = 7
-SUBLEVEL = 2
+PATCHLEVEL = 9
+SUBLEVEL = 1
 
 ifdef EXTRAVERSION
@@ -45,4 +45,4 @@
 endif
 
-NAME = Boosted Effort
-COPYRIGHT = Copyright (c) 2001-2018 HelenOS project
+NAME = Armonia
+COPYRIGHT = Copyright (c) 2001-2019 HelenOS project
