Index: .travis.yml
===================================================================
--- .travis.yml	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ .travis.yml	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -64,5 +64,5 @@
   - sudo apt-get install -qq python3-setuptools
   - pip3 install ninja
-  - pip3 install meson
+  - pip3 install --force-reinstall meson==0.50.1
   - ./tools/travis.sh install
 script:
Index: abi/include/_bits/uchar.h
===================================================================
--- abi/include/_bits/uchar.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
+++ abi/include/_bits/uchar.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2020 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 bits
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _BITS_UCHAR_H_
+#define _BITS_UCHAR_H_
+
+#include <stdint.h>
+
+typedef uint8_t char8_t;
+typedef uint32_t char32_t;
+
+#endif
+
+/** @}
+ */
Index: abi/include/_bits/wchar_limits.h
===================================================================
--- abi/include/_bits/wchar_limits.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ abi/include/_bits/wchar_limits.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -38,14 +38,14 @@
  */
 
-#ifndef _BITS_WCHAR_MIN_H_
-#define _BITS_WCHAR_MIN_H_
+#ifndef _BITS_WCHAR_LIMITS_H_
+#define _BITS_WCHAR_LIMITS_H_
 
-/* wchar_t should always be signed int in HelenOS. */
+/* wchar_t should always be int32_t in HelenOS. */
 
 #include <_bits/wchar_t.h>
 
 #ifndef __cplusplus
-_Static_assert(((wchar_t)-1) < 0, "wchar_t is not int");
-_Static_assert(sizeof(wchar_t) == 4, "wchar_t is not int");
+_Static_assert(((wchar_t) -1) < 0, "wchar_t is not int32_t");
+_Static_assert(sizeof(wchar_t) == 4, "wchar_t is not int32_t");
 #endif
 
Index: abi/include/abi/syscall.h
===================================================================
--- abi/include/abi/syscall.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ abi/include/abi/syscall.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -108,7 +108,5 @@
 	SYS_DEBUG_CONSOLE,
 
-	SYS_KLOG,
-
-	SYSCALL_END
+	SYS_KLOG
 } syscall_t;
 
Index: abi/include/abi/sysinfo.h
===================================================================
--- abi/include/abi/sysinfo.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ abi/include/abi/sysinfo.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -125,4 +125,12 @@
 } stats_thread_t;
 
+/** Statistics about a single IPC connection
+ *
+ */
+typedef struct {
+	task_id_t caller;  /**< Source task ID */
+	task_id_t callee;  /**< Target task ID */
+} stats_ipcc_t;
+
 /** Statistics about a single exception
  *
Index: abi/include/inttypes.h
===================================================================
--- abi/include/inttypes.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ abi/include/inttypes.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -43,4 +43,5 @@
 #include <stdint.h>
 #include <_bits/wchar_t.h>
+#include <_bits/uchar.h>
 #include <_bits/decls.h>
 
@@ -337,10 +338,12 @@
 } imaxdiv_t;
 
-intmax_t imaxabs(intmax_t);
-imaxdiv_t imaxdiv(intmax_t, intmax_t);
-intmax_t strtoimax(const char *__restrict__, char **__restrict__, int);
-uintmax_t strtoumax(const char *__restrict__, char **__restrict__, int);
-intmax_t wcstoimax(const wchar_t *__restrict__, wchar_t **__restrict__, int);
-uintmax_t wcstoumax(const wchar_t *__restrict__, wchar_t **__restrict__, int);
+extern intmax_t imaxabs(intmax_t);
+extern imaxdiv_t imaxdiv(intmax_t, intmax_t);
+extern intmax_t strtoimax(const char *__restrict__, char **__restrict__, int);
+extern uintmax_t strtoumax(const char *__restrict__, char **__restrict__, int);
+extern intmax_t wcstoimax(const wchar_t *__restrict__, wchar_t **__restrict__,
+    int);
+extern uintmax_t wcstoumax(const wchar_t *__restrict__, wchar_t **__restrict__,
+    int);
 
 __C_DECLS_END;
Index: boot/arch/arm32/src/putchar.c
===================================================================
--- boot/arch/arm32/src/putchar.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ boot/arch/arm32/src/putchar.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -193,7 +193,8 @@
 /** Display a character
  *
- * @param ch	Character to display
- */
-void putwchar(const wchar_t ch)
+ * @param ch Character to display
+ *
+ */
+void putuchar(const char32_t ch)
 {
 	if (ch == '\n')
Index: boot/arch/arm64/src/main.c
===================================================================
--- boot/arch/arm64/src/main.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ boot/arch/arm64/src/main.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -99,6 +99,7 @@
  *
  * @param ch Character to display.
- */
-void putwchar(wchar_t ch)
+ *
+ */
+void putuchar(char32_t ch)
 {
 	if (ch == '\n')
Index: boot/arch/ia64/src/putchar.c
===================================================================
--- boot/arch/ia64/src/putchar.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ boot/arch/ia64/src/putchar.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -33,5 +33,5 @@
 #include <arch/ski.h>
 
-void putwchar(const wchar_t ch)
+void putuchar(const char32_t ch)
 {
 #ifdef MACHINE_ski
Index: boot/arch/mips32/src/putchar.c
===================================================================
--- boot/arch/mips32/src/putchar.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ boot/arch/mips32/src/putchar.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -57,5 +57,5 @@
 #endif
 
-void putwchar(const wchar_t ch)
+void putuchar(const char32_t ch)
 {
 	if (ascii_check(ch))
Index: boot/arch/ppc32/src/ofw.c
===================================================================
--- boot/arch/ppc32/src/ofw.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ boot/arch/ppc32/src/ofw.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -39,5 +39,5 @@
 }
 
-void putwchar(wchar_t ch)
+void putuchar(char32_t ch)
 {
 	if (ch == '\n')
Index: boot/arch/riscv64/src/putchar.c
===================================================================
--- boot/arch/riscv64/src/putchar.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ boot/arch/riscv64/src/putchar.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -33,5 +33,5 @@
 #include <arch/ucb.h>
 
-void putwchar(wchar_t ch)
+void putuchar(char32_t ch)
 {
 	if (ascii_check(ch))
Index: boot/arch/sparc64/src/ofw.c
===================================================================
--- boot/arch/sparc64/src/ofw.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ boot/arch/sparc64/src/ofw.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -43,5 +43,5 @@
 #include <str.h>
 
-void putwchar(wchar_t ch)
+void putuchar(char32_t ch)
 {
 	if (ch == '\n')
Index: boot/generic/include/putchar.h
===================================================================
--- boot/generic/include/putchar.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ boot/generic/include/putchar.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -37,6 +37,7 @@
 
 #include <stddef.h>
+#include <uchar.h>
 
-extern void putwchar(wchar_t);
+extern void putuchar(char32_t);
 
 #endif
Index: boot/generic/include/str.h
===================================================================
--- boot/generic/include/str.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ boot/generic/include/str.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -38,13 +38,14 @@
 #include <stdbool.h>
 #include <stddef.h>
+#include <uchar.h>
 
 /* Common Unicode characters */
-#define U_SPECIAL      '?'
+#define U_SPECIAL  '?'
 
 /** No size limit constant */
 #define STR_NO_LIMIT  ((size_t) -1)
 
-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 char32_t str_decode(const char *str, size_t *offset, size_t sz);
+extern errno_t chr_encode(char32_t ch, char *str, size_t *offset, size_t sz);
 
 extern size_t str_size(const char *str);
@@ -52,6 +53,6 @@
 extern size_t str_length(const char *str);
 
-extern bool ascii_check(wchar_t ch);
-extern bool chr_check(wchar_t ch);
+extern bool ascii_check(char32_t ch);
+extern bool chr_check(char32_t ch);
 
 extern int str_cmp(const char *s1, const char *s2);
Index: boot/generic/include/tar.h
===================================================================
--- boot/generic/include/tar.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ boot/generic/include/tar.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -33,6 +33,6 @@
  */
 
-#ifndef TAR_H_
-#define TAR_H_
+#ifndef BOOT_TAR_H_
+#define BOOT_TAR_H_
 
 #include <stdbool.h>
Index: boot/generic/include/uchar.h
===================================================================
--- boot/generic/include/uchar.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
+++ boot/generic/include/uchar.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2020 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_generic
+ * @{
+ */
+/** @file
+ */
+
+#ifndef BOOT_UCHAR_H_
+#define BOOT_UCHAR_H_
+
+#include <_bits/uchar.h>
+
+#endif
+
+/** @}
+ */
Index: boot/generic/src/balloc.c
===================================================================
--- boot/generic/src/balloc.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ boot/generic/src/balloc.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -28,4 +28,5 @@
 
 #include <balloc.h>
+#include <stdalign.h>
 #include <stddef.h>
 #include <align.h>
@@ -51,5 +52,5 @@
 
 	/* Enforce minimal alignment. */
-	alignment = ALIGN_UP(alignment, 4);
+	alignment = ALIGN_UP(alignment, alignof(max_align_t));
 
 	uintptr_t addr = phys_base + ALIGN_UP(ballocs->size, alignment);
Index: boot/generic/src/payload.c
===================================================================
--- boot/generic/src/payload.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ boot/generic/src/payload.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -61,5 +61,5 @@
 {
 	char *e = (char *) ext(s);
-	if (str_cmp(e, ".gz") == 0)
+	if (e != NULL && str_cmp(e, ".gz") == 0)
 		*e = '\0';
 }
@@ -67,5 +67,6 @@
 static bool isgzip(const char *s)
 {
-	return str_cmp(ext(s), ".gz") == 0;
+	const char *e = ext(s);
+	return e != NULL && str_cmp(e, ".gz") == 0;
 }
 
Index: boot/generic/src/printf_core.c
===================================================================
--- boot/generic/src/printf_core.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ boot/generic/src/printf_core.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -504,5 +504,5 @@
 	while (true) {
 		i = nxt;
-		wchar_t uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
+		char32_t uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
 
 		if (uc == 0)
Index: boot/generic/src/str.c
===================================================================
--- boot/generic/src/str.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ boot/generic/src/str.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -38,5 +38,5 @@
  * 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
+ * represented as char32_t.@n
  *
  * Overview of the terminology:@n
@@ -46,6 +46,6 @@
  *  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
+ *  character             UTF-32 encoded Unicode character, stored in char32_t
+ *                        (unsigned 32 bit integer), code points 0 .. 1114111
  *                        are valid
  *
@@ -57,5 +57,5 @@
  *
  *  wide string           UTF-32 encoded NULL-terminated Unicode string,
- *                        wchar_t *
+ *                        char32_t *
  *
  *  [wide] string size    number of BYTES in a [wide] string (excluding
@@ -96,5 +96,5 @@
  * A specific character inside a [wide] string can be referred to by:@n
  *
- *  pointer (char *, wchar_t *)
+ *  pointer (char *, char32_t *)
  *  byte offset (size_t)
  *  character index (size_t)
@@ -109,11 +109,4 @@
 #include <stdint.h>
 
-/** Check the condition if wchar_t is signed */
-#ifdef __WCHAR_UNSIGNED__
-#define WCHAR_SIGNED_CHECK(cond)  (true)
-#else
-#define WCHAR_SIGNED_CHECK(cond)  (cond)
-#endif
-
 /** Byte mask consisting of lowest @n bits (out of 8) */
 #define LO_MASK_8(n)  ((uint8_t) ((1 << (n)) - 1))
@@ -143,5 +136,5 @@
  *
  */
-wchar_t str_decode(const char *str, size_t *offset, size_t size)
+char32_t str_decode(const char *str, size_t *offset, size_t size)
 {
 	if (*offset + 1 > size)
@@ -180,5 +173,5 @@
 		return U_SPECIAL;
 
-	wchar_t ch = b0 & LO_MASK_8(b0_bits);
+	char32_t ch = b0 & LO_MASK_8(b0_bits);
 
 	/* Decode continuation bytes */
@@ -191,5 +184,5 @@
 
 		/* Shift data bits to ch */
-		ch = (ch << CONT_BITS) | (wchar_t) (b & LO_MASK_8(CONT_BITS));
+		ch = (ch << CONT_BITS) | (char32_t) (b & LO_MASK_8(CONT_BITS));
 		cbytes--;
 	}
@@ -213,5 +206,5 @@
  *         code was invalid.
  */
-errno_t chr_encode(const wchar_t ch, char *str, size_t *offset, size_t size)
+errno_t chr_encode(const char32_t ch, char *str, size_t *offset, size_t size)
 {
 	if (*offset >= size)
@@ -340,7 +333,7 @@
  *
  */
-bool ascii_check(wchar_t ch)
-{
-	if (WCHAR_SIGNED_CHECK(ch >= 0) && (ch <= 127))
+bool ascii_check(char32_t ch)
+{
+	if (ch <= 127)
 		return true;
 
@@ -353,7 +346,7 @@
  *
  */
-bool chr_check(wchar_t ch)
-{
-	if (WCHAR_SIGNED_CHECK(ch >= 0) && (ch <= 1114111))
+bool chr_check(char32_t ch)
+{
+	if (ch <= 1114111)
 		return true;
 
@@ -381,6 +374,6 @@
 int str_cmp(const char *s1, const char *s2)
 {
-	wchar_t c1 = 0;
-	wchar_t c2 = 0;
+	char32_t c1 = 0;
+	char32_t c2 = 0;
 
 	size_t off1 = 0;
@@ -421,5 +414,5 @@
 	size_t dest_off = 0;
 
-	wchar_t ch;
+	char32_t ch;
 	while ((ch = str_decode(src, &src_off, STR_NO_LIMIT)) != 0) {
 		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
Index: boot/generic/src/vprintf.c
===================================================================
--- boot/generic/src/vprintf.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ boot/generic/src/vprintf.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -42,5 +42,5 @@
 
 	while (offset < size) {
-		putwchar(str_decode(str, &offset, size));
+		putuchar(str_decode(str, &offset, size));
 		chars++;
 	}
@@ -53,12 +53,12 @@
 	size_t offset = 0;
 	size_t chars = 0;
-	wchar_t uc;
+	char32_t uc;
 
 	while ((uc = str_decode(str, &offset, STR_NO_LIMIT)) != 0) {
-		putwchar(uc);
+		putuchar(uc);
 		chars++;
 	}
 
-	putwchar('\n');
+	putuchar('\n');
 	return chars;
 }
Index: boot/grub/meson.build
===================================================================
--- boot/grub/meson.build	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ boot/grub/meson.build	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -108,5 +108,9 @@
 	genisoimage_args = [ '-eltorito-boot', grub_image, '-no-emul-boot', '-boot-info-table' ]
 elif GRUB_ARCH == 'efi'
-	genisoimage_args = [ '--efi-boot', grub_image ]
+	if genisoimage_type == 'mkisofs'
+		genisoimage_args = [ '-eltorito-platform', 'efi', '-eltorito-boot', grub_image, '-no-emul-boot' ]
+	else
+		genisoimage_args = [ '--efi-boot', grub_image ]
+	endif
 endif
 
Index: contrib/qemu/build-from-scratch.sh
===================================================================
--- contrib/qemu/build-from-scratch.sh	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ contrib/qemu/build-from-scratch.sh	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -29,5 +29,5 @@
 #
 
-VERSION=4.1.0
+VERSION=5.0.0
 BASENAME=qemu-${VERSION}
 BASENAME_MASTER=qemu-master
Index: contrib/tools/font/bdf2c.pl
===================================================================
--- contrib/tools/font/bdf2c.pl	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ contrib/tools/font/bdf2c.pl	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -106,5 +106,5 @@
 
 print "\n";
-print "uint16_t fb_font_glyph(const wchar_t ch)\n";
+print "uint16_t fb_font_glyph(const char32_t ch)\n";
 print "{\n";
 print "\tif (ch == 0x0000)\n";
Index: kernel/arch/abs32le/include/arch/asm.h
===================================================================
--- kernel/arch/abs32le/include/arch/asm.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/abs32le/include/arch/asm.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -188,17 +188,4 @@
 }
 
-_NO_TRACE static inline uintptr_t get_stack_base(void)
-{
-	/*
-	 * On real hardware this returns the address of the bottom
-	 * of the current CPU stack. The current_t structure is stored
-	 * on the bottom of stack and this is used to identify the
-	 * current CPU, current task, current thread and current
-	 * address space.
-	 */
-
-	return 0;
-}
-
 #endif
 
Index: kernel/arch/abs32le/src/abs32le.c
===================================================================
--- kernel/arch/abs32le/src/abs32le.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/abs32le/src/abs32le.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -136,5 +136,5 @@
 }
 
-void early_putwchar(wchar_t ch)
+void early_putuchar(char32_t ch)
 {
 }
Index: kernel/arch/amd64/include/arch/asm.h
===================================================================
--- kernel/arch/amd64/include/arch/asm.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/amd64/include/arch/asm.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -42,24 +42,4 @@
 
 #define IO_SPACE_BOUNDARY	((void *) (64 * 1024))
-
-/** 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 (
-	    "andq %%rsp, %[v]\n"
-	    : [v] "=r" (v)
-	    : "0" (~((uint64_t) STACK_SIZE - 1))
-	);
-
-	return v;
-}
 
 _NO_TRACE static inline void cpu_sleep(void)
Index: kernel/arch/amd64/src/asm.S
===================================================================
--- kernel/arch/amd64/src/asm.S	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/amd64/src/asm.S	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -409,5 +409,5 @@
  *
  */
-FUNCTION_BEGIN(early_putwchar)
+FUNCTION_BEGIN(early_putuchar)
 
 #if (defined(CONFIG_L4RE_UVMM_EARLY_PRINT))
@@ -447,9 +447,9 @@
 	/* Sanity check for the cursor on screen */
 	cmp $2000, %ax
-	jb early_putwchar_cursor_ok
+	jb early_putuchar_cursor_ok
 
 		movw $1998, %ax
 
-	early_putwchar_cursor_ok:
+	early_putuchar_cursor_ok:
 
 	movw %ax, %bx
@@ -460,5 +460,5 @@
 
 	cmp $0x0a, %al
-	jne early_putwchar_backspace
+	jne early_putuchar_backspace
 
 		/* Interpret newline */
@@ -474,20 +474,20 @@
 		subw %dx, %bx
 
-		jmp early_putwchar_skip
-
-	early_putwchar_backspace:
+		jmp early_putuchar_skip
+
+	early_putuchar_backspace:
 
 		cmp $0x08, %al
-		jne early_putwchar_print
+		jne early_putuchar_print
 
 		/* Interpret backspace */
 
 		cmp $0x0000, %bx
-		je early_putwchar_skip
+		je early_putuchar_skip
 
 		dec %bx
-		jmp early_putwchar_skip
-
-	early_putwchar_print:
+		jmp early_putuchar_skip
+
+	early_putuchar_print:
 
 		/* Print character */
@@ -497,9 +497,9 @@
 		inc %bx
 
-	early_putwchar_skip:
+	early_putuchar_skip:
 
 	/* Sanity check for the cursor on the last line */
 	cmp $2000, %bx
-	jb early_putwchar_no_scroll
+	jb early_putuchar_no_scroll
 
 		/* Scroll the screen (24 rows) */
@@ -517,5 +517,5 @@
 		movw $1920, %bx
 
-	early_putwchar_no_scroll:
+	early_putuchar_no_scroll:
 
 	/* Write bits 8 - 15 of the cursor address */
@@ -544,3 +544,3 @@
 
 	ret
-FUNCTION_END(early_putwchar)
+FUNCTION_END(early_putuchar)
Index: kernel/arch/arm32/include/arch/asm.h
===================================================================
--- kernel/arch/arm32/include/arch/asm.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/arm32/include/arch/asm.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -95,24 +95,4 @@
 }
 
-/** 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 (
-	    "and %[v], sp, %[size]\n"
-	    : [v] "=r" (v)
-	    : [size] "r" (~(STACK_SIZE - 1))
-	);
-
-	return v;
-}
-
 extern void cpu_halt(void) __attribute__((noreturn));
 extern void asm_delay_loop(uint32_t t);
Index: kernel/arch/arm32/include/arch/context.h
===================================================================
--- kernel/arch/arm32/include/arch/context.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/arm32/include/arch/context.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -42,5 +42,5 @@
 #include <arch/regutils.h>
 
-/* Put one item onto the stack to support get_stack_base() and align it up. */
+/* Put one item onto the stack to support CURRENT and align it up. */
 #define SP_DELTA  (0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
 
Index: kernel/arch/arm32/src/asm.S
===================================================================
--- kernel/arch/arm32/src/asm.S	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/arm32/src/asm.S	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -98,5 +98,5 @@
 	ldmia sp!, {r4, r5, pc}
 
-FUNCTION_BEGIN(early_putwchar)
+FUNCTION_BEGIN(early_putuchar)
 	mov pc, lr
-FUNCTION_END(early_putwchar)
+FUNCTION_END(early_putuchar)
Index: kernel/arch/arm64/include/arch/asm.h
===================================================================
--- kernel/arch/arm64/include/arch/asm.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/arm64/include/arch/asm.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -52,24 +52,4 @@
 {
 	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;
 }
 
Index: kernel/arch/arm64/include/arch/context.h
===================================================================
--- kernel/arch/arm64/include/arch/context.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/arm64/include/arch/context.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -41,5 +41,5 @@
 #include <arch/stack.h>
 
-/* Put one item onto the stack to support get_stack_base() and align it up. */
+/* Put one item onto the stack to support CURRENT and align it up. */
 #define SP_DELTA  (0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
 
Index: kernel/arch/arm64/src/arm64.c
===================================================================
--- kernel/arch/arm64/src/arm64.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/arm64/src/arm64.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -167,7 +167,11 @@
 	asm volatile (
 	    /*
-	     * Clear all general-purpose registers, except x0 that holds an
-	     * argument for the user space.
+	     * Reset the kernel stack to its base value.
+	     *
+	     * Clear all general-purpose registers,
+	     * except x0 that holds an argument for
+	     * the user space.
 	     */
+	    "mov sp, %[kstack]\n"
 	    "mov x0, %[uspace_uarg]\n"
 	    "mov x1, #0\n"
@@ -202,5 +206,7 @@
 	    "mov x30, #0\n"
 	    "eret\n"
-	    :: [uspace_uarg] "r" (kernel_uarg->uspace_uarg)
+	    :: [uspace_uarg] "r" (kernel_uarg->uspace_uarg),
+	      [kstack] "r" (((uint64_t) (THREAD->kstack)) +
+	      MEM_STACK_SIZE - SP_DELTA)
 	);
 
Index: kernel/arch/arm64/src/asm.S
===================================================================
--- kernel/arch/arm64/src/asm.S	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/arm64/src/asm.S	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -56,7 +56,7 @@
 FUNCTION_END(memcpy_to_uspace_failover_address)
 
-FUNCTION_BEGIN(early_putwchar)
+FUNCTION_BEGIN(early_putuchar)
 	ret
-FUNCTION_END(early_putwchar)
+FUNCTION_END(early_putuchar)
 
 /* Static checks for the istate_t save/load. */
Index: kernel/arch/ia32/include/arch/asm.h
===================================================================
--- kernel/arch/ia32/include/arch/asm.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/ia32/include/arch/asm.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -348,24 +348,4 @@
 
 #endif /* PROCESSOR_i486 */
-
-/** 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 (
-	    "andl %%esp, %[v]\n"
-	    : [v] "=r" (v)
-	    : "0" (~(STACK_SIZE - 1))
-	);
-
-	return v;
-}
 
 /** Invalidate TLB Entry.
Index: kernel/arch/ia32/include/arch/context.h
===================================================================
--- kernel/arch/ia32/include/arch/context.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/ia32/include/arch/context.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -45,5 +45,5 @@
  * First for pop of the saved register, second during ret instruction.
  *
- * One item is put onto stack to support get_stack_base().
+ * One item is put onto stack to support CURRENT.
  */
 #define SP_DELTA  (8 + STACK_ITEM_SIZE)
Index: kernel/arch/ia32/src/asm.S
===================================================================
--- kernel/arch/ia32/src/asm.S	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/ia32/src/asm.S	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -451,5 +451,5 @@
  *
  */
-FUNCTION_BEGIN(early_putwchar)
+FUNCTION_BEGIN(early_putuchar)
 
 #if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB)))
@@ -484,9 +484,9 @@
 	/* Sanity check for the cursor on screen */
 	cmp $2000, %ax
-	jb early_putwchar_cursor_ok
+	jb early_putuchar_cursor_ok
 
 		movw $1998, %ax
 
-	early_putwchar_cursor_ok:
+	early_putuchar_cursor_ok:
 
 	movw %ax, %bx
@@ -497,5 +497,5 @@
 
 	cmp $0x0a, %al
-	jne early_putwchar_backspace
+	jne early_putuchar_backspace
 
 		/* Interpret newline */
@@ -511,20 +511,20 @@
 		subw %dx, %bx
 
-		jmp early_putwchar_skip
-
-	early_putwchar_backspace:
+		jmp early_putuchar_skip
+
+	early_putuchar_backspace:
 
 		cmp $0x08, %al
-		jne early_putwchar_print
+		jne early_putuchar_print
 
 		/* Interpret backspace */
 
 		cmp $0x0000, %bx
-		je early_putwchar_skip
+		je early_putuchar_skip
 
 		dec %bx
-		jmp early_putwchar_skip
-
-	early_putwchar_print:
+		jmp early_putuchar_skip
+
+	early_putuchar_print:
 
 		/* Print character */
@@ -534,9 +534,9 @@
 		inc %bx
 
-	early_putwchar_skip:
+	early_putuchar_skip:
 
 	/* Sanity check for the cursor on the last line */
 	cmp $2000, %bx
-	jb early_putwchar_no_scroll
+	jb early_putuchar_no_scroll
 
 		/* Scroll the screen (24 rows) */
@@ -554,5 +554,5 @@
 		movw $1920, %bx
 
-	early_putwchar_no_scroll:
+	early_putuchar_no_scroll:
 
 	/* Write bits 8 - 15 of the cursor address */
@@ -583,4 +583,4 @@
 
 	ret
-FUNCTION_END(early_putwchar)
-
+FUNCTION_END(early_putuchar)
+
Index: kernel/arch/ia64/include/arch/asm.h
===================================================================
--- kernel/arch/ia64/include/arch/asm.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/ia64/include/arch/asm.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -160,22 +160,4 @@
 }
 
-/** Return base address of current memory stack.
- *
- * The memory stack is assumed to be STACK_SIZE / 2 long. Note that there is
- * also the RSE stack, which takes up the upper half of STACK_SIZE.
- * The memory stack must start on page boundary.
- */
-_NO_TRACE static inline uintptr_t get_stack_base(void)
-{
-	uint64_t value;
-
-	asm volatile (
-	    "mov %[value] = r12"
-	    : [value] "=r" (value)
-	);
-
-	return (value & (~(STACK_SIZE / 2 - 1)));
-}
-
 /** Return Processor State Register.
  *
Index: kernel/arch/ia64/include/arch/context.h
===================================================================
--- kernel/arch/ia64/include/arch/context.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/ia64/include/arch/context.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -46,5 +46,5 @@
  * No need to allocate scratch area.
  *
- * One item is put onto the stack to support get_stack_base().
+ * One item is put onto the stack to support CURRENT.
  */
 #define SP_DELTA  (0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
Index: kernel/arch/ia64/src/asm.S
===================================================================
--- kernel/arch/ia64/src/asm.S	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/ia64/src/asm.S	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -191,5 +191,5 @@
 FUNCTION_END(switch_to_userspace)
 
-FUNCTION_BEGIN(early_putwchar)
+FUNCTION_BEGIN(early_putuchar)
 	br.ret.sptk.many b0
-FUNCTION_END(early_putwchar)
+FUNCTION_END(early_putuchar)
Index: kernel/arch/ia64/src/drivers/ski.c
===================================================================
--- kernel/arch/ia64/src/drivers/ski.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/ia64/src/drivers/ski.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -60,8 +60,8 @@
 };
 
-static void ski_putwchar(outdev_t *, const wchar_t);
+static void ski_putuchar(outdev_t *, const char32_t);
 
 static outdev_operations_t skidev_ops = {
-	.write = ski_putwchar,
+	.write = ski_putuchar,
 	.redraw = NULL,
 	.scroll_up = NULL,
@@ -82,5 +82,5 @@
  *
  */
-static wchar_t ski_getchar(void)
+static char32_t ski_getchar(void)
 {
 	uint64_t ch;
@@ -96,5 +96,5 @@
 	);
 
-	return (wchar_t) ch;
+	return (char32_t) ch;
 }
 
@@ -111,5 +111,5 @@
 
 	while (count > 0) {
-		wchar_t ch = ski_getchar();
+		char32_t ch = ski_getchar();
 
 		if (ch == '\0')
@@ -203,5 +203,5 @@
  *
  */
-static void ski_putwchar(outdev_t *dev, wchar_t ch)
+static void ski_putuchar(outdev_t *dev, char32_t ch)
 {
 	if (ski_parea.mapped && !console_override)
Index: kernel/arch/mips32/include/arch/asm.h
===================================================================
--- kernel/arch/mips32/include/arch/asm.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/mips32/include/arch/asm.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -45,24 +45,4 @@
 }
 
-/** 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 base;
-
-	asm volatile (
-	    "and %[base], $29, %[mask]\n"
-	    : [base] "=r" (base)
-	    : [mask] "r" (~(STACK_SIZE - 1))
-	);
-
-	return base;
-}
-
 _NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t v)
 {
Index: kernel/arch/mips32/include/arch/context.h
===================================================================
--- kernel/arch/mips32/include/arch/context.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/mips32/include/arch/context.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -41,5 +41,5 @@
 
 /*
- * Put one item onto the stack to support get_stack_base() and align it up.
+ * Put one item onto the stack to support CURRENT and align it up.
  */
 #define SP_DELTA  (ABI_STACK_FRAME + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
Index: kernel/arch/mips32/src/asm.S
===================================================================
--- kernel/arch/mips32/src/asm.S	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/mips32/src/asm.S	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -296,6 +296,6 @@
 FUNCTION_END(fpu_context_restore)
 
-FUNCTION_BEGIN(early_putwchar)
+FUNCTION_BEGIN(early_putuchar)
 	j $ra
 	nop
-FUNCTION_END(early_putwchar)
+FUNCTION_END(early_putuchar)
Index: kernel/arch/ppc32/include/arch/asm.h
===================================================================
--- kernel/arch/ppc32/include/arch/asm.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/ppc32/include/arch/asm.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -163,24 +163,4 @@
 }
 
-/** 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 base;
-
-	asm volatile (
-	    "and %[base], %%sp, %[mask]\n"
-	    : [base] "=r" (base)
-	    : [mask] "r" (~(STACK_SIZE - 1))
-	);
-
-	return base;
-}
-
 _NO_TRACE static inline void cpu_sleep(void)
 {
Index: kernel/arch/ppc32/src/asm.S
===================================================================
--- kernel/arch/ppc32/src/asm.S	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/ppc32/src/asm.S	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -265,5 +265,5 @@
 	blr
 
-FUNCTION_BEGIN(early_putwchar)
+FUNCTION_BEGIN(early_putuchar)
 	blr
-FUNCTION_END(early_putwchar)
+FUNCTION_END(early_putuchar)
Index: kernel/arch/riscv64/include/arch/asm.h
===================================================================
--- kernel/arch/riscv64/include/arch/asm.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/riscv64/include/arch/asm.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -91,17 +91,4 @@
 }
 
-_NO_TRACE static inline uintptr_t get_stack_base(void)
-{
-	uintptr_t base;
-
-	asm volatile (
-	    "and %[base], sp, %[mask]\n"
-	    : [base] "=r" (base)
-	    : [mask] "r" (~(STACK_SIZE - 1))
-	);
-
-	return base;
-}
-
 _NO_TRACE static inline void cpu_sleep(void)
 {
Index: kernel/arch/riscv64/include/arch/drivers/ucb.h
===================================================================
--- kernel/arch/riscv64/include/arch/drivers/ucb.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/riscv64/include/arch/drivers/ucb.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -42,5 +42,5 @@
 extern void htif_init(volatile uint64_t *, volatile uint64_t *);
 extern outdev_t *htifout_init(void);
-extern void htif_putwchar(outdev_t *, const wchar_t);
+extern void htif_putuchar(outdev_t *, const char32_t);
 
 #endif
Index: kernel/arch/riscv64/src/asm.S
===================================================================
--- kernel/arch/riscv64/src/asm.S	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/riscv64/src/asm.S	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -35,7 +35,7 @@
 FUNCTION_END(asm_delay_loop)
 
-FUNCTION_BEGIN(early_putwchar)
+FUNCTION_BEGIN(early_putuchar)
 	ret
-FUNCTION_END(early_putwchar)
+FUNCTION_END(early_putuchar)
 
 FUNCTION_BEGIN(cpu_halt)
Index: kernel/arch/riscv64/src/drivers/ucb.c
===================================================================
--- kernel/arch/riscv64/src/drivers/ucb.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/riscv64/src/drivers/ucb.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -42,5 +42,5 @@
 
 static outdev_operations_t htifdev_ops = {
-	.write = htif_putwchar,
+	.write = htif_putuchar,
 	.redraw = NULL,
 	.scroll_up = NULL,
@@ -85,5 +85,5 @@
 }
 
-void htif_putwchar(outdev_t *dev, const wchar_t ch)
+void htif_putuchar(outdev_t *dev, const char32_t ch)
 {
 	if (ascii_check(ch))
Index: kernel/arch/sparc64/include/arch/asm.h
===================================================================
--- kernel/arch/sparc64/include/arch/asm.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/sparc64/include/arch/asm.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -382,24 +382,4 @@
 }
 
-/** 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 unbiased_sp;
-
-	asm volatile (
-	    "add %%sp, %[stack_bias], %[unbiased_sp]\n"
-	    : [unbiased_sp] "=r" (unbiased_sp)
-	    : [stack_bias] "i" (STACK_BIAS)
-	);
-
-	return ALIGN_DOWN(unbiased_sp, STACK_SIZE);
-}
-
 /** Read Version Register.
  *
Index: kernel/arch/sparc64/src/asm.S
===================================================================
--- kernel/arch/sparc64/src/asm.S	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/sparc64/src/asm.S	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -189,6 +189,6 @@
 	mov %g0, %o0  /* return 0 on failure */
 
-FUNCTION_BEGIN(early_putwchar)
+FUNCTION_BEGIN(early_putuchar)
 	retl
 	nop
-FUNCTION_END(early_putwchar)
+FUNCTION_END(early_putuchar)
Index: kernel/arch/sparc64/src/drivers/niagara.c
===================================================================
--- kernel/arch/sparc64/src/drivers/niagara.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/arch/sparc64/src/drivers/niagara.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -57,9 +57,9 @@
 static niagara_instance_t *instance = NULL;
 
-static void niagara_putwchar(outdev_t *, const wchar_t);
+static void niagara_putuchar(outdev_t *, const char32_t);
 
 /** Character device operations */
 static outdev_operations_t niagara_ops = {
-	.write = niagara_putwchar,
+	.write = niagara_putuchar,
 	.redraw = NULL,
 	.scroll_up = NULL,
@@ -103,5 +103,5 @@
 
 /** Write a single character to the standard output. */
-static void niagara_putwchar(outdev_t *dev, wchar_t ch)
+static void niagara_putuchar(outdev_t *dev, char32_t ch)
 {
 	if ((!outbuf_parea.mapped) || (console_override)) {
Index: kernel/genarch/include/genarch/fb/font-8x16.h
===================================================================
--- kernel/genarch/include/genarch/fb/font-8x16.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/genarch/include/genarch/fb/font-8x16.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -42,5 +42,5 @@
 #include <typedefs.h>
 
-extern uint16_t fb_font_glyph(const wchar_t ch);
+extern uint16_t fb_font_glyph(const char32_t ch);
 extern uint8_t fb_font[FONT_GLYPHS][FONT_SCANLINES];
 
Index: kernel/genarch/include/genarch/kbrd/scanc.h
===================================================================
--- kernel/genarch/include/genarch/kbrd/scanc.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/genarch/include/genarch/kbrd/scanc.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -41,6 +41,6 @@
 #define SCANCODES  128
 
-extern wchar_t sc_primary_map[SCANCODES];
-extern wchar_t sc_secondary_map[SCANCODES];
+extern char32_t sc_primary_map[SCANCODES];
+extern char32_t sc_secondary_map[SCANCODES];
 
 #endif
Index: kernel/genarch/src/drivers/dsrln/dsrlnout.c
===================================================================
--- kernel/genarch/src/drivers/dsrln/dsrlnout.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/genarch/src/drivers/dsrln/dsrlnout.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -49,5 +49,5 @@
 } dsrlnout_instance_t;
 
-static void dsrlnout_putwchar(outdev_t *dev, const wchar_t ch)
+static void dsrlnout_putuchar(outdev_t *dev, const char32_t ch)
 {
 	dsrlnout_instance_t *instance = (dsrlnout_instance_t *) dev->data;
@@ -62,5 +62,5 @@
 
 static outdev_operations_t dsrlndev_ops = {
-	.write = dsrlnout_putwchar,
+	.write = dsrlnout_putuchar,
 	.redraw = NULL,
 	.scroll_up = NULL,
Index: kernel/genarch/src/drivers/ega/ega.c
===================================================================
--- kernel/genarch/src/drivers/ega/ega.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/genarch/src/drivers/ega/ega.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -71,9 +71,9 @@
 } ega_instance_t;
 
-static void ega_putwchar(outdev_t *, wchar_t);
+static void ega_putuchar(outdev_t *, char32_t);
 static void ega_redraw(outdev_t *);
 
 static outdev_operations_t egadev_ops = {
-	.write = ega_putwchar,
+	.write = ega_putuchar,
 	.redraw = ega_redraw,
 	.scroll_up = NULL,
@@ -81,7 +81,7 @@
 };
 
-static uint16_t ega_oem_glyph(const wchar_t ch)
-{
-	if ((ch >= 0x0000) && (ch <= 0x007f))
+static uint16_t ega_oem_glyph(const char32_t ch)
+{
+	if (ch <= 0x007f)
 		return ch;
 
@@ -515,5 +515,5 @@
 }
 
-static void ega_display_wchar(ega_instance_t *instance, wchar_t ch)
+static void ega_display_wchar(ega_instance_t *instance, char32_t ch)
 {
 	uint16_t index = ega_oem_glyph(ch);
@@ -538,5 +538,5 @@
 }
 
-static void ega_putwchar(outdev_t *dev, wchar_t ch)
+static void ega_putuchar(outdev_t *dev, char32_t ch)
 {
 	ega_instance_t *instance = (ega_instance_t *) dev->data;
Index: kernel/genarch/src/drivers/ns16550/ns16550.c
===================================================================
--- kernel/genarch/src/drivers/ns16550/ns16550.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/genarch/src/drivers/ns16550/ns16550.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -112,5 +112,5 @@
 }
 
-static void ns16550_putwchar(outdev_t *dev, wchar_t ch)
+static void ns16550_putuchar(outdev_t *dev, char32_t ch)
 {
 	ns16550_instance_t *instance = (ns16550_instance_t *) dev->data;
@@ -128,5 +128,5 @@
 
 static outdev_operations_t ns16550_ops = {
-	.write = ns16550_putwchar,
+	.write = ns16550_putuchar,
 	.redraw = NULL
 };
Index: kernel/genarch/src/drivers/omap/uart.c
===================================================================
--- kernel/genarch/src/drivers/omap/uart.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/genarch/src/drivers/omap/uart.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -49,5 +49,5 @@
 }
 
-static void omap_uart_putwchar(outdev_t *dev, wchar_t ch)
+static void omap_uart_putuchar(outdev_t *dev, char32_t ch)
 {
 	omap_uart_t *uart = dev->data;
@@ -62,5 +62,5 @@
 
 static outdev_operations_t omap_uart_ops = {
-	.write = omap_uart_putwchar,
+	.write = omap_uart_putuchar,
 	.redraw = NULL,
 	.scroll_up = NULL,
Index: kernel/genarch/src/drivers/pl011/pl011.c
===================================================================
--- kernel/genarch/src/drivers/pl011/pl011.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/genarch/src/drivers/pl011/pl011.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -56,5 +56,5 @@
 }
 
-static void pl011_uart_putwchar(outdev_t *dev, wchar_t ch)
+static void pl011_uart_putuchar(outdev_t *dev, char32_t ch)
 {
 	pl011_uart_t *uart = dev->data;
@@ -74,5 +74,5 @@
 
 static outdev_operations_t pl011_uart_ops = {
-	.write = pl011_uart_putwchar,
+	.write = pl011_uart_putuchar,
 	.redraw = NULL,
 	.scroll_up = NULL,
Index: kernel/genarch/src/drivers/s3c24xx/uart.c
===================================================================
--- kernel/genarch/src/drivers/s3c24xx/uart.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/genarch/src/drivers/s3c24xx/uart.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -61,5 +61,5 @@
 }
 
-static void s3c24xx_uart_putwchar(outdev_t *dev, wchar_t ch)
+static void s3c24xx_uart_putuchar(outdev_t *dev, char32_t ch)
 {
 	s3c24xx_uart_t *uart =
@@ -94,5 +94,5 @@
 
 static outdev_operations_t s3c24xx_uart_ops = {
-	.write = s3c24xx_uart_putwchar,
+	.write = s3c24xx_uart_putuchar,
 	.redraw = NULL,
 	.scroll_up = NULL,
Index: kernel/genarch/src/fb/fb.c
===================================================================
--- kernel/genarch/src/fb/fb.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/genarch/src/fb/fb.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -123,5 +123,5 @@
 } fb_instance_t;
 
-static void fb_putwchar(outdev_t *, wchar_t);
+static void fb_putuchar(outdev_t *, char32_t);
 static void fb_redraw(outdev_t *);
 static void fb_scroll_up(outdev_t *);
@@ -129,5 +129,5 @@
 
 static outdev_operations_t fbdev_ops = {
-	.write = fb_putwchar,
+	.write = fb_putuchar,
 	.redraw = fb_redraw,
 	.scroll_up = fb_scroll_up,
@@ -418,5 +418,5 @@
  *
  */
-static void fb_putwchar(outdev_t *dev, wchar_t ch)
+static void fb_putuchar(outdev_t *dev, char32_t ch)
 {
 	fb_instance_t *instance = (fb_instance_t *) dev->data;
Index: kernel/genarch/src/fb/font-8x16.c
===================================================================
--- kernel/genarch/src/fb/font-8x16.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/genarch/src/fb/font-8x16.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -43,5 +43,5 @@
  * mark glyph if no specific glyph exists.
  */
-uint16_t fb_font_glyph(const wchar_t ch)
+uint16_t fb_font_glyph(const char32_t ch)
 {
 	if (ch == 0x0000)
Index: kernel/genarch/src/kbrd/kbrd.c
===================================================================
--- kernel/genarch/src/kbrd/kbrd.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/genarch/src/kbrd/kbrd.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -76,5 +76,5 @@
  * @param sc Scancode of the key being released.
  */
-static void key_released(kbrd_instance_t *instance, wchar_t sc)
+static void key_released(kbrd_instance_t *instance, char32_t sc)
 {
 	spinlock_lock(&instance->keylock);
@@ -103,10 +103,10 @@
  * @param sc Scancode of the key being pressed.
  */
-static void key_pressed(kbrd_instance_t *instance, wchar_t sc)
+static void key_pressed(kbrd_instance_t *instance, char32_t sc)
 {
 	bool letter;
 	bool shift;
 	bool capslock;
-	wchar_t ch;
+	char32_t ch;
 
 	spinlock_lock(&instance->keylock);
@@ -158,5 +158,5 @@
 
 	while (true) {
-		wchar_t sc = indev_pop_character(&instance->raw);
+		char32_t sc = indev_pop_character(&instance->raw);
 
 		if (sc == IGNORE_CODE)
Index: kernel/genarch/src/kbrd/kbrd_at.c
===================================================================
--- kernel/genarch/src/kbrd/kbrd_at.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/genarch/src/kbrd/kbrd_at.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -59,5 +59,5 @@
 #define AT_SCROLL_SCAN_CODE	0x7E
 
-static bool is_lock_key(wchar_t);
+static bool is_lock_key(char32_t);
 
 static indev_operations_t kbrd_raw_ops = {
@@ -69,5 +69,5 @@
  * @param sc Scancode of the key being released.
  */
-static void key_released(kbrd_instance_t *instance, wchar_t sc)
+static void key_released(kbrd_instance_t *instance, char32_t sc)
 {
 	spinlock_lock(&instance->keylock);
@@ -96,5 +96,5 @@
  * @param sc Scancode of the key being pressed.
  */
-static void key_pressed(kbrd_instance_t *instance, wchar_t sc)
+static void key_pressed(kbrd_instance_t *instance, char32_t sc)
 {
 	bool letter;
@@ -140,5 +140,5 @@
 
 	while (true) {
-		wchar_t sc = indev_pop_character(&instance->raw);
+		char32_t sc = indev_pop_character(&instance->raw);
 
 		if (sc == AT_KEY_RELEASE) {
@@ -203,5 +203,5 @@
 }
 
-static bool is_lock_key(wchar_t sc)
+static bool is_lock_key(char32_t sc)
 {
 	return ((sc == AT_CAPS_SCAN_CODE) || (sc == AT_NUM_SCAN_CODE) ||
Index: kernel/genarch/src/kbrd/scanc_at.c
===================================================================
--- kernel/genarch/src/kbrd/scanc_at.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/genarch/src/kbrd/scanc_at.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -39,5 +39,5 @@
 
 /** Primary meaning of scancodes. */
-wchar_t sc_primary_map[] = {
+char32_t sc_primary_map[] = {
 	U_NULL, /* 0x00 */
 	U_SPECIAL, /* 0x01 - F9 */
@@ -135,5 +135,5 @@
 
 /** Secondary meaning of scancodes. */
-wchar_t sc_secondary_map[] = {
+char32_t sc_secondary_map[] = {
 	U_NULL, /* 0x00 */
 	U_SPECIAL, /* 0x01 - F9 */
Index: kernel/genarch/src/kbrd/scanc_mac.c
===================================================================
--- kernel/genarch/src/kbrd/scanc_mac.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/genarch/src/kbrd/scanc_mac.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -40,5 +40,5 @@
 
 /** Primary meaning of scancodes. */
-wchar_t sc_primary_map[SCANCODES] = {
+char32_t sc_primary_map[SCANCODES] = {
 	[0x00] = 'a',
 	[0x01] = 's',
@@ -172,5 +172,5 @@
 
 /** Secondary meaning of scancodes. */
-wchar_t sc_secondary_map[SCANCODES] = {
+char32_t sc_secondary_map[SCANCODES] = {
 	[0x00] = 'A',
 	[0x01] = 'S',
Index: kernel/genarch/src/kbrd/scanc_pc.c
===================================================================
--- kernel/genarch/src/kbrd/scanc_pc.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/genarch/src/kbrd/scanc_pc.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -40,5 +40,5 @@
 
 /** Primary meaning of scancodes. */
-wchar_t sc_primary_map[SCANCODES] = {
+char32_t sc_primary_map[SCANCODES] = {
 	U_NULL,         /* 0x00 - undefined */
 	U_ESCAPE,       /* 0x01 - Esc */
@@ -129,5 +129,5 @@
 
 /** Secondary meaning of scancodes. */
-wchar_t sc_secondary_map[SCANCODES] = {
+char32_t sc_secondary_map[SCANCODES] = {
 	U_NULL,         /* 0x00 - undefined */
 	U_ESCAPE,       /* 0x01 - Esc */
Index: kernel/genarch/src/kbrd/scanc_sun.c
===================================================================
--- kernel/genarch/src/kbrd/scanc_sun.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/genarch/src/kbrd/scanc_sun.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -40,5 +40,5 @@
 
 /** Primary meaning of scancodes. */
-wchar_t sc_primary_map[SCANCODES] = {
+char32_t sc_primary_map[SCANCODES] = {
 	[0x00] = U_SPECIAL,
 	[0x01] = U_SPECIAL,
@@ -172,5 +172,5 @@
 
 /** Secondary meaning of scancodes. */
-wchar_t sc_secondary_map[SCANCODES] = {
+char32_t sc_secondary_map[SCANCODES] = {
 	[0x00] = U_SPECIAL,
 	[0x01] = U_SPECIAL,
Index: kernel/genarch/src/srln/srln.c
===================================================================
--- kernel/genarch/src/srln/srln.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/genarch/src/srln/srln.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -56,5 +56,5 @@
 
 	while (true) {
-		wchar_t ch = indev_pop_character(&instance->raw);
+		char32_t ch = indev_pop_character(&instance->raw);
 
 		/* ANSI escape sequence processing */
Index: kernel/generic/include/arch.h
===================================================================
--- kernel/generic/include/arch.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/include/arch.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -36,14 +36,21 @@
 #define KERN_ARCH_H_
 
-#include <arch/asm.h>   /* get_stack_base() */
 #include <config.h>
 
-/*
+/** Return the current_t structure
+ *
  * The current_t structure holds pointers to various parts of the current
  * execution state, like running task, thread, address space, etc.
+ *
+ * The current_t structure is located at the base address of the current
+ * stack. The stack is assumed to be STACK_SIZE bytes long. The stack base
+ * address must be aligned to STACK_SIZE.
+ *
  */
-#define CURRENT  ((current_t * )(get_stack_base()))
+#define CURRENT \
+	((current_t *) (((uintptr_t) __builtin_frame_address(0)) & \
+	    (~((uintptr_t) STACK_SIZE - 1))))
 
-#define MAGIC                UINT32_C(0xfacefeed)
+#define MAGIC  UINT32_C(0xfacefeed)
 
 #define container_check(ctn1, ctn2)  ((ctn1) == (ctn2))
@@ -59,16 +66,18 @@
 struct as;
 
-/**
+/** Current structure
+ *
  * For each possible kernel stack, structure
  * of the following type will be placed at
  * the base address of the stack.
+ *
  */
 typedef struct {
-	size_t preemption;     /**< Preemption disabled counter and flag. */
-	struct thread *thread; /**< Current thread. */
-	struct task *task;     /**< Current task. */
-	struct cpu *cpu;       /**< Executing cpu. */
-	struct as *as;         /**< Current address space. */
-	uint32_t magic;        /**< Magic value */
+	size_t preemption;      /**< Preemption disabled counter and flag. */
+	struct thread *thread;  /**< Current thread. */
+	struct task *task;      /**< Current task. */
+	struct cpu *cpu;        /**< Executing CPU. */
+	struct as *as;          /**< Current address space. */
+	uint32_t magic;         /**< Magic value. */
 } current_t;
 
@@ -89,5 +98,5 @@
 	} while (0)
 
-#define ARCH_OP(op)	ARCH_STRUCT_OP(arch_ops, op)
+#define ARCH_OP(op)  ARCH_STRUCT_OP(arch_ops, op)
 
 extern void current_initialize(current_t *);
Index: kernel/generic/include/console/chardev.h
===================================================================
--- kernel/generic/include/console/chardev.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/include/console/chardev.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -55,5 +55,5 @@
 typedef struct {
 	/** Read character directly from device, assume interrupts disabled. */
-	wchar_t (*poll)(struct indev *);
+	char32_t (*poll)(struct indev *);
 
 	/** Signal out-of-band condition. */
@@ -68,5 +68,5 @@
 	/** Protects everything below. */
 	IRQ_SPINLOCK_DECLARE(lock);
-	wchar_t buffer[INDEV_BUFLEN];
+	char32_t buffer[INDEV_BUFLEN];
 	size_t counter;
 
@@ -82,5 +82,5 @@
 typedef struct {
 	/** Write character to output. */
-	void (*write)(struct outdev *, wchar_t);
+	void (*write)(struct outdev *, char32_t);
 
 	/** Redraw any previously cached characters. */
@@ -112,6 +112,6 @@
 extern void indev_initialize(const char *, indev_t *,
     indev_operations_t *);
-extern void indev_push_character(indev_t *, wchar_t);
-extern wchar_t indev_pop_character(indev_t *);
+extern void indev_push_character(indev_t *, char32_t);
+extern char32_t indev_pop_character(indev_t *);
 extern void indev_signal(indev_t *, indev_signal_t);
 
Index: kernel/generic/include/console/console.h
===================================================================
--- kernel/generic/include/console/console.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/include/console/console.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -57,5 +57,5 @@
 extern outdev_t *stdout;
 
-extern void early_putwchar(wchar_t);
+extern void early_putuchar(char32_t);
 
 extern indev_t *stdin_wire(void);
@@ -66,8 +66,8 @@
 extern void kio_update(void *);
 extern void kio_flush(void);
-extern void kio_push_char(const wchar_t);
+extern void kio_push_char(const char32_t);
 SPINLOCK_EXTERN(kio_lock);
 
-extern wchar_t getc(indev_t *indev);
+extern char32_t getc(indev_t *indev);
 extern size_t gets(indev_t *indev, char *buf, size_t buflen);
 extern sys_errno_t sys_kio(int cmd, uspace_addr_t buf, size_t size);
Index: kernel/generic/include/macros.h
===================================================================
--- kernel/generic/include/macros.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/include/macros.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -164,4 +164,14 @@
 	    ((void *) &(((type *) 0)->member_identif))))
 
+/** Get the size of an array in array elements
+ *
+ * @param array Array to determine the size of
+ *
+ * @return Size of array in array elements
+ *
+ */
+#define sizeof_array(array) \
+	(sizeof(array) / sizeof((array)[0]))
+
 #endif
 
Index: kernel/generic/include/printf/printf_core.h
===================================================================
--- kernel/generic/include/printf/printf_core.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/include/printf/printf_core.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -38,4 +38,5 @@
 #include <stdarg.h>
 #include <stddef.h>
+#include <uchar.h>
 
 /** Structure for specifying output methods for different printf clones. */
@@ -45,5 +46,5 @@
 
 	/* Wide string output function, returns number of printed characters or EOF */
-	int (*wstr_write)(const wchar_t *, size_t, void *);
+	int (*wstr_write)(const char32_t *, size_t, void *);
 
 	/* User data - output stream specification, state, locks, etc. */
Index: kernel/generic/include/putchar.h
===================================================================
--- kernel/generic/include/putchar.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/include/putchar.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -36,7 +36,7 @@
 #define KERN_PUTCHAR_H_
 
-#include <stddef.h>
+#include <uchar.h>
 
-extern void putwchar(wchar_t);
+extern void putuchar(char32_t);
 
 #endif
Index: kernel/generic/include/str.h
===================================================================
--- kernel/generic/include/str.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/include/str.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -44,5 +44,5 @@
 
 /* Common Unicode characters */
-#define U_SPECIAL      '?'
+#define U_SPECIAL  '?'
 
 #define U_LEFT_ARROW   0x2190
@@ -69,36 +69,36 @@
 #define STR_BOUNDS(length)  ((length) << 2)
 
-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 char32_t str_decode(const char *, size_t *, size_t);
+extern errno_t chr_encode(char32_t, char *, size_t *, size_t);
 
-extern size_t str_size(const char *str);
-extern size_t wstr_size(const wchar_t *str);
+extern size_t str_size(const char *);
+extern size_t wstr_size(const char32_t *);
 
-extern size_t str_lsize(const char *str, size_t max_len);
-extern size_t wstr_lsize(const wchar_t *str, size_t max_len);
+extern size_t str_lsize(const char *, size_t);
+extern size_t wstr_lsize(const char32_t *, size_t);
 
-extern size_t str_length(const char *str);
-extern size_t wstr_length(const wchar_t *wstr);
+extern size_t str_length(const char *);
+extern size_t wstr_length(const char32_t *);
 
-extern size_t str_nlength(const char *str, size_t size);
-extern size_t wstr_nlength(const wchar_t *str, size_t size);
+extern size_t str_nlength(const char *, size_t);
+extern size_t wstr_nlength(const char32_t *, size_t);
 
-extern bool ascii_check(wchar_t ch);
-extern bool chr_check(wchar_t ch);
+extern bool ascii_check(char32_t);
+extern bool chr_check(char32_t);
 
-extern int str_cmp(const char *s1, const char *s2);
-extern int str_lcmp(const char *s1, const char *s2, size_t max_len);
+extern int str_cmp(const char *, const char *);
+extern int str_lcmp(const char *, const char *, size_t);
 
-extern void str_cpy(char *dest, size_t size, const char *src);
-extern void str_ncpy(char *dest, size_t size, const char *src, size_t n);
-extern void wstr_to_str(char *dest, size_t size, const wchar_t *src);
+extern void str_cpy(char *, size_t, const char *);
+extern void str_ncpy(char *, size_t, const char *, size_t);
+extern void wstr_to_str(char *, size_t, const char32_t *);
 
-extern char *str_chr(const char *str, wchar_t ch);
+extern char *str_chr(const char *, char32_t);
 
-extern bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos);
-extern bool wstr_remove(wchar_t *str, size_t pos);
+extern bool wstr_linsert(char32_t *, char32_t, size_t, size_t);
+extern bool wstr_remove(char32_t *, size_t);
 
-extern char *str_dup(const char *src);
-extern char *str_ndup(const char *src, size_t n);
+extern char *str_dup(const char *);
+extern char *str_ndup(const char *, size_t);
 
 extern errno_t str_uint64_t(const char *, char **, unsigned int, bool,
@@ -108,6 +108,6 @@
 extern void bin_order_suffix(const uint64_t, uint64_t *, const char **, bool);
 
-extern const char *str_error(errno_t err);
-extern const char *str_error_name(errno_t err);
+extern const char *str_error(errno_t);
+extern const char *str_error_name(errno_t);
 
 #endif
Index: kernel/generic/include/syscall/syscall.h
===================================================================
--- kernel/generic/include/syscall/syscall.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/include/syscall/syscall.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -42,5 +42,4 @@
     sysarg_t, sysarg_t);
 
-extern syshandler_t syscall_table[SYSCALL_END];
 extern sysarg_t syscall_handler(sysarg_t, sysarg_t, sysarg_t, sysarg_t,
     sysarg_t, sysarg_t, sysarg_t);
Index: kernel/generic/include/uchar.h
===================================================================
--- kernel/generic/include/uchar.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
+++ kernel/generic/include/uchar.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2020 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_generic
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _KERN_UCHAR_H_
+#define _KERN_UCHAR_H_
+
+#include <_bits/uchar.h>
+
+#endif
+
+/** @}
+ */
Index: kernel/generic/src/console/chardev.c
===================================================================
--- kernel/generic/src/console/chardev.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/src/console/chardev.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -65,5 +65,5 @@
  *
  */
-void indev_push_character(indev_t *indev, wchar_t ch)
+void indev_push_character(indev_t *indev, char32_t ch)
 {
 	assert(indev);
@@ -92,5 +92,5 @@
  *
  */
-wchar_t indev_pop_character(indev_t *indev)
+char32_t indev_pop_character(indev_t *indev)
 {
 	if (atomic_load(&haltstate)) {
@@ -117,5 +117,5 @@
 	waitq_sleep(&indev->wq);
 	irq_spinlock_lock(&indev->lock, true);
-	wchar_t ch = indev->buffer[(indev->index - indev->counter) %
+	char32_t ch = indev->buffer[(indev->index - indev->counter) %
 	    INDEV_BUFLEN];
 	indev->counter--;
Index: kernel/generic/src/console/console.c
===================================================================
--- kernel/generic/src/console/console.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/src/console/console.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -59,8 +59,8 @@
 
 #define KIO_PAGES    8
-#define KIO_LENGTH   (KIO_PAGES * PAGE_SIZE / sizeof(wchar_t))
+#define KIO_LENGTH   (KIO_PAGES * PAGE_SIZE / sizeof(char32_t))
 
 /** Kernel log cyclic buffer */
-wchar_t kio[KIO_LENGTH] __attribute__((aligned(PAGE_SIZE)));
+char32_t kio[KIO_LENGTH] __attribute__((aligned(PAGE_SIZE)));
 
 /** Kernel log initialized */
@@ -95,5 +95,5 @@
 };
 
-static void stdout_write(outdev_t *, wchar_t);
+static void stdout_write(outdev_t *, char32_t);
 static void stdout_redraw(outdev_t *);
 static void stdout_scroll_up(outdev_t *);
@@ -148,5 +148,5 @@
 }
 
-static void stdout_write(outdev_t *dev, wchar_t ch)
+static void stdout_write(outdev_t *dev, char32_t ch)
 {
 	list_foreach(dev->list, link, outdev_t, sink) {
@@ -261,12 +261,12 @@
 	buf[offset] = 0;
 
-	wchar_t ch;
+	char32_t ch;
 	while ((ch = indev_pop_character(indev)) != '\n') {
 		if (ch == '\b') {
 			if (count > 0) {
 				/* Space, backspace, space */
-				putwchar('\b');
-				putwchar(' ');
-				putwchar('\b');
+				putuchar('\b');
+				putuchar(' ');
+				putuchar('\b');
 
 				count--;
@@ -277,5 +277,5 @@
 
 		if (chr_encode(ch, buf, &offset, buflen - 1) == EOK) {
-			putwchar(ch);
+			putuchar(ch);
 			count++;
 			buf[offset] = 0;
@@ -287,8 +287,8 @@
 
 /** Get character from input device & echo it to screen */
-wchar_t getc(indev_t *indev)
-{
-	wchar_t ch = indev_pop_character(indev);
-	putwchar(ch);
+char32_t getc(indev_t *indev)
+{
+	char32_t ch = indev_pop_character(indev);
+	putuchar(ch);
 	return ch;
 }
@@ -324,5 +324,5 @@
 	/* Print characters that weren't printed earlier */
 	while (kio_stored > 0) {
-		wchar_t tmp = kio[(kio_start + kio_len - kio_stored) % KIO_LENGTH];
+		char32_t tmp = kio[(kio_start + kio_len - kio_stored) % KIO_LENGTH];
 		kio_stored--;
 
@@ -344,5 +344,5 @@
  * The caller is required to hold kio_lock
  */
-void kio_push_char(const wchar_t ch)
+void kio_push_char(const char32_t ch)
 {
 	kio[(kio_start + kio_len) % KIO_LENGTH] = ch;
@@ -360,5 +360,5 @@
 }
 
-void putwchar(const wchar_t ch)
+void putuchar(const char32_t ch)
 {
 	bool ordy = ((stdout) && (stdout->op->write));
@@ -377,10 +377,10 @@
 		 * for possible future output.
 		 *
-		 * The early_putwchar() function is used to output
+		 * The early_putuchar() function is used to output
 		 * the character for low-level debugging purposes.
 		 * Note that the early_putc() function might be
 		 * a no-op on certain hardware configurations.
 		 */
-		early_putwchar(ch);
+		early_putuchar(ch);
 	}
 
Index: kernel/generic/src/console/kconsole.c
===================================================================
--- kernel/generic/src/console/kconsole.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/src/console/kconsole.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -86,5 +86,5 @@
 LIST_INITIALIZE(cmd_list);      /**< Command list. */
 
-static wchar_t history[KCONSOLE_HISTORY][MAX_CMDLINE] = { };
+static char32_t history[KCONSOLE_HISTORY][MAX_CMDLINE] = { };
 static size_t history_pos = 0;
 
@@ -156,9 +156,9 @@
 
 /** Print count times a character */
-_NO_TRACE static void print_cc(wchar_t ch, size_t count)
+_NO_TRACE static void print_cc(char32_t ch, size_t count)
 {
 	size_t i;
 	for (i = 0; i < count; i++)
-		putwchar(ch);
+		putuchar(ch);
 }
 
@@ -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 char32_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 char32_t *clever_readline(const char *prompt, indev_t *indev,
     char *tmp)
 {
@@ -337,13 +337,13 @@
 
 	size_t position = 0;
-	wchar_t *current = history[history_pos];
+	char32_t *current = history[history_pos];
 	current[0] = 0;
 
 	while (true) {
-		wchar_t ch = indev_pop_character(indev);
+		char32_t ch = indev_pop_character(indev);
 
 		if (ch == '\n') {
 			/* Enter */
-			putwchar(ch);
+			putuchar(ch);
 			break;
 		}
@@ -356,5 +356,5 @@
 			if (wstr_remove(current, position - 1)) {
 				position--;
-				putwchar('\b');
+				putuchar('\b');
 				printf("%ls ", current + position);
 				print_cc('\b', wstr_length(current) - position + 1);
@@ -369,5 +369,5 @@
 			for (; (current[position] != 0) && (!isspace(current[position]));
 			    position++)
-				putwchar(current[position]);
+				putuchar(current[position]);
 
 			/*
@@ -464,5 +464,5 @@
 			/* Left */
 			if (position > 0) {
-				putwchar('\b');
+				putuchar('\b');
 				position--;
 			}
@@ -473,5 +473,5 @@
 			/* Right */
 			if (position < wstr_length(current)) {
-				putwchar(current[position]);
+				putuchar(current[position]);
 				position++;
 			}
@@ -646,5 +646,5 @@
 	size_t offset = *start;
 	size_t prev = *start;
-	wchar_t ch;
+	char32_t ch;
 
 	while ((ch = str_decode(cmdline, &offset, size)) != 0) {
@@ -825,5 +825,5 @@
 
 	while (true) {
-		wchar_t *tmp = clever_readline((char *) prompt, stdin, buffer);
+		char32_t *tmp = clever_readline((char *) prompt, stdin, buffer);
 		size_t len = wstr_length(tmp);
 		if (!len)
Index: kernel/generic/src/console/prompt.c
===================================================================
--- kernel/generic/src/console/prompt.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/src/console/prompt.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -56,5 +56,5 @@
 
 	while (true) {
-		wchar_t answer = indev_pop_character(indev);
+		char32_t answer = indev_pop_character(indev);
 
 		if ((answer == 'y') || (answer == 'Y')) {
@@ -87,5 +87,5 @@
 	printf("--More--");
 	while (true) {
-		wchar_t continue_showing_hints = indev_pop_character(indev);
+		char32_t continue_showing_hints = indev_pop_character(indev);
 		/* Display a full page again? */
 		if ((continue_showing_hints == 'y') ||
Index: kernel/generic/src/cpu/cpu.c
===================================================================
--- kernel/generic/src/cpu/cpu.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/src/cpu/cpu.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -71,8 +71,9 @@
 		memsetb(cpus, sizeof(cpu_t) * config.cpu_count, 0);
 
-		// NOTE: All kernel stacks must be aligned to STACK_SIZE,
-		//       see get_stack_base().
-		size_t i;
-		for (i = 0; i < config.cpu_count; i++) {
+		/*
+		 * NOTE: All kernel stacks must be aligned to STACK_SIZE,
+		 *       see CURRENT.
+		 */
+		for (size_t i = 0; i < config.cpu_count; i++) {
 			uintptr_t stack_phys = frame_alloc(STACK_FRAMES,
 			    FRAME_LOWMEM | FRAME_ATOMIC, STACK_SIZE - 1);
Index: kernel/generic/src/lib/str.c
===================================================================
--- kernel/generic/src/lib/str.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/src/lib/str.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -42,5 +42,5 @@
  * 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
+ * represented as char32_t.@n
  *
  * Overview of the terminology:@n
@@ -50,6 +50,6 @@
  *  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
+ *  character             UTF-32 encoded Unicode character, stored in char32_t
+ *                        (unsigned 32 bit integer), code points 0 .. 1114111
  *                        are valid
  *
@@ -61,5 +61,5 @@
  *
  *  wide string           UTF-32 encoded NULL-terminated Unicode string,
- *                        wchar_t *
+ *                        char32_t *
  *
  *  [wide] string size    number of BYTES in a [wide] string (excluding
@@ -100,5 +100,5 @@
  * A specific character inside a [wide] string can be referred to by:@n
  *
- *  pointer (char *, wchar_t *)
+ *  pointer (char *, char32_t *)
  *  byte offset (size_t)
  *  character index (size_t)
@@ -118,11 +118,4 @@
 #include <macros.h>
 
-/** Check the condition if wchar_t is signed */
-#ifdef __WCHAR_UNSIGNED__
-#define WCHAR_SIGNED_CHECK(cond)  (true)
-#else
-#define WCHAR_SIGNED_CHECK(cond)  (cond)
-#endif
-
 /** Byte mask consisting of lowest @n bits (out of 8) */
 #define LO_MASK_8(n)  ((uint8_t) ((1 << (n)) - 1))
@@ -152,5 +145,5 @@
  *
  */
-wchar_t str_decode(const char *str, size_t *offset, size_t size)
+char32_t str_decode(const char *str, size_t *offset, size_t size)
 {
 	if (*offset + 1 > size)
@@ -189,5 +182,5 @@
 		return U_SPECIAL;
 
-	wchar_t ch = b0 & LO_MASK_8(b0_bits);
+	char32_t ch = b0 & LO_MASK_8(b0_bits);
 
 	/* Decode continuation bytes */
@@ -200,5 +193,5 @@
 
 		/* Shift data bits to ch */
-		ch = (ch << CONT_BITS) | (wchar_t) (b & LO_MASK_8(CONT_BITS));
+		ch = (ch << CONT_BITS) | (char32_t) (b & LO_MASK_8(CONT_BITS));
 		cbytes--;
 	}
@@ -222,5 +215,5 @@
  *         code was invalid.
  */
-errno_t chr_encode(const wchar_t ch, char *str, size_t *offset, size_t size)
+errno_t chr_encode(const char32_t ch, char *str, size_t *offset, size_t size)
 {
 	if (*offset >= size)
@@ -308,7 +301,7 @@
  *
  */
-size_t wstr_size(const wchar_t *str)
-{
-	return (wstr_length(str) * sizeof(wchar_t));
+size_t wstr_size(const char32_t *str)
+{
+	return (wstr_length(str) * sizeof(char32_t));
 }
 
@@ -354,7 +347,7 @@
  *
  */
-size_t wstr_lsize(const wchar_t *str, size_t max_len)
-{
-	return (wstr_nlength(str, max_len * sizeof(wchar_t)) * sizeof(wchar_t));
+size_t wstr_lsize(const char32_t *str, size_t max_len)
+{
+	return (wstr_nlength(str, max_len * sizeof(char32_t)) * sizeof(char32_t));
 }
 
@@ -384,5 +377,5 @@
  *
  */
-size_t wstr_length(const wchar_t *wstr)
+size_t wstr_length(const char32_t *wstr)
 {
 	size_t len = 0;
@@ -421,13 +414,13 @@
  *
  */
-size_t wstr_nlength(const wchar_t *str, size_t size)
+size_t wstr_nlength(const char32_t *str, size_t size)
 {
 	size_t len = 0;
-	size_t limit = ALIGN_DOWN(size, sizeof(wchar_t));
+	size_t limit = ALIGN_DOWN(size, sizeof(char32_t));
 	size_t offset = 0;
 
 	while ((offset < limit) && (*str++ != 0)) {
 		len++;
-		offset += sizeof(wchar_t);
+		offset += sizeof(char32_t);
 	}
 
@@ -440,7 +433,7 @@
  *
  */
-bool ascii_check(wchar_t ch)
-{
-	if (WCHAR_SIGNED_CHECK(ch >= 0) && (ch <= 127))
+bool ascii_check(char32_t ch)
+{
+	if (ch <= 127)
 		return true;
 
@@ -453,7 +446,7 @@
  *
  */
-bool chr_check(wchar_t ch)
-{
-	if (WCHAR_SIGNED_CHECK(ch >= 0) && (ch <= 1114111))
+bool chr_check(char32_t ch)
+{
+	if (ch <= 1114111)
 		return true;
 
@@ -481,6 +474,6 @@
 int str_cmp(const char *s1, const char *s2)
 {
-	wchar_t c1 = 0;
-	wchar_t c2 = 0;
+	char32_t c1 = 0;
+	char32_t c2 = 0;
 
 	size_t off1 = 0;
@@ -528,6 +521,6 @@
 int str_lcmp(const char *s1, const char *s2, size_t max_len)
 {
-	wchar_t c1 = 0;
-	wchar_t c2 = 0;
+	char32_t c1 = 0;
+	char32_t c2 = 0;
 
 	size_t off1 = 0;
@@ -580,5 +573,5 @@
 	size_t dest_off = 0;
 
-	wchar_t ch;
+	char32_t ch;
 	while ((ch = str_decode(src, &src_off, STR_NO_LIMIT)) != 0) {
 		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
@@ -613,5 +606,5 @@
 	size_t dest_off = 0;
 
-	wchar_t ch;
+	char32_t ch;
 	while ((ch = str_decode(src, &src_off, n)) != 0) {
 		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
@@ -628,11 +621,11 @@
  * 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;
+ * @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 char32_t *src)
+{
+	char32_t ch;
 	size_t src_idx;
 	size_t dest_off;
@@ -659,7 +652,7 @@
  * @return Pointer to character in @a str or NULL if not found.
  */
-char *str_chr(const char *str, wchar_t ch)
-{
-	wchar_t acc;
+char *str_chr(const char *str, char32_t ch)
+{
+	char32_t acc;
 	size_t off = 0;
 	size_t last = 0;
@@ -688,5 +681,5 @@
  *
  */
-bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos)
+bool wstr_linsert(char32_t *str, char32_t ch, size_t pos, size_t max_pos)
 {
 	size_t len = wstr_length(str);
@@ -716,5 +709,5 @@
  *
  */
-bool wstr_remove(wchar_t *str, size_t pos)
+bool wstr_remove(char32_t *str, size_t pos)
 {
 	size_t len = wstr_length(str);
Index: kernel/generic/src/lib/str_error.c
===================================================================
--- kernel/generic/src/lib/str_error.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/src/lib/str_error.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -53,5 +53,5 @@
 
 #undef __errno_entry
-#define __errno_entry(name, num, desc) "[" #name "]" desc,
+#define __errno_entry(name, num, desc) "[" #name "] " desc,
 
 static const char *err_desc[] = {
Index: kernel/generic/src/log/log.c
===================================================================
--- kernel/generic/src/log/log.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/src/log/log.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -214,5 +214,5 @@
 }
 
-static int log_printf_wstr_write(const wchar_t *wstr, size_t size, void *data)
+static int log_printf_wstr_write(const char32_t *wstr, size_t size, void *data)
 {
 	char buffer[16];
@@ -220,5 +220,5 @@
 	size_t chars = 0;
 
-	for (offset = 0; offset < size; offset += sizeof(wchar_t), chars++) {
+	for (offset = 0; offset < size; offset += sizeof(char32_t), chars++) {
 		kio_push_char(wstr[chars]);
 
Index: kernel/generic/src/main/main.c
===================================================================
--- kernel/generic/src/main/main.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/src/main/main.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -170,6 +170,8 @@
 	    ALIGN_UP((uintptr_t) kdata_end - config.base, PAGE_SIZE);
 
-	// NOTE: All kernel stacks must be aligned to STACK_SIZE,
-	//       see get_stack_base().
+	/*
+	 * NOTE: All kernel stacks must be aligned to STACK_SIZE,
+	 *       see CURRENT.
+	 */
 
 	/* Place the stack after the kernel, init and ballocs. */
Index: kernel/generic/src/printf/printf_core.c
===================================================================
--- kernel/generic/src/printf/printf_core.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/src/printf/printf_core.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -139,5 +139,5 @@
  *
  */
-static int printf_wputnchars(const wchar_t *buf, size_t size,
+static int printf_wputnchars(const char32_t *buf, size_t size,
     printf_spec_t *ps)
 {
@@ -185,10 +185,10 @@
  *
  */
-static int printf_putwchar(const wchar_t ch, printf_spec_t *ps)
+static int printf_putuchar(const char32_t ch, printf_spec_t *ps)
 {
 	if (!chr_check(ch))
 		return ps->str_write((void *) &invalch, 1, ps->data);
 
-	return ps->wstr_write(&ch, sizeof(wchar_t), ps->data);
+	return ps->wstr_write(&ch, sizeof(char32_t), ps->data);
 }
 
@@ -240,5 +240,5 @@
  *
  */
-static int print_wchar(const wchar_t ch, int width, uint32_t flags, printf_spec_t *ps)
+static int print_wchar(const char32_t ch, int width, uint32_t flags, printf_spec_t *ps)
 {
 	size_t counter = 0;
@@ -254,5 +254,5 @@
 	}
 
-	if (printf_putwchar(ch, ps) > 0)
+	if (printf_putuchar(ch, ps) > 0)
 		counter++;
 
@@ -326,5 +326,5 @@
  * @return Number of wide characters printed, negative value on failure.
  */
-static int print_wstr(wchar_t *str, int width, unsigned int precision,
+static int print_wstr(char32_t *str, int width, unsigned int precision,
     uint32_t flags, printf_spec_t *ps)
 {
@@ -576,5 +576,5 @@
  *  - "l"  Signed or unsigned long int.@n
  *         If conversion is "c", the character is wint_t (wide character).@n
- *         If conversion is "s", the string is wchar_t * (wide string).@n
+ *         If conversion is "s", the string is char32_t * (UTF-32 string).@n
  *  - "ll" Signed or unsigned long long int.@n
  *  - "z"  Signed or unsigned ssize_t or site_t.@n
@@ -630,5 +630,5 @@
 	while (true) {
 		i = nxt;
-		wchar_t uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
+		char32_t uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
 
 		if (uc == 0)
@@ -789,5 +789,5 @@
 			case 's':
 				if (qualifier == PrintfQualifierLong)
-					retval = print_wstr(va_arg(ap, wchar_t *), width, precision, flags, ps);
+					retval = print_wstr(va_arg(ap, char32_t *), width, precision, flags, ps);
 				else
 					retval = print_str(va_arg(ap, char *), width, precision, flags, ps);
Index: kernel/generic/src/printf/vprintf.c
===================================================================
--- kernel/generic/src/printf/vprintf.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/src/printf/vprintf.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -47,5 +47,5 @@
 
 	while (offset < size) {
-		putwchar(str_decode(str, &offset, size));
+		putuchar(str_decode(str, &offset, size));
 		chars++;
 	}
@@ -54,5 +54,5 @@
 }
 
-static int vprintf_wstr_write(const wchar_t *str, size_t size, void *data)
+static int vprintf_wstr_write(const char32_t *str, size_t size, void *data)
 {
 	size_t offset = 0;
@@ -60,7 +60,7 @@
 
 	while (offset < size) {
-		putwchar(str[chars]);
+		putuchar(str[chars]);
 		chars++;
-		offset += sizeof(wchar_t);
+		offset += sizeof(char32_t);
 	}
 
@@ -72,12 +72,12 @@
 	size_t offset = 0;
 	size_t chars = 0;
-	wchar_t uc;
+	char32_t uc;
 
 	while ((uc = str_decode(str, &offset, STR_NO_LIMIT)) != 0) {
-		putwchar(uc);
+		putuchar(uc);
 		chars++;
 	}
 
-	putwchar('\n');
+	putuchar('\n');
 	return chars;
 }
Index: kernel/generic/src/printf/vsnprintf.c
===================================================================
--- kernel/generic/src/printf/vsnprintf.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/src/printf/vsnprintf.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -88,5 +88,5 @@
 
 		while (index < size) {
-			wchar_t uc = str_decode(str, &index, size);
+			char32_t uc = str_decode(str, &index, size);
 
 			if (chr_encode(uc, data->dst, &data->len, data->size - 1) != EOK)
@@ -133,9 +133,9 @@
  *
  */
-static int vsnprintf_wstr_write(const wchar_t *str, size_t size, vsnprintf_data_t *data)
+static int vsnprintf_wstr_write(const char32_t *str, size_t size, vsnprintf_data_t *data)
 {
 	size_t index = 0;
 
-	while (index < (size / sizeof(wchar_t))) {
+	while (index < (size / sizeof(char32_t))) {
 		size_t left = data->size - data->len;
 
@@ -177,5 +177,5 @@
 	printf_spec_t ps = {
 		(int (*) (const char *, size_t, void *)) vsnprintf_str_write,
-		(int (*) (const wchar_t *, size_t, void *)) vsnprintf_wstr_write,
+		(int (*) (const char32_t *, size_t, void *)) vsnprintf_wstr_write,
 		&data
 	};
Index: kernel/generic/src/proc/program.c
===================================================================
--- kernel/generic/src/proc/program.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/src/proc/program.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -187,5 +187,5 @@
 		log(LF_OTHER, LVL_ERROR, "Cannot spawn loader (%s)",
 		    str_error(prg->loader_status));
-		return ENOENT;
+		return prg->loader_status;
 	}
 
Index: kernel/generic/src/proc/thread.c
===================================================================
--- kernel/generic/src/proc/thread.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/src/proc/thread.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -191,6 +191,8 @@
 	kmflags &= ~FRAME_HIGHMEM;
 
-	// NOTE: All kernel stacks must be aligned to STACK_SIZE,
-	//       see get_stack_base().
+	/*
+	 * NOTE: All kernel stacks must be aligned to STACK_SIZE,
+	 *       see CURRENT.
+	 */
 
 	uintptr_t stack_phys =
Index: kernel/generic/src/syscall/syscall.c
===================================================================
--- kernel/generic/src/syscall/syscall.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/src/syscall/syscall.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -56,67 +56,5 @@
 #include <log.h>
 
-/** Dispatch system call */
-sysarg_t syscall_handler(sysarg_t a1, sysarg_t a2, sysarg_t a3,
-    sysarg_t a4, sysarg_t a5, sysarg_t a6, sysarg_t id)
-{
-	/* Do userpace accounting */
-	irq_spinlock_lock(&THREAD->lock, true);
-	thread_update_accounting(true);
-	irq_spinlock_unlock(&THREAD->lock, true);
-
-#ifdef CONFIG_UDEBUG
-	/*
-	 * An istate_t-compatible record was created on the stack by the
-	 * low-level syscall handler. This is the userspace space state
-	 * structure.
-	 */
-	THREAD->udebug.uspace_state = istate_get(THREAD);
-
-	/*
-	 * Early check for undebugged tasks. We do not lock anything as this
-	 * test need not be precise in either direction.
-	 */
-	if (THREAD->udebug.active)
-		udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, 0, false);
-#endif
-
-	sysarg_t rc;
-	if (id < SYSCALL_END) {
-		rc = syscall_table[id](a1, a2, a3, a4, a5, a6);
-	} else {
-		log(LF_OTHER, LVL_ERROR,
-		    "Task %" PRIu64 ": Unknown syscall %#" PRIxn, TASK->taskid, id);
-		task_kill_self(true);
-	}
-
-	if (THREAD->interrupted)
-		thread_exit();
-
-#ifdef CONFIG_UDEBUG
-	if (THREAD->udebug.active) {
-		udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, rc, true);
-
-		/*
-		 * Stopping point needed for tasks that only invoke
-		 * non-blocking system calls. Not needed if the task
-		 * is not being debugged (it cannot block here).
-		 */
-		udebug_stoppable_begin();
-		udebug_stoppable_end();
-	}
-
-	/* Clear userspace state pointer */
-	THREAD->udebug.uspace_state = NULL;
-#endif
-
-	/* Do kernel accounting */
-	irq_spinlock_lock(&THREAD->lock, true);
-	thread_update_accounting(false);
-	irq_spinlock_unlock(&THREAD->lock, true);
-
-	return rc;
-}
-
-syshandler_t syscall_table[SYSCALL_END] = {
+static syshandler_t syscall_table[] = {
 	/* System management syscalls. */
 	[SYS_KIO] = (syshandler_t) sys_kio,
@@ -198,4 +136,66 @@
 };
 
+/** Dispatch system call */
+sysarg_t syscall_handler(sysarg_t a1, sysarg_t a2, sysarg_t a3,
+    sysarg_t a4, sysarg_t a5, sysarg_t a6, sysarg_t id)
+{
+	/* Do userpace accounting */
+	irq_spinlock_lock(&THREAD->lock, true);
+	thread_update_accounting(true);
+	irq_spinlock_unlock(&THREAD->lock, true);
+
+#ifdef CONFIG_UDEBUG
+	/*
+	 * An istate_t-compatible record was created on the stack by the
+	 * low-level syscall handler. This is the userspace space state
+	 * structure.
+	 */
+	THREAD->udebug.uspace_state = istate_get(THREAD);
+
+	/*
+	 * Early check for undebugged tasks. We do not lock anything as this
+	 * test need not be precise in either direction.
+	 */
+	if (THREAD->udebug.active)
+		udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, 0, false);
+#endif
+
+	sysarg_t rc;
+	if (id < sizeof_array(syscall_table)) {
+		rc = syscall_table[id](a1, a2, a3, a4, a5, a6);
+	} else {
+		log(LF_OTHER, LVL_ERROR,
+		    "Task %" PRIu64 ": Unknown syscall %#" PRIxn, TASK->taskid, id);
+		task_kill_self(true);
+	}
+
+	if (THREAD->interrupted)
+		thread_exit();
+
+#ifdef CONFIG_UDEBUG
+	if (THREAD->udebug.active) {
+		udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, rc, true);
+
+		/*
+		 * Stopping point needed for tasks that only invoke
+		 * non-blocking system calls. Not needed if the task
+		 * is not being debugged (it cannot block here).
+		 */
+		udebug_stoppable_begin();
+		udebug_stoppable_end();
+	}
+
+	/* Clear userspace state pointer */
+	THREAD->udebug.uspace_state = NULL;
+#endif
+
+	/* Do kernel accounting */
+	irq_spinlock_lock(&THREAD->lock, true);
+	thread_update_accounting(false);
+	irq_spinlock_unlock(&THREAD->lock, true);
+
+	return rc;
+}
+
 /** @}
  */
Index: kernel/generic/src/sysinfo/stats.c
===================================================================
--- kernel/generic/src/sysinfo/stats.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ kernel/generic/src/sysinfo/stats.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -69,4 +69,12 @@
 #define LOAD_INTERVAL  5
 
+/** IPC connections statistics state */
+typedef struct {
+	bool counting;
+	size_t count;
+	size_t i;
+	stats_ipcc_t *data;
+} ipccs_state_t;
+
 /** Fixed-point representation of
  *
@@ -371,4 +379,119 @@
 
 	return ((void *) stats_threads);
+}
+
+/** Produce IPC connection statistics
+ *
+ * Summarize IPC connection information into IPC connection statistics.
+ *
+ * @param cap Phone capability.
+ * @param arg State variable.
+ *
+ */
+static bool produce_stats_ipcc_cb(cap_t *cap, void *arg)
+{
+	phone_t *phone = cap->kobject->phone;
+	ipccs_state_t *state = (ipccs_state_t *) arg;
+
+	if (state->counting) {
+		/*
+		 * Simply update the number of entries
+		 * in case we are in the counting mode.
+		 */
+
+		state->count++;
+		return true;
+	}
+
+	/* We are in the gathering mode */
+
+	if ((state->data == NULL) || (state->i >= state->count)) {
+		/*
+		 * Do nothing if we have no buffer
+		 * to store the data to (meaning we are
+		 * in a dry run) or the buffer is already
+		 * full.
+		 */
+
+		return true;
+	}
+
+	mutex_lock(&phone->lock);
+
+	if (phone->state == IPC_PHONE_CONNECTED) {
+		state->data[state->i].caller = phone->caller->taskid;
+		state->data[state->i].callee = phone->callee->task->taskid;
+		state->i++;
+	}
+
+	mutex_unlock(&phone->lock);
+
+	return true;
+}
+
+/** Get IPC connections statistics
+ *
+ * @param item    Sysinfo item (unused).
+ * @param size    Size of the returned data.
+ * @param dry_run Do not get the data, just calculate the size.
+ * @param data    Unused.
+ *
+ * @return Data containing several stats_ipccs_t structures.
+ *         If the return value is not NULL, it should be freed
+ *         in the context of the sysinfo request.
+ *
+ */
+static void *get_stats_ipccs(struct sysinfo_item *item, size_t *size,
+    bool dry_run, void *data)
+{
+	/* Messing with tasks structures, avoid deadlock */
+	irq_spinlock_lock(&tasks_lock, true);
+
+	ipccs_state_t state = {
+		.counting = true,
+		.count = 0,
+		.i = 0,
+		.data = NULL
+	};
+
+	/* Compute the number of IPC connections */
+	task_t *task = task_first();
+	while (task != NULL) {
+		task_hold(task);
+		irq_spinlock_unlock(&tasks_lock, true);
+
+		caps_apply_to_kobject_type(task, KOBJECT_TYPE_PHONE,
+		    produce_stats_ipcc_cb, &state);
+
+		irq_spinlock_lock(&tasks_lock, true);
+
+		task = task_next(task);
+	}
+
+	state.counting = false;
+	*size = sizeof(stats_ipcc_t) * state.count;
+
+	if (!dry_run)
+		state.data = (stats_ipcc_t *) malloc(*size);
+
+	/* Gather the statistics for each task */
+	task = task_first();
+	while (task != NULL) {
+		/* We already hold a reference to the task */
+		irq_spinlock_unlock(&tasks_lock, true);
+
+		caps_apply_to_kobject_type(task, KOBJECT_TYPE_PHONE,
+		    produce_stats_ipcc_cb, &state);
+
+		irq_spinlock_lock(&tasks_lock, true);
+
+		task_t *prev_task = task;
+		task = task_next(prev_task);
+		task_release(prev_task);
+	}
+
+	irq_spinlock_unlock(&tasks_lock, true);
+
+	return ((void *) state.data);
 }
 
@@ -754,4 +877,5 @@
 	sysinfo_set_item_gen_data("system.tasks", NULL, get_stats_tasks, NULL);
 	sysinfo_set_item_gen_data("system.threads", NULL, get_stats_threads, NULL);
+	sysinfo_set_item_gen_data("system.ipccs", NULL, get_stats_ipccs, NULL);
 	sysinfo_set_item_gen_data("system.exceptions", NULL, get_stats_exceptions, NULL);
 	sysinfo_set_subtree_fn("system.tasks", NULL, get_stats_task, NULL);
Index: meson/part/compiler_args/meson.build
===================================================================
--- meson/part/compiler_args/meson.build	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ meson/part/compiler_args/meson.build	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -39,8 +39,6 @@
 
 add_project_link_arguments(
-	cc.get_supported_link_arguments([
-		'-Wl,--gc-sections',
-		'-Wl,--warn-common',
-	]),
+	'-Wl,--gc-sections',
+	'-Wl,--warn-common',
 	'-Wl,--fatal-warnings',
 	language : [ 'c', 'cpp' ],
Index: meson/part/extra_targets/meson.build
===================================================================
--- meson/part/extra_targets/meson.build	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ meson/part/extra_targets/meson.build	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -82,4 +82,10 @@
 endif
 
+if cppcheck.found()
+	run_target('cppcheck', command: ['cppcheck', '--project=' +
+		join_paths(meson.build_root(), 'compile_commands.json'),
+		' -q --force --file-list=*.c* --platform=unix32 --enable=all' ])
+endif
+
 # TODO text-xcw
 #ifeq ($(CONFIG_DEVEL_FILES),y)
Index: meson/part/initrd/meson.build
===================================================================
--- meson/part/initrd/meson.build	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ meson/part/initrd/meson.build	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -99,4 +99,5 @@
 	input: [ install_script, install_deps ],
 	command: [ sh, '@INPUT0@', '@OUTPUT@', dist_dir ],
+	build_always_stale: true,
 )
 
Index: meson/part/tools/meson.build
===================================================================
--- meson/part/tools/meson.build	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ meson/part/tools/meson.build	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -54,4 +54,5 @@
 which = find_program('which')
 cpc = find_program(_tools_dir / 'cc.sh')
+cppcheck = find_program('cppcheck', required: false)
 
 sh = [ find_program('sh'), '-u', '-e' ]
@@ -61,16 +62,18 @@
 
 genisoimage = find_program('genisoimage', required: false)
-
-if not genisoimage.found()
+if genisoimage.found()
+	genisoimage_type = 'genisoimage'
+else
 	genisoimage = find_program('mkisofs', required: false)
-endif
-
-if not genisoimage.found()
-	xorriso = find_program('xorriso', required: false)
-
-	if xorriso.found()
-		genisoimage = [ xorriso, '-as', 'genisoimage' ]
+	if genisoimage.found()
+		genisoimage_type = 'mkisofs'
 	else
-		error('Need genisoimage, mkisofs or xorriso.')
+		xorriso = find_program('xorriso', required: false)
+		if xorriso.found()
+			genisoimage = [ xorriso, '-as', 'genisoimage' ]
+			genisoimage_type = 'genisoimage'
+		else
+			error('Need genisoimage, mkisofs or xorriso.')
+		endif
 	endif
 endif
Index: tools/ew.py
===================================================================
--- tools/ew.py	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ tools/ew.py	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -1,3 +1,3 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 # Copyright (c) 2013 Jakub Jermar
@@ -39,5 +39,5 @@
 import subprocess
 import sys
-import thread
+import _thread
 import time
 
@@ -68,7 +68,7 @@
 
 def cfg_get(platform, machine, processor):
-	if machine == "" or emulators[platform].has_key("run"):
+	if machine == "" or "run" in emulators[platform]:
 		return emulators[platform]
-	elif processor == "" or emulators[platform][machine].has_key("run"):
+	elif processor == "" or "run" in emulators[platform][machine]:
 		return emulators[platform][machine]
 	else:
@@ -148,5 +148,5 @@
 		)
 		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")
+		    "http://snapshots.linaro.org/components/kernel/leg-virt-tianocore-edk2-upstream/latest/QEMU-AARCH64/RELEASE_GCC5/QEMU_EFI.fd.\n")
 		efi_path = find_firmware(
 		    "EDK2", 'EW_QEMU_EFI_AARCH64', default_paths, extra_info)
Index: tools/toolchain.sh
===================================================================
--- tools/toolchain.sh	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ tools/toolchain.sh	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -362,5 +362,5 @@
 
 	change_title "binutils: configure (${PLATFORM})"
-	CFLAGS=-Wno-error "${BASEDIR}/downloads/binutils-${BINUTILS_VERSION}/configure" \
+	CFLAGS="-Wno-error -fcommon" "${BASEDIR}/downloads/binutils-${BINUTILS_VERSION}/configure" \
 		"--target=${TARGET}" \
 		"--prefix=${PREFIX}" \
@@ -439,5 +439,5 @@
 
 	change_title "GDB: configure (${PLATFORM})"
-	PATH="$PATH:${INSTALL_DIR}/${PREFIX}/bin" "${BASEDIR}/downloads/gdb-${GDB_VERSION}/configure" \
+	CFLAGS="-fcommon" PATH="$PATH:${INSTALL_DIR}/${PREFIX}/bin" "${BASEDIR}/downloads/gdb-${GDB_VERSION}/configure" \
 		"--target=${TARGET}" \
 		"--prefix=${PREFIX}" \
Index: uspace/app/bdsh/cmds/modules/cat/cat.c
===================================================================
--- uspace/app/bdsh/cmds/modules/cat/cat.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/bdsh/cmds/modules/cat/cat.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -154,5 +154,5 @@
 }
 
-static void paged_char(wchar_t c)
+static void paged_char(char32_t c)
 {
 	if (last_char_was_newline && number) {
@@ -160,5 +160,5 @@
 		printf("%6u  ", lineno);
 	}
-	putwchar(c);
+	putuchar(c);
 	last_char_was_newline = c == '\n';
 	if (paging_enabled) {
@@ -269,5 +269,5 @@
 					paged_char(((count + i + 1) & 0xf) == 0 ? '\n' : ' ');
 				} else {
-					wchar_t c = str_decode(buff, &offset, bytes);
+					char32_t c = str_decode(buff, &offset, bytes);
 					if (c == 0) {
 						/* Reached end of string */
Index: uspace/app/bdsh/cmds/modules/mkdir/mkdir.c
===================================================================
--- uspace/app/bdsh/cmds/modules/mkdir/mkdir.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/bdsh/cmds/modules/mkdir/mkdir.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -108,5 +108,5 @@
 		while (true) {
 			size_t prev_off = off;
-			wchar_t cur_char = str_decode(path, &off, STR_NO_LIMIT);
+			char32_t cur_char = str_decode(path, &off, STR_NO_LIMIT);
 			if ((cur_char == 0) || (cur_char == U_SPECIAL)) {
 				break;
Index: uspace/app/bdsh/cmds/modules/printf/printf.c
===================================================================
--- uspace/app/bdsh/cmds/modules/printf/printf.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/bdsh/cmds/modules/printf/printf.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -68,5 +68,5 @@
  * @param arg string with data to print.
  */
-static int print_arg(wchar_t ch, const char *arg)
+static int print_arg(char32_t ch, const char *arg)
 {
 	switch (ch) {
@@ -93,5 +93,5 @@
  * @param ch  Control character.
  */
-static int process_ctl(wchar_t ch)
+static int process_ctl(char32_t ch)
 {
 	switch (ch) {
@@ -120,5 +120,5 @@
 	char *fmt;
 	size_t pos, fmt_sz;
-	wchar_t ch;
+	char32_t ch;
 	bool esc_flag = false;
 	unsigned int carg;     // Current argument
@@ -170,9 +170,9 @@
 				break;
 			}
-			putwchar(ch);
+			putuchar(ch);
 			break;
 
 		emit:
-			putwchar(ch);
+			putuchar(ch);
 			esc_flag = false;
 		}
Index: uspace/app/bdsh/compl.c
===================================================================
--- uspace/app/bdsh/compl.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/bdsh/compl.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -44,5 +44,5 @@
 #include "util.h"
 
-static errno_t compl_init(wchar_t *text, size_t pos, size_t *cstart, void **state);
+static errno_t compl_init(char32_t *text, size_t pos, size_t *cstart, void **state);
 static errno_t compl_get_next(void *state, char **compl);
 static void compl_fini(void *state);
@@ -94,5 +94,5 @@
  * Set up iterators in completion object, based on current token.
  */
-static errno_t compl_init(wchar_t *text, size_t pos, size_t *cstart, void **state)
+static errno_t compl_init(char32_t *text, size_t pos, size_t *cstart, void **state)
 {
 	compl_t *cs = NULL;
Index: uspace/app/bdsh/tok.c
===================================================================
--- uspace/app/bdsh/tok.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/bdsh/tok.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -36,7 +36,7 @@
 
 /* Forward declarations of static functions */
-static wchar_t tok_get_char(tokenizer_t *);
-static wchar_t tok_look_char(tokenizer_t *);
-static errno_t tok_push_char(tokenizer_t *, wchar_t);
+static char32_t tok_get_char(tokenizer_t *);
+static char32_t tok_look_char(tokenizer_t *);
+static errno_t tok_push_char(tokenizer_t *, char32_t);
 static errno_t tok_push_token(tokenizer_t *);
 static bool tok_pending_chars(tokenizer_t *);
@@ -92,5 +92,5 @@
 {
 	errno_t rc;
-	wchar_t next_char;
+	char32_t next_char;
 
 	/* Read the input line char by char and append tokens */
@@ -182,5 +182,5 @@
 {
 	errno_t rc;
-	wchar_t next_char;
+	char32_t next_char;
 
 	while ((next_char = tok_look_char(tok)) != 0) {
@@ -214,5 +214,5 @@
 
 /** Get a char from input, advancing the input position */
-wchar_t tok_get_char(tokenizer_t *tok)
+char32_t tok_get_char(tokenizer_t *tok)
 {
 	tok->in_char_offset++;
@@ -221,9 +221,9 @@
 
 /** Get a char from input, while staying on the same input position */
-wchar_t tok_look_char(tokenizer_t *tok)
+char32_t tok_look_char(tokenizer_t *tok)
 {
 	size_t old_offset = tok->in_offset;
 	size_t old_char_offset = tok->in_char_offset;
-	wchar_t ret = tok_get_char(tok);
+	char32_t ret = tok_get_char(tok);
 	tok->in_offset = old_offset;
 	tok->in_char_offset = old_char_offset;
@@ -232,5 +232,5 @@
 
 /** Append a char to the end of the current token */
-errno_t tok_push_char(tokenizer_t *tok, wchar_t ch)
+errno_t tok_push_char(tokenizer_t *tok, char32_t ch)
 {
 	return chr_encode(ch, tok->outbuf, &tok->outbuf_offset, tok->outbuf_size);
Index: uspace/app/edit/edit.c
===================================================================
--- uspace/app/edit/edit.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/edit/edit.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -147,5 +147,5 @@
 static void pane_caret_display(void);
 
-static void insert_char(wchar_t c);
+static void insert_char(char32_t c);
 static void delete_char_before(void);
 static void delete_char_after(void);
@@ -630,5 +630,5 @@
 	kbd_event_t *kev;
 	char *str;
-	wchar_t buffer[INFNAME_MAX_LEN + 1];
+	char32_t buffer[INFNAME_MAX_LEN + 1];
 	int max_len;
 	int nc;
@@ -670,5 +670,5 @@
 				default:
 					if (kev->c >= 32 && nc < max_len) {
-						putwchar(kev->c);
+						putuchar(kev->c);
 						console_flush(con);
 						buffer[nc++] = kev->c;
@@ -696,5 +696,5 @@
 {
 	FILE *f;
-	wchar_t c;
+	char32_t c;
 	char buf[BUF_SIZE];
 	int bcnt;
@@ -791,7 +791,10 @@
 
 		buf_size *= 2;
-		buf = realloc(buf, buf_size);
-		if (buf == NULL)
+		char *tmp = realloc(buf, buf_size);
+		if (tmp == NULL) {
+			free(buf);
 			return NULL;
+		}
+		buf = tmp;
 	}
 
@@ -847,5 +850,5 @@
 	coord_t rbc, rec;
 	char row_buf[ROW_BUF_SIZE];
-	wchar_t c;
+	char32_t c;
 	size_t pos, size;
 	int s_column;
@@ -1052,5 +1055,5 @@
 
 /** Insert a character at caret position. */
-static void insert_char(wchar_t c)
+static void insert_char(char32_t c)
 {
 	spt_t pt;
@@ -1282,5 +1285,5 @@
 
 /* Search operations */
-static errno_t search_spt_producer(void *data, wchar_t *ret)
+static errno_t search_spt_producer(void *data, char32_t *ret)
 {
 	assert(data != NULL);
@@ -1291,5 +1294,5 @@
 }
 
-static errno_t search_spt_reverse_producer(void *data, wchar_t *ret)
+static errno_t search_spt_reverse_producer(void *data, char32_t *ret)
 {
 	assert(data != NULL);
@@ -1510,5 +1513,5 @@
 	char *str;
 	size_t off;
-	wchar_t c;
+	char32_t c;
 	errno_t rc;
 
@@ -1606,5 +1609,5 @@
 }
 
-static wchar_t get_first_wchar(const char *str)
+static char32_t get_first_wchar(const char *str)
 {
 	size_t offset = 0;
@@ -1627,5 +1630,5 @@
 		return false;
 
-	wchar_t first_char = get_first_wchar(ch);
+	char32_t first_char = get_first_wchar(ch);
 	switch (first_char) {
 	case ' ':
@@ -1653,5 +1656,5 @@
 		return false;
 
-	wchar_t first_char = get_first_wchar(ch);
+	char32_t first_char = get_first_wchar(ch);
 	switch (first_char) {
 	case ',':
Index: uspace/app/edit/search.c
===================================================================
--- uspace/app/edit/search.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/edit/search.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -50,5 +50,5 @@
 		return NULL;
 
-	wchar_t *p = str_to_awstr(pattern);
+	char32_t *p = str_to_awstr(pattern);
 	if (p == NULL) {
 		free(search);
@@ -63,5 +63,5 @@
 		half = search->pattern_length / 2;
 		for (pos = 0; pos < half; pos++) {
-			wchar_t tmp = p[pos];
+			char32_t tmp = p[pos];
 			p[pos] = p[search->pattern_length - pos - 1];
 			p[search->pattern_length - pos - 1] = tmp;
@@ -107,5 +107,5 @@
 	search_equals_fn eq = s->ops.equals;
 
-	wchar_t cur_char;
+	char32_t cur_char;
 	errno_t rc = EOK;
 	while ((rc = s->ops.producer(s->client_data, &cur_char)) == EOK && cur_char > 0) {
@@ -141,5 +141,5 @@
 }
 
-bool char_exact_equals(const wchar_t a, const wchar_t b)
+bool char_exact_equals(const char32_t a, const char32_t b)
 {
 	return a == b;
Index: uspace/app/edit/search.h
===================================================================
--- uspace/app/edit/search.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/edit/search.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -42,6 +42,6 @@
 struct search;
 typedef struct search search_t;
-typedef bool (*search_equals_fn)(const wchar_t, const wchar_t);
-typedef errno_t (*search_producer_fn)(void *, wchar_t *);
+typedef bool (*search_equals_fn)(const char32_t, const char32_t);
+typedef errno_t (*search_producer_fn)(void *, char32_t *);
 typedef errno_t (*search_mark_fn)(void *, void **);
 typedef void (*search_mark_free_fn)(void *);
@@ -59,5 +59,5 @@
 } search_ops_t;
 
-extern bool char_exact_equals(const wchar_t, const wchar_t);
+extern bool char_exact_equals(const char32_t, const char32_t);
 extern search_t *search_init(const char *, void *, search_ops_t, bool);
 extern errno_t search_next_match(search_t *, match_t *);
Index: uspace/app/edit/search_impl.h
===================================================================
--- uspace/app/edit/search_impl.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/edit/search_impl.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -43,5 +43,5 @@
 	/* Note: This structure is opaque for the user. */
 
-	wchar_t *pattern;
+	char32_t *pattern;
 	size_t pattern_length;
 	ssize_t *back_table;
Index: uspace/app/edit/sheet.c
===================================================================
--- uspace/app/edit/sheet.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/edit/sheet.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -79,6 +79,8 @@
 
 	sh->data = malloc(sh->dbuf_size);
-	if (sh->data == NULL)
+	if (sh->data == NULL) {
+		free(sh);
 		return ENOMEM;
+	}
 
 	list_initialize(&sh->tags);
@@ -193,5 +195,5 @@
 	size_t copy_sz;
 	size_t off, prev;
-	wchar_t c;
+	char32_t c;
 
 	spp = sh->data + spos->b_off;
@@ -220,5 +222,5 @@
 {
 	size_t cur_pos, prev_pos;
-	wchar_t c;
+	char32_t c;
 	coord_t cc;
 
@@ -289,5 +291,5 @@
 	size_t off;
 	coord_t cc;
-	wchar_t c;
+	char32_t c;
 	sheet_t *sh;
 
@@ -318,7 +320,7 @@
 
 /** Get a character at spt and return next spt */
-wchar_t spt_next_char(spt_t spt, spt_t *next)
-{
-	wchar_t ch = str_decode(spt.sh->data, &spt.b_off, spt.sh->text_size);
+char32_t spt_next_char(spt_t spt, spt_t *next)
+{
+	char32_t ch = str_decode(spt.sh->data, &spt.b_off, spt.sh->text_size);
 	if (next)
 		*next = spt;
@@ -326,7 +328,7 @@
 }
 
-wchar_t spt_prev_char(spt_t spt, spt_t *prev)
-{
-	wchar_t ch = str_decode_reverse(spt.sh->data, &spt.b_off, spt.sh->text_size);
+char32_t spt_prev_char(spt_t spt, spt_t *prev)
+{
+	char32_t ch = str_decode_reverse(spt.sh->data, &spt.b_off, spt.sh->text_size);
 	if (prev)
 		*prev = spt;
Index: uspace/app/edit/sheet.h
===================================================================
--- uspace/app/edit/sheet.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/edit/sheet.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -101,6 +101,6 @@
 extern void spt_get_coord(spt_t const *, coord_t *);
 extern bool spt_equal(spt_t const *, spt_t const *);
-extern wchar_t spt_next_char(spt_t, spt_t *);
-extern wchar_t spt_prev_char(spt_t, spt_t *);
+extern char32_t spt_next_char(spt_t, spt_t *);
+extern char32_t spt_prev_char(spt_t, spt_t *);
 
 extern void sheet_place_tag(sheet_t *, spt_t const *, tag_t *);
Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/init/init.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -53,4 +53,7 @@
 #include "init.h"
 
+#define BANNER_LEFT   "######> "
+#define BANNER_RIGHT  " <######"
+
 #define ROOT_DEVICE       "bd/initrd"
 #define ROOT_MOUNT_POINT  "/"
@@ -83,4 +86,17 @@
 {
 	printf("%s: HelenOS init\n", NAME);
+}
+
+static void oom_check(errno_t rc, const char *path)
+{
+	if (rc == ENOMEM) {
+		printf("%sOut-of-memory condition detected%s\n", BANNER_LEFT,
+		    BANNER_RIGHT);
+		printf("%sBailing out of the boot process after %s%s\n",
+		    BANNER_LEFT, path, BANNER_RIGHT);
+		printf("%sMore physical memory is required%s\n", BANNER_LEFT,
+		    BANNER_RIGHT);
+		exit(ENOMEM);
+	}
 }
 
@@ -201,4 +217,5 @@
 
 	if (rc != EOK) {
+		oom_check(rc, path);
 		printf("%s: Error spawning %s (%s)\n", NAME, path,
 		    str_error(rc));
@@ -269,4 +286,5 @@
 	errno_t rc = task_spawnl(&id, &wait, app, app, display_svc, NULL);
 	if (rc != EOK) {
+		oom_check(rc, app);
 		printf("%s: Error spawning %s (%s)\n", NAME, app,
 		    str_error(rc));
@@ -280,5 +298,5 @@
 		printf("%s: Error retrieving retval from %s (%s)\n", NAME,
 		    app, str_error(rc));
-		return -1;
+		return rc;
 	}
 
@@ -294,7 +312,9 @@
 		errno_t rc = task_spawnl(NULL, NULL, APP_GETTERM, APP_GETTERM, svc,
 		    LOCFS_MOUNT_POINT, "--msg", "--wait", "--", app, NULL);
-		if (rc != EOK)
+		if (rc != EOK) {
+			oom_check(rc, APP_GETTERM);
 			printf("%s: Error spawning %s %s %s --msg --wait -- %s\n",
 			    NAME, APP_GETTERM, svc, LOCFS_MOUNT_POINT, app);
+		}
 	} else {
 		printf("%s: Spawning %s %s %s --wait -- %s\n", NAME,
@@ -303,7 +323,9 @@
 		errno_t rc = task_spawnl(NULL, NULL, APP_GETTERM, APP_GETTERM, svc,
 		    LOCFS_MOUNT_POINT, "--wait", "--", app, NULL);
-		if (rc != EOK)
+		if (rc != EOK) {
+			oom_check(rc, APP_GETTERM);
 			printf("%s: Error spawning %s %s %s --wait -- %s\n",
 			    NAME, APP_GETTERM, svc, LOCFS_MOUNT_POINT, app);
+		}
 	}
 }
Index: uspace/app/kio/kio.c
===================================================================
--- uspace/app/kio/kio.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/kio/kio.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -56,5 +56,5 @@
 	link_t link;
 	size_t length;
-	wchar_t *data;
+	char32_t *data;
 } item_t;
 
@@ -62,5 +62,5 @@
 
 /* Pointer to kio area */
-static wchar_t *kio = (wchar_t *) AS_AREA_ANY;
+static char32_t *kio = (char32_t *) AS_AREA_ANY;
 static size_t kio_length;
 
@@ -77,5 +77,5 @@
  *
  */
-static void producer(size_t length, wchar_t *data)
+static void producer(size_t length, char32_t *data)
 {
 	item_t *item = (item_t *) malloc(sizeof(item_t));
@@ -83,6 +83,6 @@
 		return;
 
-	size_t sz = sizeof(wchar_t) * length;
-	wchar_t *buf = (wchar_t *) malloc(sz);
+	size_t sz = sizeof(char32_t) * length;
+	char32_t *buf = (char32_t *) malloc(sz);
 	if (buf == NULL) {
 		free(item);
@@ -121,9 +121,9 @@
 
 		for (size_t i = 0; i < item->length; i++)
-			putwchar(item->data[i]);
+			putuchar(item->data[i]);
 
 		if (log != NULL) {
 			for (size_t i = 0; i < item->length; i++)
-				fputwc(item->data[i], log);
+				fputuc(item->data[i], log);
 
 			fflush(log);
@@ -202,5 +202,5 @@
 
 	size_t size = pages * PAGE_SIZE;
-	kio_length = size / sizeof(wchar_t);
+	kio_length = size / sizeof(char32_t);
 
 	rc = physmem_map(faddr, pages, AS_AREA_READ | AS_AREA_CACHEABLE,
Index: uspace/app/netecho/netecho.c
===================================================================
--- uspace/app/netecho/netecho.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/netecho/netecho.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -71,5 +71,5 @@
 }
 
-static void send_char(wchar_t c)
+static void send_char(char32_t c)
 {
 	char cbuf[STR_BOUNDS(1)];
Index: uspace/app/nterm/nterm.c
===================================================================
--- uspace/app/nterm/nterm.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/nterm/nterm.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -58,5 +58,5 @@
 }
 
-static void send_char(wchar_t c)
+static void send_char(char32_t c)
 {
 	char cbuf[STR_BOUNDS(1)];
Index: uspace/app/sbi/src/builtin/bi_char.c
===================================================================
--- uspace/app/sbi/src/builtin/bi_char.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/sbi/src/builtin/bi_char.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -90,5 +90,5 @@
 	}
 
-	str = os_chr_to_astr((wchar_t) char_val);
+	str = os_chr_to_astr((char32_t) char_val);
 
 	/* Ownership of str is transferred. */
Index: uspace/app/sbi/src/os/helenos.c
===================================================================
--- uspace/app/sbi/src/os/helenos.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/sbi/src/os/helenos.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -94,5 +94,5 @@
 	size_t i;
 	size_t size;
-	wchar_t c;
+	char32_t c;
 
 	assert(start + length <= str_length(str));
@@ -155,5 +155,5 @@
 	size_t offset;
 	int i;
-	wchar_t c = 0;
+	char32_t c = 0;
 
 	if (index < 0)
@@ -178,5 +178,5 @@
  * @return		Newly allocated string.
  */
-char *os_chr_to_astr(wchar_t chr)
+char *os_chr_to_astr(char32_t chr)
 {
 	char *str;
Index: uspace/app/sbi/src/os/os.h
===================================================================
--- uspace/app/sbi/src/os/os.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/sbi/src/os/os.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -38,5 +38,5 @@
 size_t os_str_length(const char *str);
 errno_t os_str_get_char(const char *str, int index, int *out_char);
-char *os_chr_to_astr(wchar_t chr);
+char *os_chr_to_astr(char32_t chr);
 void os_input_disp_help(void);
 errno_t os_input_line(const char *prompt, char **ptr);
Index: uspace/app/sbi/src/os/posix.c
===================================================================
--- uspace/app/sbi/src/os/posix.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/sbi/src/os/posix.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -164,5 +164,5 @@
  * @return		Newly allocated string.
  */
-char *os_chr_to_astr(wchar_t chr)
+char *os_chr_to_astr(char32_t chr)
 {
 	char *str;
Index: uspace/app/stats/stats.c
===================================================================
--- uspace/app/stats/stats.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/stats/stats.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -52,4 +52,17 @@
 #define MINUTE  60
 
+#define KERNEL_NAME  "kernel"
+#define INIT_PREFIX  "init:"
+
+typedef enum {
+	LIST_TASKS,
+	LIST_THREADS,
+	LIST_IPCCS,
+	LIST_CPUS,
+	PRINT_LOAD,
+	PRINT_UPTIME,
+	PRINT_ARCH
+} output_toggle_t;
+
 static void list_tasks(void)
 {
@@ -65,6 +78,5 @@
 	    " [kcycles] [name\n");
 
-	size_t i;
-	for (i = 0; i < count; i++) {
+	for (size_t i = 0; i < count; i++) {
 		uint64_t resmem;
 		uint64_t virtmem;
@@ -103,6 +115,5 @@
 	printf("[taskid] [threadid] [state ] [prio] [cpu ] [ucycles] [kcycles]\n");
 
-	size_t i;
-	for (i = 0; i < count; i++) {
+	for (size_t i = 0; i < count; i++) {
 		if ((all) || (stats_threads[i].task_id == task_id)) {
 			uint64_t ucycles, kcycles;
@@ -130,4 +141,26 @@
 }
 
+static void list_ipccs(task_id_t task_id, bool all)
+{
+	size_t count;
+	stats_ipcc_t *stats_ipccs = stats_get_ipccs(&count);
+
+	if (stats_ipccs == NULL) {
+		fprintf(stderr, "%s: Unable to get IPC connections\n", NAME);
+		return;
+	}
+
+	printf("[caller] [callee]\n");
+
+	for (size_t i = 0; i < count; i++) {
+		if ((all) || (stats_ipccs[i].caller == task_id)) {
+			printf("%-8" PRIu64 " %-8" PRIu64 "\n",
+			    stats_ipccs[i].caller, stats_ipccs[i].callee);
+		}
+	}
+
+	free(stats_ipccs);
+}
+
 static void list_cpus(void)
 {
@@ -142,6 +175,5 @@
 	printf("[id] [MHz     ] [busy cycles] [idle cycles]\n");
 
-	size_t i;
-	for (i = 0; i < count; i++) {
+	for (size_t i = 0; i < count; i++) {
 		printf("%-4u ", cpus[i].id);
 		if (cpus[i].active) {
@@ -174,6 +206,5 @@
 	printf("%s: Load average: ", NAME);
 
-	size_t i;
-	for (i = 0; i < count; i++) {
+	for (size_t i = 0; i < count; i++) {
 		if (i > 0)
 			printf(" ");
@@ -197,32 +228,172 @@
 }
 
+static char *escape_dot(const char *str)
+{
+	size_t size = 0;
+	for (size_t i = 0; str[i] != 0; i++) {
+		if (str[i] == '"')
+			size++;
+
+		size++;
+	}
+
+	char *escaped_str = calloc(size + 1, sizeof(char));
+	if (escaped_str == NULL)
+		return NULL;
+
+	size_t pos = 0;
+	for (size_t i = 0; str[i] != 0; i++) {
+		if (str[i] == '"') {
+			escaped_str[pos] = '\\';
+			pos++;
+		}
+
+		escaped_str[pos] = str[i];
+		pos++;
+	}
+
+	escaped_str[pos] = 0;
+
+	return escaped_str;
+}
+
+static void print_arch(void)
+{
+	size_t count_tasks;
+	stats_task_t *stats_tasks = stats_get_tasks(&count_tasks);
+
+	if (stats_tasks == NULL) {
+		fprintf(stderr, "%s: Unable to get tasks\n", NAME);
+		return;
+	}
+
+	size_t count_ipccs;
+	stats_ipcc_t *stats_ipccs = stats_get_ipccs(&count_ipccs);
+
+	if (stats_ipccs == NULL) {
+		fprintf(stderr, "%s: Unable to get IPC connections\n", NAME);
+		return;
+	}
+
+	/* Global dot language attributes */
+	printf("digraph HelenOS {\n");
+	printf("\tlayout=sfdp\n");
+	printf("\t// layout=neato\n");
+	printf("\tsplines=true\n");
+	printf("\t// splines=ortho\n");
+	printf("\tconcentrate=true\n");
+	printf("\tcenter=true\n");
+	printf("\toverlap=false\n");
+	printf("\toutputorder=edgesfirst\n");
+	printf("\tfontsize=12\n");
+	printf("\tnode [shape=component style=filled color=red "
+	    "fillcolor=yellow]\n\t\n");
+
+	bool kernel_found = false;
+	task_id_t kernel_id = 0;
+
+	/* Tasks as vertices (components) */
+	for (size_t i = 0; i < count_tasks; i++) {
+		/* Kernel task */
+		bool kernel = (str_cmp(stats_tasks[i].name, KERNEL_NAME) == 0);
+
+		/* Init task */
+		bool init = str_test_prefix(stats_tasks[i].name, INIT_PREFIX);
+
+		char *escaped_name = NULL;
+
+		if (init)
+			escaped_name = escape_dot(str_suffix(stats_tasks[i].name,
+			    str_length(INIT_PREFIX)));
+		else
+			escaped_name = escape_dot(stats_tasks[i].name);
+
+		if (escaped_name == NULL)
+			continue;
+
+		if (kernel) {
+			if (kernel_found) {
+				fprintf(stderr, "%s: Duplicate kernel tasks\n", NAME);
+			} else {
+				kernel_found = true;
+				kernel_id = stats_tasks[i].task_id;
+			}
+
+			printf("\ttask%" PRIu64 " [label=\"%s\" shape=invtrapezium "
+			    "fillcolor=gold]\n", stats_tasks[i].task_id, escaped_name);
+		} else if (init)
+			printf("\ttask%" PRIu64 " [label=\"%s\" fillcolor=orange]\n",
+			    stats_tasks[i].task_id, escaped_name);
+		else
+			printf("\ttask%" PRIu64 " [label=\"%s\"]\n", stats_tasks[i].task_id,
+			    escaped_name);
+
+		free(escaped_name);
+	}
+
+	printf("\t\n");
+
+	if (kernel_found) {
+		/*
+		 * Add an invisible edge from all user
+		 * space tasks to the kernel to increase
+		 * the kernel ranking.
+		 */
+
+		for (size_t i = 0; i < count_tasks; i++) {
+			/* Skip the kernel itself */
+			if (stats_tasks[i].task_id == kernel_id)
+				continue;
+
+			printf("\ttask%" PRIu64 " -> task%" PRIu64 " [style=\"invis\"]\n",
+			    stats_tasks[i].task_id, kernel_id);
+		}
+	}
+
+	printf("\t\n");
+
+	/* IPC connections as edges */
+	for (size_t i = 0; i < count_ipccs; i++) {
+		printf("\ttask%" PRIu64 " -> task%" PRIu64 "\n",
+		    stats_ipccs[i].caller, stats_ipccs[i].callee);
+	}
+
+	printf("}\n");
+
+	free(stats_tasks);
+	free(stats_ipccs);
+}
+
 static void usage(const char *name)
 {
 	printf(
-	    "Usage: %s [-t task_id] [-a] [-c] [-l] [-u]\n"
+	    "Usage: %s [-t task_id] [-i task_id] [-at] [-ai] [-c] [-l] [-u] [-d]\n"
 	    "\n"
 	    "Options:\n"
-	    "\t-t task_id\n"
-	    "\t--task=task_id\n"
+	    "\t-t task_id | --task=task_id\n"
 	    "\t\tList threads of the given task\n"
 	    "\n"
-	    "\t-a\n"
-	    "\t--all\n"
+	    "\t-i task_id | --ipcc=task_id\n"
+	    "\t\tList IPC connections of the given task\n"
+	    "\n"
+	    "\t-at | --all-threads\n"
 	    "\t\tList all threads\n"
 	    "\n"
-	    "\t-c\n"
-	    "\t--cpus\n"
+	    "\t-ai | --all-ipccs\n"
+	    "\t\tList all IPC connections\n"
+	    "\n"
+	    "\t-c | --cpus\n"
 	    "\t\tList CPUs\n"
 	    "\n"
-	    "\t-l\n"
-	    "\t--load\n"
+	    "\t-l | --load\n"
 	    "\t\tPrint system load\n"
 	    "\n"
-	    "\t-u\n"
-	    "\t--uptime\n"
+	    "\t-u | --uptime\n"
 	    "\t\tPrint system uptime\n"
 	    "\n"
-	    "\t-h\n"
-	    "\t--help\n"
+	    "\t-d | --design\n"
+	    "\t\tPrint the current system architecture graph\n"
+	    "\n"
+	    "\t-h | --help\n"
 	    "\t\tPrint this usage information\n"
 	    "\n"
@@ -233,15 +404,9 @@
 int main(int argc, char *argv[])
 {
-	bool toggle_tasks = true;
-	bool toggle_threads = false;
+	output_toggle_t output_toggle = LIST_TASKS;
 	bool toggle_all = false;
-	bool toggle_cpus = false;
-	bool toggle_load = false;
-	bool toggle_uptime = false;
-
 	task_id_t task_id = 0;
 
-	int i;
-	for (i = 1; i < argc; i++) {
+	for (int i = 1; i < argc; i++) {
 		int off;
 
@@ -252,20 +417,35 @@
 		}
 
+		/* All IPC connections */
+		if ((off = arg_parse_short_long(argv[i], "-ai", "--all-ipccs")) != -1) {
+			output_toggle = LIST_IPCCS;
+			toggle_all = true;
+			continue;
+		}
+
 		/* All threads */
-		if ((off = arg_parse_short_long(argv[i], "-a", "--all")) != -1) {
-			toggle_tasks = false;
-			toggle_threads = true;
+		if ((off = arg_parse_short_long(argv[i], "-at", "--all-threads")) != -1) {
+			output_toggle = LIST_THREADS;
 			toggle_all = true;
 			continue;
 		}
 
-		/* CPUs */
-		if ((off = arg_parse_short_long(argv[i], "-c", "--cpus")) != -1) {
-			toggle_tasks = false;
-			toggle_cpus = true;
-			continue;
-		}
-
-		/* Threads */
+		/* IPC connections */
+		if ((off = arg_parse_short_long(argv[i], "-i", "--ipcc=")) != -1) {
+			// TODO: Support for 64b range
+			int tmp;
+			errno_t ret = arg_parse_int(argc, argv, &i, &tmp, off);
+			if (ret != EOK) {
+				printf("%s: Malformed task id '%s'\n", NAME, argv[i]);
+				return -1;
+			}
+
+			task_id = tmp;
+
+			output_toggle = LIST_IPCCS;
+			continue;
+		}
+
+		/* Tasks */
 		if ((off = arg_parse_short_long(argv[i], "-t", "--task=")) != -1) {
 			// TODO: Support for 64b range
@@ -273,5 +453,5 @@
 			errno_t ret = arg_parse_int(argc, argv, &i, &tmp, off);
 			if (ret != EOK) {
-				printf("%s: Malformed task_id '%s'\n", NAME, argv[i]);
+				printf("%s: Malformed task id '%s'\n", NAME, argv[i]);
 				return -1;
 			}
@@ -279,6 +459,11 @@
 			task_id = tmp;
 
-			toggle_tasks = false;
-			toggle_threads = true;
+			output_toggle = LIST_THREADS;
+			continue;
+		}
+
+		/* CPUs */
+		if ((off = arg_parse_short_long(argv[i], "-c", "--cpus")) != -1) {
+			output_toggle = LIST_CPUS;
 			continue;
 		}
@@ -286,6 +471,5 @@
 		/* Load */
 		if ((off = arg_parse_short_long(argv[i], "-l", "--load")) != -1) {
-			toggle_tasks = false;
-			toggle_load = true;
+			output_toggle = PRINT_LOAD;
 			continue;
 		}
@@ -293,24 +477,38 @@
 		/* Uptime */
 		if ((off = arg_parse_short_long(argv[i], "-u", "--uptime")) != -1) {
-			toggle_tasks = false;
-			toggle_uptime = true;
-			continue;
-		}
-	}
-
-	if (toggle_tasks)
+			output_toggle = PRINT_UPTIME;
+			continue;
+		}
+
+		/* Architecture */
+		if ((off = arg_parse_short_long(argv[i], "-d", "--design")) != -1) {
+			output_toggle = PRINT_ARCH;
+			continue;
+		}
+	}
+
+	switch (output_toggle) {
+	case LIST_TASKS:
 		list_tasks();
-
-	if (toggle_threads)
+		break;
+	case LIST_THREADS:
 		list_threads(task_id, toggle_all);
-
-	if (toggle_cpus)
+		break;
+	case LIST_IPCCS:
+		list_ipccs(task_id, toggle_all);
+		break;
+	case LIST_CPUS:
 		list_cpus();
-
-	if (toggle_load)
+		break;
+	case PRINT_LOAD:
 		print_load();
-
-	if (toggle_uptime)
+		break;
+	case PRINT_UPTIME:
 		print_uptime();
+		break;
+	case PRINT_ARCH:
+		print_arch();
+		break;
+	}
 
 	return 0;
Index: uspace/app/sysinfo/sysinfo.c
===================================================================
--- uspace/app/sysinfo/sysinfo.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/sysinfo/sysinfo.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -56,5 +56,5 @@
 
 	while (offset < size) {
-		wchar_t c = str_decode(data, &offset, size);
+		char32_t c = str_decode(data, &offset, size);
 		printf("%lc", (wint_t) c);
 	}
Index: uspace/app/taskdump/taskdump.c
===================================================================
--- uspace/app/taskdump/taskdump.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/taskdump/taskdump.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -126,21 +126,22 @@
 static errno_t connect_task(task_id_t task_id)
 {
-	async_sess_t *ksess = async_connect_kbox(task_id);
+	errno_t rc;
+	async_sess_t *ksess = async_connect_kbox(task_id, &rc);
 
 	if (!ksess) {
-		if (errno == ENOTSUP) {
+		if (rc == ENOTSUP) {
 			printf("You do not have userspace debugging support "
 			    "compiled in the kernel.\n");
 			printf("Compile kernel with 'Support for userspace debuggers' "
 			    "(CONFIG_UDEBUG) enabled.\n");
-			return errno;
+			return rc;
 		}
 
 		printf("Error connecting\n");
 		printf("async_connect_kbox(%" PRIu64 ") -> %s", task_id, str_error_name(errno));
-		return errno;
-	}
-
-	errno_t rc = udebug_begin(ksess);
+		return rc;
+	}
+
+	rc = udebug_begin(ksess);
 	if (rc != EOK) {
 		printf("udebug_begin() -> %s\n", str_error_name(rc));
Index: uspace/app/tester/mm/pager1.c
===================================================================
--- uspace/app/tester/mm/pager1.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/tester/mm/pager1.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -65,5 +65,6 @@
 	TPRINTF("Connecting to VFS pager...\n");
 
-	vfs_pager_sess = service_connect_blocking(SERVICE_VFS, INTERFACE_PAGER, 0);
+	vfs_pager_sess = service_connect_blocking(SERVICE_VFS, INTERFACE_PAGER,
+	    0, NULL);
 
 	if (!vfs_pager_sess) {
Index: uspace/app/tester/print/print4.c
===================================================================
--- uspace/app/tester/print/print4.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/tester/print/print4.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -29,5 +29,5 @@
 #include <stdio.h>
 #include <stddef.h>
-#include <wchar.h>
+#include <uchar.h>
 #include "../tester.h"
 
Index: uspace/app/tester/stdio/stdio1.c
===================================================================
--- uspace/app/tester/stdio/stdio1.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/tester/stdio/stdio1.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -41,5 +41,5 @@
 {
 	FILE *file;
-	const char *file_name = "/textdemo";
+	const char *file_name = "/demo.txt";
 
 	TPRINTF("Open file \"%s\"...", file_name);
Index: uspace/app/tetris/scores.c
===================================================================
--- uspace/app/tetris/scores.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/tetris/scores.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -154,5 +154,5 @@
 		if (kev->key == KC_BACKSPACE) {
 			if (i > 0) {
-				wchar_t uc;
+				char32_t uc;
 
 				--i;
Index: uspace/app/tetris/screen.c
===================================================================
--- uspace/app/tetris/screen.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/tetris/screen.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -371,5 +371,5 @@
 	 */
 
-	wchar_t c = 0;
+	char32_t c = 0;
 
 	while (c == 0) {
@@ -393,5 +393,5 @@
 int twait(void)
 {
-	wchar_t c = 0;
+	char32_t c = 0;
 
 	while (c == 0) {
Index: uspace/app/top/screen.c
===================================================================
--- uspace/app/top/screen.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/top/screen.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -551,5 +551,5 @@
 	 */
 
-	wchar_t c = 0;
+	char32_t c = 0;
 
 	while (c == 0) {
Index: uspace/app/trace/trace.c
===================================================================
--- uspace/app/trace/trace.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/trace/trace.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -139,9 +139,8 @@
 
 	if (sess == NULL) {
-		sess = async_connect_kbox(task_id);
+		sess = async_connect_kbox(task_id, &rc);
 		if (sess == NULL) {
 			printf("Error connecting to task %" PRIu64 ".\n",
 			    task_id);
-			rc = EIO;
 			goto error;
 		}
Index: uspace/app/usbinfo/main.c
===================================================================
--- uspace/app/usbinfo/main.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/app/usbinfo/main.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -69,5 +69,5 @@
 	_OPTION("-S --status", "Get status of the device.");
 	_OPTION("-r --hid-report", "Dump HID report descriptor.");
-	_OPTION("-r --hid-report-usages", "Dump usages of HID report.");
+	_OPTION("-R --hid-report-usages", "Dump usages of HID report.");
 
 	printf("\n");
Index: uspace/dist/src/c/demos/edit/edit.c
===================================================================
--- uspace/dist/src/c/demos/edit/edit.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/dist/src/c/demos/edit/edit.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -147,5 +147,5 @@
 static void pane_caret_display(void);
 
-static void insert_char(wchar_t c);
+static void insert_char(char32_t c);
 static void delete_char_before(void);
 static void delete_char_after(void);
@@ -630,5 +630,5 @@
 	kbd_event_t *kev;
 	char *str;
-	wchar_t buffer[INFNAME_MAX_LEN + 1];
+	char32_t buffer[INFNAME_MAX_LEN + 1];
 	int max_len;
 	int nc;
@@ -670,5 +670,5 @@
 				default:
 					if (kev->c >= 32 && nc < max_len) {
-						putwchar(kev->c);
+						putuchar(kev->c);
 						console_flush(con);
 						buffer[nc++] = kev->c;
@@ -696,5 +696,5 @@
 {
 	FILE *f;
-	wchar_t c;
+	char32_t c;
 	char buf[BUF_SIZE];
 	int bcnt;
@@ -847,5 +847,5 @@
 	coord_t rbc, rec;
 	char row_buf[ROW_BUF_SIZE];
-	wchar_t c;
+	char32_t c;
 	size_t pos, size;
 	int s_column;
@@ -1052,5 +1052,5 @@
 
 /** Insert a character at caret position. */
-static void insert_char(wchar_t c)
+static void insert_char(char32_t c)
 {
 	spt_t pt;
@@ -1282,5 +1282,5 @@
 
 /* Search operations */
-static errno_t search_spt_producer(void *data, wchar_t *ret)
+static errno_t search_spt_producer(void *data, char32_t *ret)
 {
 	assert(data != NULL);
@@ -1291,5 +1291,5 @@
 }
 
-static errno_t search_spt_reverse_producer(void *data, wchar_t *ret)
+static errno_t search_spt_reverse_producer(void *data, char32_t *ret)
 {
 	assert(data != NULL);
@@ -1510,5 +1510,5 @@
 	char *str;
 	size_t off;
-	wchar_t c;
+	char32_t c;
 	errno_t rc;
 
@@ -1606,5 +1606,5 @@
 }
 
-static wchar_t get_first_wchar(const char *str)
+static char32_t get_first_wchar(const char *str)
 {
 	size_t offset = 0;
@@ -1627,5 +1627,5 @@
 		return false;
 
-	wchar_t first_char = get_first_wchar(ch);
+	char32_t first_char = get_first_wchar(ch);
 	switch (first_char) {
 	case ' ':
@@ -1653,5 +1653,5 @@
 		return false;
 
-	wchar_t first_char = get_first_wchar(ch);
+	char32_t first_char = get_first_wchar(ch);
 	switch (first_char) {
 	case ',':
Index: uspace/dist/src/c/demos/edit/search.c
===================================================================
--- uspace/dist/src/c/demos/edit/search.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/dist/src/c/demos/edit/search.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -49,5 +49,5 @@
 		return NULL;
 
-	wchar_t *p = str_to_awstr(pattern);
+	char32_t *p = str_to_awstr(pattern);
 	if (p == NULL) {
 		free(search);
@@ -62,5 +62,5 @@
 		half = search->pattern_length / 2;
 		for (pos = 0; pos < half; pos++) {
-			wchar_t tmp = p[pos];
+			char32_t tmp = p[pos];
 			p[pos] = p[search->pattern_length - pos - 1];
 			p[search->pattern_length - pos - 1] = tmp;
@@ -106,5 +106,5 @@
 	search_equals_fn eq = s->ops.equals;
 
-	wchar_t cur_char;
+	char32_t cur_char;
 	errno_t rc = EOK;
 	while ((rc = s->ops.producer(s->client_data, &cur_char)) == EOK && cur_char > 0) {
@@ -140,5 +140,5 @@
 }
 
-bool char_exact_equals(const wchar_t a, const wchar_t b)
+bool char_exact_equals(const char32_t a, const char32_t b)
 {
 	return a == b;
Index: uspace/dist/src/c/demos/edit/search.h
===================================================================
--- uspace/dist/src/c/demos/edit/search.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/dist/src/c/demos/edit/search.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -41,6 +41,6 @@
 struct search;
 typedef struct search search_t;
-typedef bool (*search_equals_fn)(const wchar_t, const wchar_t);
-typedef errno_t (*search_producer_fn)(void *, wchar_t *);
+typedef bool (*search_equals_fn)(const char32_t, const char32_t);
+typedef errno_t (*search_producer_fn)(void *, char32_t *);
 typedef errno_t (*search_mark_fn)(void *, void **);
 typedef void (*search_mark_free_fn)(void *);
@@ -58,5 +58,5 @@
 } search_ops_t;
 
-extern bool char_exact_equals(const wchar_t, const wchar_t);
+extern bool char_exact_equals(const char32_t, const char32_t);
 extern search_t *search_init(const char *, void *, search_ops_t, bool);
 extern errno_t search_next_match(search_t *, match_t *);
Index: uspace/dist/src/c/demos/edit/search_impl.h
===================================================================
--- uspace/dist/src/c/demos/edit/search_impl.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/dist/src/c/demos/edit/search_impl.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -43,5 +43,5 @@
 	/* Note: This structure is opaque for the user. */
 
-	const wchar_t *pattern;
+	const char32_t *pattern;
 	size_t pattern_length;
 	ssize_t *back_table;
Index: uspace/dist/src/c/demos/edit/sheet.c
===================================================================
--- uspace/dist/src/c/demos/edit/sheet.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/dist/src/c/demos/edit/sheet.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -193,5 +193,5 @@
 	size_t copy_sz;
 	size_t off, prev;
-	wchar_t c;
+	char32_t c;
 
 	spp = sh->data + spos->b_off;
@@ -220,5 +220,5 @@
 {
 	size_t cur_pos, prev_pos;
-	wchar_t c;
+	char32_t c;
 	coord_t cc;
 
@@ -289,5 +289,5 @@
 	size_t off;
 	coord_t cc;
-	wchar_t c;
+	char32_t c;
 	sheet_t *sh;
 
@@ -318,7 +318,7 @@
 
 /** Get a character at spt and return next spt */
-wchar_t spt_next_char(spt_t spt, spt_t *next)
-{
-	wchar_t ch = str_decode(spt.sh->data, &spt.b_off, spt.sh->text_size);
+char32_t spt_next_char(spt_t spt, spt_t *next)
+{
+	char32_t ch = str_decode(spt.sh->data, &spt.b_off, spt.sh->text_size);
 	if (next)
 		*next = spt;
@@ -326,7 +326,7 @@
 }
 
-wchar_t spt_prev_char(spt_t spt, spt_t *prev)
-{
-	wchar_t ch = str_decode_reverse(spt.sh->data, &spt.b_off, spt.sh->text_size);
+char32_t spt_prev_char(spt_t spt, spt_t *prev)
+{
+	char32_t ch = str_decode_reverse(spt.sh->data, &spt.b_off, spt.sh->text_size);
 	if (prev)
 		*prev = spt;
Index: uspace/dist/src/c/demos/edit/sheet.h
===================================================================
--- uspace/dist/src/c/demos/edit/sheet.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/dist/src/c/demos/edit/sheet.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -101,6 +101,6 @@
 extern void spt_get_coord(spt_t const *, coord_t *);
 extern bool spt_equal(spt_t const *, spt_t const *);
-extern wchar_t spt_next_char(spt_t, spt_t *);
-extern wchar_t spt_prev_char(spt_t, spt_t *);
+extern char32_t spt_next_char(spt_t, spt_t *);
+extern char32_t spt_prev_char(spt_t, spt_t *);
 
 extern void sheet_place_tag(sheet_t *, spt_t const *, tag_t *);
Index: uspace/dist/src/c/demos/tetris/scores.c
===================================================================
--- uspace/dist/src/c/demos/tetris/scores.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/dist/src/c/demos/tetris/scores.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -155,5 +155,5 @@
 		if (kev->key == KC_BACKSPACE) {
 			if (i > 0) {
-				wchar_t uc;
+				char32_t uc;
 
 				--i;
Index: uspace/dist/src/c/demos/tetris/screen.c
===================================================================
--- uspace/dist/src/c/demos/tetris/screen.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/dist/src/c/demos/tetris/screen.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -371,5 +371,5 @@
 	 */
 
-	wchar_t c = 0;
+	char32_t c = 0;
 
 	while (c == 0) {
@@ -393,5 +393,5 @@
 errno_t twait(void)
 {
-	wchar_t c = 0;
+	char32_t c = 0;
 
 	while (c == 0) {
Index: uspace/dist/src/c/demos/top/screen.c
===================================================================
--- uspace/dist/src/c/demos/top/screen.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/dist/src/c/demos/top/screen.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -553,5 +553,5 @@
 	 */
 
-	wchar_t c = 0;
+	char32_t c = 0;
 
 	while (c == 0) {
Index: uspace/drv/audio/hdaudio/codec.c
===================================================================
--- uspace/drv/audio/hdaudio/codec.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/drv/audio/hdaudio/codec.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -70,8 +70,8 @@
 #if 0
 	if (resp != NULL) {
-		ddf_msg(LVL_NOTE, "verb 0x%" PRIx32 " -> 0x%" PRIx32, verb,
+		ddf_msg(LVL_DEBUG, "verb 0x%" PRIx32 " -> 0x%" PRIx32, verb,
 		    *resp);
 	} else {
-		ddf_msg(LVL_NOTE, "verb 0x%" PRIx32, verb);
+		ddf_msg(LVL_DEBUG, "verb 0x%" PRIx32, verb);
 	}
 #endif
@@ -273,5 +273,5 @@
 
 	offset = ampcaps & 0x7f;
-	ddf_msg(LVL_NOTE, "out amp caps 0x%x (offset=0x%x)",
+	ddf_msg(LVL_DEBUG, "out amp caps 0x%x (offset=0x%x)",
 	    ampcaps, offset);
 
@@ -288,5 +288,5 @@
 		goto error;
 
-	ddf_msg(LVL_NOTE, "gain/mute: L:0x%x R:0x%x", gmleft, gmright);
+	ddf_msg(LVL_DEBUG, "gain/mute: L:0x%x R:0x%x", gmleft, gmright);
 
 	return EOK;
@@ -309,5 +309,5 @@
 
 	offset = ampcaps & 0x7f;
-	ddf_msg(LVL_NOTE, "in amp caps 0x%x (offset=0x%x)", ampcaps, offset);
+	ddf_msg(LVL_DEBUG, "in amp caps 0x%x (offset=0x%x)", ampcaps, offset);
 
 	for (i = 0; i < 15; i++) {
@@ -324,5 +324,5 @@
 			goto error;
 
-		ddf_msg(LVL_NOTE, "in:%d gain/mute: L:0x%x R:0x%x",
+		ddf_msg(LVL_DEBUG, "in:%d gain/mute: L:0x%x R:0x%x",
 		    i, gmleft, gmright);
 	}
@@ -345,5 +345,5 @@
 	int i, j;
 
-	ddf_msg(LVL_NOTE, "Connections for widget %d:", aw);
+	ddf_msg(LVL_DEBUG, "Connections for widget %d:", aw);
 
 	rc = hda_get_clist_len(codec, aw, &longform, &len);
@@ -384,5 +384,5 @@
 
 		for (j = 0; j < epresp && i < len; j++) {
-			ddf_msg(LVL_NOTE, "<- %d%s", resp & mask,
+			ddf_msg(LVL_DEBUG, "<- %d%s", resp & mask,
 			    (int)cidx == i ? " *** current *** " : "");
 			resp = resp >> shift;
@@ -406,5 +406,5 @@
 	if (rc != EOK)
 		goto error;
-	ddf_msg(LVL_NOTE, "aw %d: PIN cdfgef=0x%x",
+	ddf_msg(LVL_DEBUG, "aw %d: PIN cdfgef=0x%x",
 	    aw, cfgdef);
 
@@ -412,5 +412,5 @@
 	if (rc != EOK)
 		goto error;
-	ddf_msg(LVL_NOTE, "aw %d : PIN caps=0x%x",
+	ddf_msg(LVL_DEBUG, "aw %d : PIN caps=0x%x",
 	    aw, pcaps);
 
@@ -420,5 +420,5 @@
 			goto error;
 
-		ddf_msg(LVL_NOTE, "PIN %d had EAPD value=0x%x", aw, eapd);
+		ddf_msg(LVL_DEBUG, "PIN %d had EAPD value=0x%x", aw, eapd);
 
 		rc = hda_set_eapd_btl_enable(codec, aw, eapd | 2);
@@ -430,20 +430,20 @@
 			goto error;
 
-		ddf_msg(LVL_NOTE, "PIN %d now has EAPD value=0x%x", aw, eapd);
+		ddf_msg(LVL_DEBUG, "PIN %d now has EAPD value=0x%x", aw, eapd);
 	}
 
 	pctl = 0;
 	if ((pcaps & BIT_V(uint32_t, pwc_output)) != 0) {
-		ddf_msg(LVL_NOTE, "PIN %d will enable output", aw);
+		ddf_msg(LVL_DEBUG, "PIN %d will enable output", aw);
 		pctl = pctl | BIT_V(uint8_t, pctl_out_enable);
 	}
 
 	if ((pcaps & BIT_V(uint32_t, pwc_input)) != 0) {
-		ddf_msg(LVL_NOTE, "PIN %d will enable input", aw);
+		ddf_msg(LVL_DEBUG, "PIN %d will enable input", aw);
 		pctl = pctl | BIT_V(uint8_t, pctl_in_enable);
 	}
 
 	if ((pcaps & BIT_V(uint32_t, pwc_hpd)) != 0) {
-		ddf_msg(LVL_NOTE, "PIN %d will enable headphone drive", aw);
+		ddf_msg(LVL_DEBUG, "PIN %d will enable headphone drive", aw);
 		pctl = pctl | BIT_V(uint8_t, pctl_hpd_enable);
 	}
@@ -451,9 +451,9 @@
 #if 0
 	if ((pcaps & BIT_V(uint32_t, pwc_input)) != 0) {
-		ddf_msg(LVL_NOTE, "PIN %d will enable input");
+		ddf_msg(LVL_DEBUG, "PIN %d will enable input");
 		pctl = pctl | BIT_V(uint8_t, pctl_input_enable);
 	}
 #endif
-	ddf_msg(LVL_NOTE, "Setting PIN %d ctl to 0x%x", aw, pctl);
+	ddf_msg(LVL_DEBUG, "Setting PIN %d ctl to 0x%x", aw, pctl);
 	rc = hda_set_pin_ctl(codec, aw, pctl);
 	if (rc != EOK)
@@ -465,5 +465,5 @@
 		goto error;
 
-	ddf_msg(LVL_NOTE, "PIN %d ctl reads as 0x%x", aw, pctl);
+	ddf_msg(LVL_DEBUG, "PIN %d ctl reads as 0x%x", aw, pctl);
 
 	return EOK;
@@ -478,10 +478,10 @@
 	uint32_t pwrstate;
 
-	ddf_msg(LVL_NOTE, "aw %d is power control-capable", aw);
+	ddf_msg(LVL_DEBUG, "aw %d is power control-capable", aw);
 
 	rc = hda_get_power_state(codec, aw, &pwrstate);
 	if (rc != EOK)
 		goto error;
-	ddf_msg(LVL_NOTE, "aw %d: power state = 0x%x", aw, pwrstate);
+	ddf_msg(LVL_DEBUG, "aw %d: power state = 0x%x", aw, pwrstate);
 
 	return EOK;
@@ -517,9 +517,9 @@
 		goto error;
 
-	ddf_msg(LVL_NOTE, "hda_get_subnc -> %s", str_error_name(rc));
-	ddf_msg(LVL_NOTE, "sfg=%d nfg=%d", sfg, nfg);
+	ddf_msg(LVL_DEBUG, "hda_get_subnc -> %s", str_error_name(rc));
+	ddf_msg(LVL_DEBUG, "sfg=%d nfg=%d", sfg, nfg);
 
 	for (fg = sfg; fg < sfg + nfg; fg++) {
-		ddf_msg(LVL_NOTE, "Enumerate FG %d", fg);
+		ddf_msg(LVL_DEBUG, "Enumerate FG %d", fg);
 
 		rc = hda_get_fgrp_type(codec, fg, &unsol, &grptype);
@@ -527,6 +527,6 @@
 			goto error;
 
-		ddf_msg(LVL_NOTE, "hda_get_fgrp_type -> %s", str_error_name(rc));
-		ddf_msg(LVL_NOTE, "unsol: %d, grptype: %d", unsol, grptype);
+		ddf_msg(LVL_DEBUG, "hda_get_fgrp_type -> %s", str_error_name(rc));
+		ddf_msg(LVL_DEBUG, "unsol: %d, grptype: %d", unsol, grptype);
 
 		rc = hda_get_gpio_cnt(codec, fg, &gpio);
@@ -534,5 +534,5 @@
 			goto error;
 
-		ddf_msg(LVL_NOTE, "GPIO: wake=%d unsol=%d gpis=%d gpos=%d gpios=%d",
+		ddf_msg(LVL_DEBUG, "GPIO: wake=%d unsol=%d gpis=%d gpos=%d gpios=%d",
 		    (gpio & BIT_V(uint32_t, 31)) != 0,
 		    (gpio & BIT_V(uint32_t, 30)) != 0,
@@ -549,6 +549,6 @@
 			goto error;
 
-		ddf_msg(LVL_NOTE, "hda_get_subnc -> %s", str_error_name(rc));
-		ddf_msg(LVL_NOTE, "saw=%d baw=%d", saw, naw);
+		ddf_msg(LVL_DEBUG, "hda_get_subnc -> %s", str_error_name(rc));
+		ddf_msg(LVL_DEBUG, "saw=%d baw=%d", saw, naw);
 
 		for (aw = saw; aw < saw + naw; aw++) {
@@ -556,5 +556,5 @@
 			if (rc != EOK)
 				goto error;
-			ddf_msg(LVL_NOTE, "aw %d: type=0x%x caps=0x%x",
+			ddf_msg(LVL_DEBUG, "aw %d: type=0x%x caps=0x%x",
 			    aw, awtype, awcaps);
 
@@ -594,13 +594,13 @@
 					goto error;
 
-				ddf_msg(LVL_NOTE, "Output widget %d: rates=0x%x formats=0x%x",
+				ddf_msg(LVL_DEBUG, "Output widget %d: rates=0x%x formats=0x%x",
 				    aw, rates, formats);
 			} else if (awtype == awt_audio_input) {
 				if (codec->in_aw < 0) {
-					ddf_msg(LVL_NOTE, "Selected input "
+					ddf_msg(LVL_DEBUG, "Selected input "
 					    "widget %d\n", aw);
 					codec->in_aw = aw;
 				} else {
-					ddf_msg(LVL_NOTE, "Ignoring input "
+					ddf_msg(LVL_DEBUG, "Ignoring input "
 					    "widget %d\n", aw);
 				}
@@ -614,5 +614,5 @@
 					goto error;
 
-				ddf_msg(LVL_NOTE, "Input widget %d: rates=0x%x formats=0x%x",
+				ddf_msg(LVL_DEBUG, "Input widget %d: rates=0x%x formats=0x%x",
 				    aw, rates, formats);
 			}
@@ -628,5 +628,5 @@
 	hda_ctl_dump_info(hda->ctl);
 
-	ddf_msg(LVL_NOTE, "Codec OK");
+	ddf_msg(LVL_DEBUG, "Codec OK");
 	return codec;
 error:
@@ -637,5 +637,5 @@
 void hda_codec_fini(hda_codec_t *codec)
 {
-	ddf_msg(LVL_NOTE, "hda_codec_fini()");
+	ddf_msg(LVL_DEBUG, "hda_codec_fini()");
 	free(codec);
 }
@@ -652,10 +652,10 @@
 		/* Configure converter */
 
-		ddf_msg(LVL_NOTE, "Configure output converter format");
+		ddf_msg(LVL_DEBUG, "Configure output converter format");
 		rc = hda_set_converter_fmt(codec, out_aw, stream->fmt);
 		if (rc != EOK)
 			goto error;
 
-		ddf_msg(LVL_NOTE, "Configure output converter stream, channel");
+		ddf_msg(LVL_DEBUG, "Configure output converter stream, channel");
 		rc = hda_set_converter_ctl(codec, out_aw, stream->sid, 0);
 		if (rc != EOK)
@@ -674,10 +674,10 @@
 	/* Configure converter */
 
-	ddf_msg(LVL_NOTE, "Configure input converter format");
+	ddf_msg(LVL_DEBUG, "Configure input converter format");
 	rc = hda_set_converter_fmt(codec, codec->in_aw, stream->fmt);
 	if (rc != EOK)
 		goto error;
 
-	ddf_msg(LVL_NOTE, "Configure input converter stream, channel");
+	ddf_msg(LVL_DEBUG, "Configure input converter stream, channel");
 	rc = hda_set_converter_ctl(codec, codec->in_aw, stream->sid, 0);
 	if (rc != EOK)
Index: uspace/drv/audio/hdaudio/hdactl.c
===================================================================
--- uspace/drv/audio/hdaudio/hdactl.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/drv/audio/hdaudio/hdactl.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -154,10 +154,10 @@
 	errno_t rc;
 
-	ddf_msg(LVL_NOTE, "hda_corb_init()");
+	ddf_msg(LVL_DEBUG, "hda_corb_init()");
 
 	/* Stop CORB if not stopped */
 	ctl = hda_reg8_read(&hda->regs->corbctl);
 	if ((ctl & BIT_V(uint8_t, corbctl_run)) != 0) {
-		ddf_msg(LVL_NOTE, "CORB is enabled, disabling first.");
+		ddf_msg(LVL_DEBUG, "CORB is enabled, disabling first.");
 		hda_reg8_write(&hda->regs->corbctl, ctl & ~BIT_V(uint8_t,
 		    corbctl_run));
@@ -176,5 +176,5 @@
 	corbsz = corbsz | selsz;
 
-	ddf_msg(LVL_NOTE, "Setting CORB Size register to 0x%x", corbsz);
+	ddf_msg(LVL_DEBUG, "Setting CORB Size register to 0x%x", corbsz);
 	hda_reg8_write(&hda->regs->corbsize, corbsz);
 	hda->ctl->corb_entries = hda_rb_entries(selsz);
@@ -190,9 +190,9 @@
 	if (rc != EOK) {
 		hda->ctl->corb_virt = NULL;
-		ddf_msg(LVL_NOTE, "Failed allocating DMA memory for CORB");
-		goto error;
-	}
-
-	ddf_msg(LVL_NOTE, "Set CORB base registers");
+		ddf_msg(LVL_ERROR, "Failed allocating DMA memory for CORB");
+		goto error;
+	}
+
+	ddf_msg(LVL_DEBUG, "Set CORB base registers");
 
 	/* Update CORB base registers */
@@ -200,5 +200,5 @@
 	hda_reg32_write(&hda->regs->corbubase, UPPER32(hda->ctl->corb_phys));
 
-	ddf_msg(LVL_NOTE, "Reset CORB Read/Write pointers");
+	ddf_msg(LVL_DEBUG, "Reset CORB Read/Write pointers");
 
 	/* Reset CORB Read Pointer */
@@ -206,5 +206,5 @@
 	    BIT_V(uint16_t, corbrp_rst));
 	if (rc != EOK) {
-		ddf_msg(LVL_NOTE, "Failed resetting CORBRP");
+		ddf_msg(LVL_ERROR, "Failed resetting CORBRP");
 		goto error;
 	}
@@ -215,9 +215,9 @@
 	/* Start CORB */
 	ctl = hda_reg8_read(&hda->regs->corbctl);
-	ddf_msg(LVL_NOTE, "CORBctl (0x%x) = 0x%x",
+	ddf_msg(LVL_DEBUG, "CORBctl (0x%x) = 0x%x",
 	    (unsigned)((void *)&hda->regs->corbctl - (void *)hda->regs), ctl | BIT_V(uint8_t, corbctl_run));
 	hda_reg8_write(&hda->regs->corbctl, ctl | BIT_V(uint8_t, corbctl_run));
 
-	ddf_msg(LVL_NOTE, "CORB initialized");
+	ddf_msg(LVL_DEBUG, "CORB initialized");
 	return EOK;
 error:
@@ -251,10 +251,10 @@
 	errno_t rc;
 
-	ddf_msg(LVL_NOTE, "hda_rirb_init()");
+	ddf_msg(LVL_DEBUG, "hda_rirb_init()");
 
 	/* Stop RIRB if not stopped */
 	ctl = hda_reg8_read(&hda->regs->rirbctl);
 	if ((ctl & BIT_V(uint8_t, rirbctl_run)) != 0) {
-		ddf_msg(LVL_NOTE, "RIRB is enabled, disabling first.");
+		ddf_msg(LVL_DEBUG, "RIRB is enabled, disabling first.");
 		hda_reg8_write(&hda->regs->corbctl, ctl & ~BIT_V(uint8_t,
 		    rirbctl_run));
@@ -273,5 +273,5 @@
 	rirbsz = rirbsz | (selsz << rirbsize_size_l);
 
-	ddf_msg(LVL_NOTE, "Setting RIRB Size register to 0x%x", rirbsz);
+	ddf_msg(LVL_DEBUG, "Setting RIRB Size register to 0x%x", rirbsz);
 	hda_reg8_write(&hda->regs->rirbsize, rirbsz);
 	hda->ctl->rirb_entries = hda_rb_entries(selsz);
@@ -287,9 +287,9 @@
 	if (rc != EOK) {
 		hda->ctl->rirb_virt = NULL;
-		ddf_msg(LVL_NOTE, "Failed allocating DMA memory for RIRB");
-		goto error;
-	}
-
-	ddf_msg(LVL_NOTE, "Set RIRB base registers");
+		ddf_msg(LVL_ERROR, "Failed allocating DMA memory for RIRB");
+		goto error;
+	}
+
+	ddf_msg(LVL_DEBUG, "Set RIRB base registers");
 
 	/* Update RIRB base registers */
@@ -297,5 +297,5 @@
 	hda_reg32_write(&hda->regs->rirbubase, UPPER32(hda->ctl->rirb_phys));
 
-	ddf_msg(LVL_NOTE, "Reset RIRB Write pointer");
+	ddf_msg(LVL_DEBUG, "Reset RIRB Write pointer");
 
 	/* Reset RIRB Write Pointer */
@@ -309,10 +309,10 @@
 	/* Start RIRB and enable RIRB interrupt */
 	ctl = hda_reg8_read(&hda->regs->rirbctl);
-	ddf_msg(LVL_NOTE, "RIRBctl (0x%x) = 0x%x",
+	ddf_msg(LVL_DEBUG, "RIRBctl (0x%x) = 0x%x",
 	    (unsigned)((void *)&hda->regs->rirbctl - (void *)hda->regs), ctl | BIT_V(uint8_t, rirbctl_run));
 	hda_reg8_write(&hda->regs->rirbctl, ctl | BIT_V(uint8_t, rirbctl_run) |
 	    BIT_V(uint8_t, rirbctl_int));
 
-	ddf_msg(LVL_NOTE, "RIRB initialized");
+	ddf_msg(LVL_DEBUG, "RIRB initialized");
 	return EOK;
 error:
@@ -479,5 +479,5 @@
 
 			if (hda->ctl->solrb_wp == hda->ctl->solrb_rp) {
-				ddf_msg(LVL_NOTE, "hda_solrb_read() - last ditch effort process RIRB");
+				ddf_msg(LVL_DEBUG, "hda_solrb_read() - last ditch effort process RIRB");
 				fibril_mutex_unlock(&hda->ctl->solrb_lock);
 				hda_ctl_process_rirb(hda->ctl);
@@ -486,5 +486,5 @@
 
 			if (hda->ctl->solrb_wp == hda->ctl->solrb_rp) {
-				ddf_msg(LVL_NOTE, "hda_solrb_read() time out");
+				ddf_msg(LVL_DEBUG, "hda_solrb_read() time out");
 				fibril_mutex_unlock(&hda->ctl->solrb_lock);
 				return ETIMEOUT;
@@ -525,5 +525,5 @@
 	}
 
-	ddf_msg(LVL_NOTE, "reg 0x%zx STATESTS = 0x%x",
+	ddf_msg(LVL_DEBUG, "reg 0x%zx STATESTS = 0x%x",
 	    (void *)&hda->regs->statests - (void *)hda->regs,
 	    hda_reg16_read(&hda->regs->statests));
@@ -534,5 +534,5 @@
 	hda_reg16_write(&hda->regs->statests, 0x7f);
 
-	ddf_msg(LVL_NOTE, "after clearing reg 0x%zx STATESTS = 0x%x",
+	ddf_msg(LVL_DEBUG, "after clearing reg 0x%zx STATESTS = 0x%x",
 	    (void *)&hda->regs->statests - (void *)hda->regs,
 	    hda_reg16_read(&hda->regs->statests));
@@ -540,9 +540,9 @@
 	gctl = hda_reg32_read(&hda->regs->gctl);
 	if ((gctl & BIT_V(uint32_t, gctl_crst)) != 0) {
-		ddf_msg(LVL_NOTE, "Controller not in reset. Resetting.");
+		ddf_msg(LVL_DEBUG, "Controller not in reset. Resetting.");
 		hda_reg32_write(&hda->regs->gctl, gctl & ~BIT_V(uint32_t, gctl_crst));
 	}
 
-	ddf_msg(LVL_NOTE, "Taking controller out of reset.");
+	ddf_msg(LVL_DEBUG, "Taking controller out of reset.");
 	hda_reg32_write(&hda->regs->gctl, gctl | BIT_V(uint32_t, gctl_crst));
 
@@ -552,9 +552,9 @@
 		gctl = hda_reg32_read(&hda->regs->gctl);
 		if ((gctl & BIT_V(uint32_t, gctl_crst)) != 0) {
-			ddf_msg(LVL_NOTE, "gctl=0x%x", gctl);
+			ddf_msg(LVL_DEBUG, "gctl=0x%x", gctl);
 			break;
 		}
 
-		ddf_msg(LVL_NOTE, "Waiting for controller to initialize.");
+		ddf_msg(LVL_DEBUG, "Waiting for controller to initialize.");
 		fibril_usleep(100 * 1000);
 		--cnt;
@@ -566,7 +566,7 @@
 	}
 
-	ddf_msg(LVL_NOTE, "Controller is out of reset.");
-
-	ddf_msg(LVL_NOTE, "Read GCAP");
+	ddf_msg(LVL_DEBUG, "Controller is out of reset.");
+
+	ddf_msg(LVL_DEBUG, "Read GCAP");
 	uint16_t gcap = hda_reg16_read(&hda->regs->gcap);
 	ctl->ok64bit = (gcap & BIT_V(uint16_t, gcap_64ok)) != 0;
@@ -574,16 +574,16 @@
 	ctl->iss = BIT_RANGE_EXTRACT(uint16_t, gcap_iss_h, gcap_iss_l, gcap);
 	ctl->bss = BIT_RANGE_EXTRACT(uint16_t, gcap_bss_h, gcap_bss_l, gcap);
-	ddf_msg(LVL_NOTE, "GCAP: 0x%x (64OK=%d)", gcap, ctl->ok64bit);
-	ddf_msg(LVL_NOTE, "iss: %d, oss: %d, bss: %d\n",
+	ddf_msg(LVL_DEBUG, "GCAP: 0x%x (64OK=%d)", gcap, ctl->ok64bit);
+	ddf_msg(LVL_DEBUG, "iss: %d, oss: %d, bss: %d\n",
 	    ctl->iss, ctl->oss, ctl->bss);
 	/* Give codecs enough time to enumerate themselves */
 	fibril_usleep(codec_enum_wait_us);
 
-	ddf_msg(LVL_NOTE, "STATESTS = 0x%x",
+	ddf_msg(LVL_DEBUG, "STATESTS = 0x%x",
 	    hda_reg16_read(&hda->regs->statests));
 
 	/* Enable interrupts */
 	intctl = hda_reg32_read(&hda->regs->intctl);
-	ddf_msg(LVL_NOTE, "intctl (0x%x) := 0x%x",
+	ddf_msg(LVL_DEBUG, "intctl (0x%x) := 0x%x",
 	    (unsigned)((void *)&hda->regs->intctl - (void *)hda->regs),
 	    intctl | BIT_V(uint32_t, intctl_gie) | BIT_V(uint32_t, intctl_cie));
@@ -600,13 +600,13 @@
 		goto error;
 
-	ddf_msg(LVL_NOTE, "call hda_codec_init()");
+	ddf_msg(LVL_DEBUG, "call hda_codec_init()");
 	hda->ctl->codec = hda_codec_init(hda, 0);
 	if (hda->ctl->codec == NULL) {
-		ddf_msg(LVL_NOTE, "hda_codec_init() failed");
-		goto error;
-	}
-
-	ddf_msg(LVL_NOTE, "intsts=0x%x", hda_reg32_read(&hda->regs->intsts));
-	ddf_msg(LVL_NOTE, "sdesc[%d].sts=0x%x",
+		ddf_msg(LVL_DEBUG, "hda_codec_init() failed");
+		goto error;
+	}
+
+	ddf_msg(LVL_DEBUG, "intsts=0x%x", hda_reg32_read(&hda->regs->intsts));
+	ddf_msg(LVL_DEBUG, "sdesc[%d].sts=0x%x",
 	    hda->ctl->iss, hda_reg8_read(&hda->regs->sdesc[hda->ctl->iss].sts));
 
@@ -622,5 +622,5 @@
 void hda_ctl_fini(hda_ctl_t *ctl)
 {
-	ddf_msg(LVL_NOTE, "hda_ctl_fini()");
+	ddf_msg(LVL_DEBUG, "hda_ctl_fini()");
 	hda_rirb_fini(ctl->hda);
 	hda_corb_fini(ctl->hda);
@@ -677,14 +677,14 @@
 void hda_ctl_dump_info(hda_ctl_t *ctl)
 {
-	ddf_msg(LVL_NOTE, "corbwp=%d, corbrp=%d",
+	ddf_msg(LVL_DEBUG, "corbwp=%d, corbrp=%d",
 	    hda_reg16_read(&ctl->hda->regs->corbwp),
 	    hda_reg16_read(&ctl->hda->regs->corbrp));
-	ddf_msg(LVL_NOTE, "corbctl=0x%x, corbsts=0x%x",
+	ddf_msg(LVL_DEBUG, "corbctl=0x%x, corbsts=0x%x",
 	    hda_reg8_read(&ctl->hda->regs->corbctl),
 	    hda_reg8_read(&ctl->hda->regs->corbsts));
-	ddf_msg(LVL_NOTE, "rirbwp=0x%x, soft-rirbrp=0x%zx",
+	ddf_msg(LVL_DEBUG, "rirbwp=0x%x, soft-rirbrp=0x%zx",
 	    hda_reg16_read(&ctl->hda->regs->rirbwp),
 	    ctl->rirb_rp);
-	ddf_msg(LVL_NOTE, "solrb_wp=0x%zx, solrb_rp=0x%zx",
+	ddf_msg(LVL_DEBUG, "solrb_wp=0x%zx, solrb_rp=0x%zx",
 	    ctl->solrb_wp, ctl->solrb_wp);
 }
Index: uspace/drv/audio/hdaudio/hdaudio.c
===================================================================
--- uspace/drv/audio/hdaudio/hdaudio.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/drv/audio/hdaudio/hdaudio.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -163,5 +163,5 @@
 	errno_t rc;
 
-	ddf_msg(LVL_NOTE, "hda_dev_add()");
+	ddf_msg(LVL_DEBUG, "hda_dev_add()");
 	hw_res_list_parsed_init(&res);
 
@@ -175,5 +175,5 @@
 	fibril_mutex_initialize(&hda->lock);
 
-	ddf_msg(LVL_NOTE, "create parent sess");
+	ddf_msg(LVL_DEBUG, "create parent sess");
 	hda->parent_sess = ddf_dev_parent_sess_get(dev);
 	if (hda->parent_sess == NULL) {
@@ -183,5 +183,5 @@
 	}
 
-	ddf_msg(LVL_NOTE, "get HW res list");
+	ddf_msg(LVL_DEBUG, "get HW res list");
 	rc = hw_res_get_list_parsed(hda->parent_sess, &res, 0);
 	if (rc != EOK) {
@@ -199,5 +199,5 @@
 	hda->rwsize = RNGSZ(res.mem_ranges.ranges[0]);
 
-	ddf_msg(LVL_NOTE, "hda reg base: %" PRIx64,
+	ddf_msg(LVL_DEBUG, "hda reg base: %" PRIx64,
 	    RNGABS(res.mem_ranges.ranges[0]));
 
@@ -208,5 +208,5 @@
 	}
 
-	ddf_msg(LVL_NOTE, "enable PIO");
+	ddf_msg(LVL_DEBUG, "enable PIO");
 	rc = pio_enable((void *)(uintptr_t)hda->rwbase, hda->rwsize, &regs);
 	if (rc != EOK) {
@@ -217,5 +217,5 @@
 	hda->regs = (hda_regs_t *)regs;
 
-	ddf_msg(LVL_NOTE, "IRQs: %zu", res.irqs.count);
+	ddf_msg(LVL_DEBUG, "IRQs: %zu", res.irqs.count);
 	if (res.irqs.count != 1) {
 		ddf_msg(LVL_ERROR, "Unexpected IRQ count %zu (!= 1)",
@@ -223,5 +223,5 @@
 		goto error;
 	}
-	ddf_msg(LVL_NOTE, "interrupt no: %d", res.irqs.irqs[0]);
+	ddf_msg(LVL_DEBUG, "interrupt no: %d", res.irqs.irqs[0]);
 
 	ncmds_base = sizeof(hdaudio_irq_commands) / sizeof(irq_cmd_t);
@@ -256,5 +256,5 @@
 	}
 
-	ddf_msg(LVL_NOTE, "range0.base=%zu", hdaudio_irq_pio_ranges[0].base);
+	ddf_msg(LVL_DEBUG, "range0.base=%zu", hdaudio_irq_pio_ranges[0].base);
 
 	rc = hw_res_enable_interrupt(hda->parent_sess, res.irqs.irqs[0]);
@@ -281,5 +281,5 @@
 	}
 
-	ddf_msg(LVL_NOTE, "create function");
+	ddf_msg(LVL_DEBUG, "create function");
 	fun_pcm = ddf_fun_create(dev, fun_exposed, "pcm");
 	if (fun_pcm == NULL) {
@@ -323,5 +323,5 @@
 	hw_res_list_parsed_clean(&res);
 
-	ddf_msg(LVL_NOTE, "Failing hda_dev_add() -> %s", str_error_name(rc));
+	ddf_msg(LVL_DEBUG, "Failing hda_dev_add() -> %s", str_error_name(rc));
 	return rc;
 }
Index: uspace/drv/audio/hdaudio/pcm_iface.c
===================================================================
--- uspace/drv/audio/hdaudio/pcm_iface.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/drv/audio/hdaudio/pcm_iface.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -92,5 +92,5 @@
 static errno_t hda_get_info_str(ddf_fun_t *fun, const char **name)
 {
-	ddf_msg(LVL_NOTE, "hda_get_info_str()");
+	ddf_msg(LVL_DEBUG, "hda_get_info_str()");
 	if (name)
 		*name = "High Definition Audio";
@@ -102,5 +102,5 @@
 	hda_t *hda = fun_to_hda(fun);
 
-	ddf_msg(LVL_NOTE, "hda_query_cap(%d)", cap);
+	ddf_msg(LVL_DEBUG, "hda_query_cap(%d)", cap);
 	switch (cap) {
 	case AUDIO_CAP_PLAYBACK:
@@ -129,5 +129,5 @@
 	errno_t rc = EOK;
 
-	ddf_msg(LVL_NOTE, "hda_test_format(%u, %u, %d)\n",
+	ddf_msg(LVL_DEBUG, "hda_test_format(%u, %u, %d)\n",
 	    *channels, *rate, *format);
 
@@ -157,5 +157,5 @@
 	hda_lock(hda);
 
-	ddf_msg(LVL_NOTE, "hda_get_buffer(): hda=%p", hda);
+	ddf_msg(LVL_DEBUG, "hda_get_buffer(): hda=%p", hda);
 	if (hda->pcm_buffers != NULL) {
 		hda_unlock(hda);
@@ -163,5 +163,5 @@
 	}
 
-	ddf_msg(LVL_NOTE, "hda_get_buffer() - allocate stream buffers");
+	ddf_msg(LVL_DEBUG, "hda_get_buffer() - allocate stream buffers");
 	rc = hda_stream_buffers_alloc(hda, &hda->pcm_buffers);
 	if (rc != EOK) {
@@ -171,10 +171,10 @@
 	}
 
-	ddf_msg(LVL_NOTE, "hda_get_buffer() - fill info");
+	ddf_msg(LVL_DEBUG, "hda_get_buffer() - fill info");
 	/* XXX This is only one buffer */
 	*buffer = hda->pcm_buffers->buf[0];
 	*size = hda->pcm_buffers->bufsize * hda->pcm_buffers->nbuffers;
 
-	ddf_msg(LVL_NOTE, "hda_get_buffer() returing EOK, buffer=%p, size=%zu",
+	ddf_msg(LVL_DEBUG, "hda_get_buffer() returing EOK, buffer=%p, size=%zu",
 	    *buffer, *size);
 
@@ -185,5 +185,5 @@
 static errno_t hda_get_buffer_position(ddf_fun_t *fun, size_t *pos)
 {
-	ddf_msg(LVL_NOTE, "hda_get_buffer_position()");
+	ddf_msg(LVL_DEBUG, "hda_get_buffer_position()");
 	return ENOTSUP;
 }
@@ -193,5 +193,5 @@
 	hda_t *hda = fun_to_hda(fun);
 
-	ddf_msg(LVL_NOTE, "hda_set_event_session()");
+	ddf_msg(LVL_DEBUG, "hda_set_event_session()");
 	hda_lock(hda);
 	hda->ev_sess = sess;
@@ -206,5 +206,5 @@
 	async_sess_t *sess;
 
-	ddf_msg(LVL_NOTE, "hda_get_event_session()");
+	ddf_msg(LVL_DEBUG, "hda_get_event_session()");
 
 	hda_lock(hda);
@@ -221,5 +221,5 @@
 	hda_lock(hda);
 
-	ddf_msg(LVL_NOTE, "hda_release_buffer()");
+	ddf_msg(LVL_DEBUG, "hda_release_buffer()");
 	if (hda->pcm_buffers == NULL) {
 		hda_unlock(hda);
@@ -240,5 +240,5 @@
 	errno_t rc;
 
-	ddf_msg(LVL_NOTE, "hda_start_playback()");
+	ddf_msg(LVL_DEBUG, "hda_start_playback()");
 	hda_lock(hda);
 
@@ -279,5 +279,5 @@
 	hda_t *hda = fun_to_hda(fun);
 
-	ddf_msg(LVL_NOTE, "hda_stop_playback()");
+	ddf_msg(LVL_DEBUG, "hda_stop_playback()");
 	hda_lock(hda);
 	hda_stream_stop(hda->pcm_stream);
@@ -299,5 +299,5 @@
 	errno_t rc;
 
-	ddf_msg(LVL_NOTE, "hda_start_capture()");
+	ddf_msg(LVL_DEBUG, "hda_start_capture()");
 	hda_lock(hda);
 
@@ -312,5 +312,5 @@
 	fmt = (fmt_base_44khz << fmt_base) | (fmt_bits_16 << fmt_bits_l) | 1;
 
-	ddf_msg(LVL_NOTE, "hda_start_capture() - create input stream");
+	ddf_msg(LVL_DEBUG, "hda_start_capture() - create input stream");
 	hda->pcm_stream = hda_stream_create(hda, sdir_input, hda->pcm_buffers,
 	    fmt);
@@ -338,5 +338,5 @@
 	hda_t *hda = fun_to_hda(fun);
 
-	ddf_msg(LVL_NOTE, "hda_stop_capture()");
+	ddf_msg(LVL_DEBUG, "hda_stop_capture()");
 	hda_lock(hda);
 	hda_stream_stop(hda->pcm_stream);
Index: uspace/drv/audio/hdaudio/stream.c
===================================================================
--- uspace/drv/audio/hdaudio/stream.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/drv/audio/hdaudio/stream.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -101,5 +101,5 @@
 			goto error;
 
-		ddf_msg(LVL_NOTE, "Stream buf phys=0x%llx virt=%p",
+		ddf_msg(LVL_DEBUG, "Stream buf phys=0x%llx virt=%p",
 		    (unsigned long long)buffer_phys, buffer);
 
@@ -123,5 +123,5 @@
 	    0, &buffer_phys, &buffer);
 	if (rc != EOK) {
-		ddf_msg(LVL_NOTE, "dmamem_map_anon -> %s", str_error_name(rc));
+		ddf_msg(LVL_DEBUG, "dmamem_map_anon -> %s", str_error_name(rc));
 		goto error;
 	}
@@ -131,5 +131,5 @@
 		bufs->buf_phys[i] = buffer_phys + i * bufs->bufsize;
 
-		ddf_msg(LVL_NOTE, "Stream buf phys=0x%llx virt=%p",
+		ddf_msg(LVL_DEBUG, "Stream buf phys=0x%llx virt=%p",
 		    (long long unsigned)(uintptr_t)bufs->buf[i],
 		    (void *)bufs->buf_phys[i]);
@@ -246,7 +246,7 @@
 	stream->buffers = bufs;
 
-	ddf_msg(LVL_NOTE, "snum=%d sdidx=%d", stream->sid, stream->sdid);
-
-	ddf_msg(LVL_NOTE, "Configure stream descriptor");
+	ddf_msg(LVL_DEBUG, "snum=%d sdidx=%d", stream->sid, stream->sdid);
+
+	ddf_msg(LVL_DEBUG, "Configure stream descriptor");
 	hda_stream_desc_configure(stream);
 	return stream;
@@ -255,5 +255,5 @@
 void hda_stream_destroy(hda_stream_t *stream)
 {
-	ddf_msg(LVL_NOTE, "hda_stream_destroy()");
+	ddf_msg(LVL_DEBUG, "hda_stream_destroy()");
 	hda_stream_reset_noinit(stream);
 	free(stream);
@@ -262,5 +262,5 @@
 void hda_stream_start(hda_stream_t *stream)
 {
-	ddf_msg(LVL_NOTE, "hda_stream_start()");
+	ddf_msg(LVL_DEBUG, "hda_stream_start()");
 	hda_stream_set_run(stream, true);
 }
@@ -268,5 +268,5 @@
 void hda_stream_stop(hda_stream_t *stream)
 {
-	ddf_msg(LVL_NOTE, "hda_stream_stop()");
+	ddf_msg(LVL_DEBUG, "hda_stream_stop()");
 	hda_stream_set_run(stream, false);
 }
@@ -274,5 +274,5 @@
 void hda_stream_reset(hda_stream_t *stream)
 {
-	ddf_msg(LVL_NOTE, "hda_stream_reset()");
+	ddf_msg(LVL_DEBUG, "hda_stream_reset()");
 	hda_stream_reset_noinit(stream);
 	hda_stream_desc_configure(stream);
Index: uspace/drv/block/ata_bd/ata_bd.c
===================================================================
--- uspace/drv/block/ata_bd/ata_bd.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/drv/block/ata_bd/ata_bd.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -163,5 +163,5 @@
 
 	for (i = 0; i < MAX_DISKS; i++) {
-		ddf_msg(LVL_NOTE, "Identify drive %d...", i);
+		ddf_msg(LVL_DEBUG, "Identify drive %d...", i);
 
 		rc = disk_init(ctrl, &ctrl->disk[i], i);
@@ -170,5 +170,5 @@
 			disk_print_summary(&ctrl->disk[i]);
 		} else {
-			ddf_msg(LVL_NOTE, "Not found.");
+			ddf_msg(LVL_DEBUG, "Not found.");
 		}
 	}
@@ -192,5 +192,5 @@
 	if (n_disks == 0) {
 		ddf_msg(LVL_WARN, "No disks detected.");
-		rc = EIO;
+		rc = ENOENT;
 		goto error;
 	}
@@ -368,5 +368,5 @@
 	if (rc == EOK) {
 		/* Success. It's a register (non-packet) device. */
-		ddf_msg(LVL_NOTE, "ATA register-only device found.");
+		ddf_msg(LVL_DEBUG, "ATA register-only device found.");
 		d->dev_type = ata_reg_dev;
 	} else if (rc == EIO) {
Index: uspace/drv/block/ata_bd/main.c
===================================================================
--- uspace/drv/block/ata_bd/main.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/drv/block/ata_bd/main.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -134,4 +134,7 @@
 
 	rc = ata_ctrl_init(ctrl, &res);
+	if (rc == ENOENT)
+		goto error;
+
 	if (rc != EOK) {
 		ddf_msg(LVL_ERROR, "Failed initializing ATA controller.");
Index: uspace/drv/hid/usbhid/mouse/mousedev.c
===================================================================
--- uspace/drv/hid/usbhid/mouse/mousedev.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/drv/hid/usbhid/mouse/mousedev.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -422,10 +422,6 @@
 
 	/* Hangup session to the console */
-	if (mouse_dev->mouse_sess != NULL) {
-		const errno_t ret = async_hangup(mouse_dev->mouse_sess);
-		if (ret != EOK)
-			usb_log_warning("Failed to hang up mouse session: "
-			    "%p, %s.\n", mouse_dev->mouse_sess, str_error(ret));
-	}
+	if (mouse_dev->mouse_sess != NULL)
+		async_hangup(mouse_dev->mouse_sess);
 
 	free(mouse_dev->buttons);
Index: uspace/drv/nic/e1k/e1k.c
===================================================================
--- uspace/drv/nic/e1k/e1k.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/drv/nic/e1k/e1k.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -256,7 +256,13 @@
 	},
 	{
+		.cmd = CMD_AND,
+		.value = ICR_RXT0,
+		.srcarg = 2,
+		.dstarg = 1
+	},
+	{
 		.cmd = CMD_PREDICATE,
 		.value = 2,
-		.srcarg = 2
+		.srcarg = 1
 	},
 	{
@@ -1274,5 +1280,5 @@
 	e1000_irq_code.ranges[0].base = (uintptr_t) e1000->reg_base_phys;
 	e1000_irq_code.cmds[0].addr = e1000->reg_base_phys + E1000_ICR;
-	e1000_irq_code.cmds[2].addr = e1000->reg_base_phys + E1000_IMC;
+	e1000_irq_code.cmds[3].addr = e1000->reg_base_phys + E1000_IMC;
 
 	errno_t rc = register_interrupt_handler(nic_get_ddf_dev(nic), e1000->irq,
Index: uspace/drv/root/root/root.c
===================================================================
--- uspace/drv/root/root/root.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/drv/root/root/root.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -144,10 +144,11 @@
 
 	/* Null-terminate string. */
-	platform = realloc(platform, platform_size + 1);
-	if (platform == NULL) {
+	char *tmp = realloc(platform, platform_size + 1);
+	if (tmp == NULL) {
 		ddf_msg(LVL_ERROR, "Memory allocation failed.");
-		return ENOMEM;
-	}
-
+		free(platform);
+		return ENOMEM;
+	}
+	platform = tmp;
 	platform[platform_size] = '\0';
 
Index: uspace/lib/bithenge/src/helenos/common.h
===================================================================
--- uspace/lib/bithenge/src/helenos/common.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/bithenge/src/helenos/common.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -47,5 +47,5 @@
 	const char *string;
 	size_t offset;
-	wchar_t ch;
+	char32_t ch;
 } string_iterator_t;
 
@@ -64,5 +64,5 @@
 }
 
-static inline errno_t string_iterator_next(string_iterator_t *i, wchar_t *out)
+static inline errno_t string_iterator_next(string_iterator_t *i, char32_t *out)
 {
 	*out = i->ch;
Index: uspace/lib/bithenge/src/linux/common.h
===================================================================
--- uspace/lib/bithenge/src/linux/common.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/bithenge/src/linux/common.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -37,5 +37,5 @@
 #include <stdlib.h>
 #include <string.h>
-#include <wchar.h>
+#include <uchar.h>
 
 #define max(aleph, bet) ((aleph) > (bet) ? (aleph) : (bet))
@@ -55,8 +55,8 @@
 }
 
-static inline errno_t string_iterator_next(string_iterator_t *i, wchar_t *out)
+static inline errno_t string_iterator_next(string_iterator_t *i, char32_t *out)
 {
 	wint_t rc = btowc(*(*i)++); // TODO
-	*out = (wchar_t) rc;
+	*out = (char32_t) rc;
 	return rc == WEOF ? EILSEQ : EOK;
 }
@@ -72,5 +72,5 @@
 }
 
-static inline const char *str_chr(const char *string, wchar_t ch)
+static inline const char *str_chr(const char *string, char32_t ch)
 {
 	return strchr(string, wctob(ch)); // TODO
Index: uspace/lib/bithenge/src/print.c
===================================================================
--- uspace/lib/bithenge/src/print.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/bithenge/src/print.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -40,5 +40,5 @@
 #include <stdarg.h>
 #include <stdio.h>
-#include <wchar.h>
+#include <uchar.h>
 #include <bithenge/blob.h>
 #include <bithenge/print.h>
@@ -164,5 +164,5 @@
 	string_iterator_t i = string_iterator(value);
 	while (!string_iterator_done(&i)) {
-		wchar_t ch;
+		char32_t ch;
 		errno_t rc = string_iterator_next(&i, &ch);
 		if (rc != EOK)
Index: uspace/lib/c/generic/async/client.c
===================================================================
--- uspace/lib/c/generic/async/client.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/async/client.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -557,28 +557,34 @@
 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);
+	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, 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)
+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)
+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)
+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);
@@ -587,150 +593,215 @@
 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, 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)
+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)
+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);
+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);
 }
 
@@ -818,4 +889,5 @@
  * @param arg2  User defined argument.
  * @param arg3  User defined argument.
+ * @param rc    Placeholder for return code. Unused if NULL.
  *
  * @return New session on success or NULL on error.
@@ -823,8 +895,10 @@
  */
 async_sess_t *async_connect_me_to(async_exch_t *exch, iface_t iface,
-    sysarg_t arg2, sysarg_t arg3)
+    sysarg_t arg2, sysarg_t arg3, errno_t *rc)
 {
 	if (exch == NULL) {
-		errno = ENOENT;
+		if (rc != NULL)
+			*rc = ENOENT;
+
 		return NULL;
 	}
@@ -832,13 +906,17 @@
 	async_sess_t *sess = calloc(1, sizeof(async_sess_t));
 	if (sess == NULL) {
-		errno = ENOMEM;
+		if (rc != NULL)
+			*rc = ENOMEM;
+
 		return NULL;
 	}
 
 	cap_phone_handle_t phone;
-	errno_t rc = async_connect_me_to_internal(exch->phone, iface, arg2,
+	errno_t ret = async_connect_me_to_internal(exch->phone, iface, arg2,
 	    arg3, 0, &phone);
-	if (rc != EOK) {
-		errno = rc;
+	if (ret != EOK) {
+		if (rc != NULL)
+			*rc = ret;
+
 		free(sess);
 		return NULL;
@@ -886,4 +964,5 @@
  * @param arg2  User defined argument.
  * @param arg3  User defined argument.
+ * @param rc    Placeholder for return code. Unused if NULL.
  *
  * @return New session on success or NULL on error.
@@ -891,8 +970,10 @@
  */
 async_sess_t *async_connect_me_to_blocking(async_exch_t *exch, iface_t iface,
-    sysarg_t arg2, sysarg_t arg3)
+    sysarg_t arg2, sysarg_t arg3, errno_t *rc)
 {
 	if (exch == NULL) {
-		errno = ENOENT;
+		if (rc != NULL)
+			*rc = ENOENT;
+
 		return NULL;
 	}
@@ -900,13 +981,17 @@
 	async_sess_t *sess = calloc(1, sizeof(async_sess_t));
 	if (sess == NULL) {
-		errno = ENOMEM;
+		if (rc != NULL)
+			*rc = ENOMEM;
+
 		return NULL;
 	}
 
 	cap_phone_handle_t phone;
-	errno_t rc = async_connect_me_to_internal(exch->phone, iface, arg2,
+	errno_t ret = async_connect_me_to_internal(exch->phone, iface, arg2,
 	    arg3, IPC_FLAG_BLOCKING, &phone);
-	if (rc != EOK) {
-		errno = rc;
+	if (ret != EOK) {
+		if (rc != NULL)
+			*rc = ret;
+
 		free(sess);
 		return NULL;
@@ -928,17 +1013,26 @@
 /** Connect to a task specified by id.
  *
- */
-async_sess_t *async_connect_kbox(task_id_t id)
+ * @param id Task to which to connect.
+ * @param rc Placeholder for return code. Unused if NULL.
+ *
+ * @return New session on success or NULL on error.
+ *
+ */
+async_sess_t *async_connect_kbox(task_id_t id, errno_t *rc)
 {
 	async_sess_t *sess = calloc(1, sizeof(async_sess_t));
 	if (sess == NULL) {
-		errno = ENOMEM;
+		if (rc != NULL)
+			*rc = ENOMEM;
+
 		return NULL;
 	}
 
 	cap_phone_handle_t phone;
-	errno_t rc = ipc_connect_kbox(id, &phone);
-	if (rc != EOK) {
-		errno = rc;
+	errno_t ret = ipc_connect_kbox(id, &phone);
+	if (ret != EOK) {
+		if (rc != NULL)
+			*rc = ret;
+
 		free(sess);
 		return NULL;
@@ -956,7 +1050,11 @@
 }
 
-static errno_t async_hangup_internal(cap_phone_handle_t phone)
-{
-	return ipc_hangup(phone);
+static void async_hangup_internal(cap_phone_handle_t phone)
+{
+	errno_t rc;
+
+	rc = ipc_hangup(phone);
+	assert(rc == EOK);
+	(void) rc;
 }
 
@@ -964,9 +1062,6 @@
  *
  * @param sess Session to hung up.
- *
- * @return Zero on success or an error code.
- *
- */
-errno_t async_hangup(async_sess_t *sess)
+ */
+void async_hangup(async_sess_t *sess)
 {
 	async_exch_t *exch;
@@ -975,11 +1070,7 @@
 
 	fibril_mutex_lock(&async_sess_mutex);
-
-	if (sess->exchanges > 0) {
-		fibril_mutex_unlock(&async_sess_mutex);
-		return EBUSY;
-	}
-
-	errno_t rc = async_hangup_internal(sess->phone);
+	assert(sess->exchanges == 0);
+
+	async_hangup_internal(sess->phone);
 
 	while (!list_empty(&sess->exch_list)) {
@@ -990,5 +1081,7 @@
 		list_remove(&exch->sess_link);
 		list_remove(&exch->global_link);
-		async_hangup_internal(exch->phone);
+		if (sess->mgmt != EXCHANGE_ATOMIC &&
+		    sess->mgmt != EXCHANGE_SERIALIZE)
+			async_hangup_internal(exch->phone);
 		free(exch);
 	}
@@ -997,6 +1090,4 @@
 
 	fibril_mutex_unlock(&async_sess_mutex);
-
-	return rc;
 }
 
Index: uspace/lib/c/generic/devman.c
===================================================================
--- uspace/lib/c/generic/devman.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/devman.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -89,5 +89,5 @@
 				devman_driver_block_sess =
 				    service_connect_blocking(SERVICE_DEVMAN,
-				    INTERFACE_DDF_DRIVER, 0);
+				    INTERFACE_DDF_DRIVER, 0, NULL);
 		}
 
@@ -108,5 +108,5 @@
 				devman_client_block_sess =
 				    service_connect_blocking(SERVICE_DEVMAN,
-				    INTERFACE_DDF_CLIENT, 0);
+				    INTERFACE_DDF_CLIENT, 0, NULL);
 		}
 
@@ -138,5 +138,5 @@
 			devman_driver_sess =
 			    service_connect(SERVICE_DEVMAN,
-			    INTERFACE_DDF_DRIVER, 0);
+			    INTERFACE_DDF_DRIVER, 0, NULL);
 
 		fibril_mutex_unlock(&devman_driver_mutex);
@@ -152,5 +152,5 @@
 			devman_client_sess =
 			    service_connect(SERVICE_DEVMAN,
-			    INTERFACE_DDF_CLIENT, 0);
+			    INTERFACE_DDF_CLIENT, 0, NULL);
 
 		fibril_mutex_unlock(&devman_client_mutex);
@@ -292,8 +292,8 @@
 	if (flags & IPC_FLAG_BLOCKING)
 		sess = service_connect_blocking(SERVICE_DEVMAN,
-		    INTERFACE_DEVMAN_DEVICE, handle);
+		    INTERFACE_DEVMAN_DEVICE, handle, NULL);
 	else
 		sess = service_connect(SERVICE_DEVMAN,
-		    INTERFACE_DEVMAN_DEVICE, handle);
+		    INTERFACE_DEVMAN_DEVICE, handle, NULL);
 
 	return sess;
@@ -350,8 +350,8 @@
 	if (flags & IPC_FLAG_BLOCKING)
 		sess = service_connect_blocking(SERVICE_DEVMAN,
-		    INTERFACE_DEVMAN_PARENT, handle);
+		    INTERFACE_DEVMAN_PARENT, handle, NULL);
 	else
-		sess = service_connect_blocking(SERVICE_DEVMAN,
-		    INTERFACE_DEVMAN_PARENT, handle);
+		sess = service_connect(SERVICE_DEVMAN,
+		    INTERFACE_DEVMAN_PARENT, handle, NULL);
 
 	return sess;
Index: uspace/lib/c/generic/inet/tcp.c
===================================================================
--- uspace/lib/c/generic/inet/tcp.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/inet/tcp.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -455,12 +455,11 @@
 	exch = async_exchange_begin(conn->tcp->sess);
 	aid_t req = async_send_1(exch, TCP_CONN_SEND, conn->id, NULL);
-
 	rc = async_data_write_start(exch, data, bytes);
+	async_exchange_end(exch);
+
 	if (rc != EOK) {
 		async_forget(req);
 		return rc;
 	}
-
-	async_exchange_end(exch);
 
 	if (rc != EOK) {
Index: uspace/lib/c/generic/inetcfg.c
===================================================================
--- uspace/lib/c/generic/inetcfg.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/inetcfg.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -103,7 +103,10 @@
 
 		alloc_size = act_size;
-		ids = realloc(ids, alloc_size);
-		if (ids == NULL)
+		service_id_t *tmp = realloc(ids, alloc_size);
+		if (tmp == NULL) {
+			free(ids);
 			return ENOMEM;
+		}
+		ids = tmp;
 	}
 
Index: uspace/lib/c/generic/io/asprintf.c
===================================================================
--- uspace/lib/c/generic/io/asprintf.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/io/asprintf.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -46,5 +46,5 @@
 }
 
-static int asprintf_wstr_write(const wchar_t *str, size_t count, void *unused)
+static int asprintf_wstr_write(const char32_t *str, size_t count, void *unused)
 {
 	return wstr_nlength(str, count);
Index: uspace/lib/c/generic/io/chargrid.c
===================================================================
--- uspace/lib/c/generic/io/chargrid.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/io/chargrid.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -140,5 +140,5 @@
  *
  */
-sysarg_t chargrid_putwchar(chargrid_t *scrbuf, wchar_t ch, bool update)
+sysarg_t chargrid_putuchar(chargrid_t *scrbuf, char32_t ch, bool update)
 {
 	assert(scrbuf->col < scrbuf->cols);
@@ -199,5 +199,5 @@
 
 	for (sysarg_t i = 0; i < spaces; i++)
-		flush += chargrid_putwchar(scrbuf, ' ', true) - 1;
+		flush += chargrid_putuchar(scrbuf, ' ', true) - 1;
 
 	return flush;
@@ -228,10 +228,10 @@
 		scrbuf->row--;
 
-		chargrid_putwchar(scrbuf, ' ', false);
+		chargrid_putuchar(scrbuf, ' ', false);
 		return 2;
 	}
 
 	scrbuf->col--;
-	chargrid_putwchar(scrbuf, ' ', false);
+	chargrid_putuchar(scrbuf, ' ', false);
 	return 1;
 }
Index: uspace/lib/c/generic/io/input.c
===================================================================
--- uspace/lib/c/generic/io/input.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/io/input.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -109,5 +109,5 @@
 	keycode_t key;
 	keymod_t mods;
-	wchar_t c;
+	char32_t c;
 	errno_t rc;
 
Index: uspace/lib/c/generic/io/io.c
===================================================================
--- uspace/lib/c/generic/io/io.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/io/io.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -48,4 +48,5 @@
 #include <adt/list.h>
 #include <wchar.h>
+#include <uchar.h>
 #include "../private/io.h"
 #include "../private/stdio.h"
@@ -749,7 +750,29 @@
 }
 
+wint_t fputuc(char32_t wc, FILE *stream)
+{
+	char buf[STR_BOUNDS(1)];
+	size_t sz = 0;
+
+	if (chr_encode(wc, buf, &sz, STR_BOUNDS(1)) != EOK) {
+		errno = EILSEQ;
+		return WEOF;
+	}
+
+	size_t wr = fwrite(buf, 1, sz, stream);
+	if (wr < sz)
+		return WEOF;
+
+	return wc;
+}
+
 wint_t putwchar(wchar_t wc)
 {
 	return fputwc(wc, stdout);
+}
+
+wint_t putuchar(char32_t wc)
+{
+	return fputuc(wc, stdout);
 }
 
Index: uspace/lib/c/generic/io/kio.c
===================================================================
--- uspace/lib/c/generic/io/kio.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/io/kio.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -140,5 +140,5 @@
 }
 
-static int kio_vprintf_wstr_write(const wchar_t *str, size_t size, void *data)
+static int kio_vprintf_wstr_write(const char32_t *str, size_t size, void *data)
 {
 	size_t offset = 0;
@@ -154,5 +154,5 @@
 
 		chars++;
-		offset += sizeof(wchar_t);
+		offset += sizeof(char32_t);
 	}
 
Index: uspace/lib/c/generic/io/log.c
===================================================================
--- uspace/lib/c/generic/io/log.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/io/log.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -167,9 +167,9 @@
 		return ENOMEM;
 
+	errno_t rc;
 	logger_session = service_connect_blocking(SERVICE_LOGGER,
-	    INTERFACE_LOGGER_WRITER, 0);
-	if (logger_session == NULL) {
-		return ENOMEM;
-	}
+	    INTERFACE_LOGGER_WRITER, 0, &rc);
+	if (logger_session == NULL)
+		return rc;
 
 	default_log_id = log_create(prog_name, LOG_NO_PARENT);
Index: uspace/lib/c/generic/io/logctl.c
===================================================================
--- uspace/lib/c/generic/io/logctl.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/io/logctl.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -48,8 +48,9 @@
 
 	if (logger_session == NULL) {
+		errno_t rc;
 		logger_session = service_connect_blocking(SERVICE_LOGGER,
-		    INTERFACE_LOGGER_CONTROL, 0);
+		    INTERFACE_LOGGER_CONTROL, 0, &rc);
 		if (logger_session == NULL)
-			return ENOMEM;
+			return rc;
 	}
 
Index: uspace/lib/c/generic/io/printf_core.c
===================================================================
--- uspace/lib/c/generic/io/printf_core.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/io/printf_core.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -47,5 +47,5 @@
 #include <assert.h>
 #include <macros.h>
-#include <wchar.h>
+#include <uchar.h>
 
 /** show prefixes 0x or 0 */
@@ -187,5 +187,5 @@
  *
  */
-static int printf_wputnchars(const wchar_t *buf, size_t size,
+static int printf_wputnchars(const char32_t *buf, size_t size,
     printf_spec_t *ps)
 {
@@ -233,10 +233,10 @@
  *
  */
-static int printf_putwchar(const wchar_t ch, printf_spec_t *ps)
+static int printf_putuchar(const char32_t ch, printf_spec_t *ps)
 {
 	if (!chr_check(ch))
 		return ps->str_write((void *) &invalch, 1, ps->data);
 
-	return ps->wstr_write(&ch, sizeof(wchar_t), ps->data);
+	return ps->wstr_write(&ch, sizeof(char32_t), ps->data);
 }
 
@@ -288,5 +288,5 @@
  *
  */
-static int print_wchar(const wchar_t ch, int width, uint32_t flags, printf_spec_t *ps)
+static int print_wchar(const char32_t ch, int width, uint32_t flags, printf_spec_t *ps)
 {
 	size_t counter = 0;
@@ -302,5 +302,5 @@
 	}
 
-	if (printf_putwchar(ch, ps) > 0)
+	if (printf_putuchar(ch, ps) > 0)
 		counter++;
 
@@ -375,5 +375,5 @@
  * @return Number of wide characters printed, negative value on failure.
  */
-static int print_wstr(wchar_t *str, int width, unsigned int precision,
+static int print_wstr(char32_t *str, int width, unsigned int precision,
     uint32_t flags, printf_spec_t *ps)
 {
@@ -1276,5 +1276,5 @@
  *  - "l"  Signed or unsigned long int.@n
  *         If conversion is "c", the character is wint_t (wide character).@n
- *         If conversion is "s", the string is wchar_t * (wide string).@n
+ *         If conversion is "s", the string is char32_t * (wide string).@n
  *  - "ll" Signed or unsigned long long int.@n
  *  - "z"  Signed or unsigned ssize_t or site_t.@n
@@ -1330,5 +1330,5 @@
 	while (true) {
 		i = nxt;
-		wchar_t uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
+		char32_t uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
 
 		if (uc == 0)
@@ -1493,5 +1493,5 @@
 
 				if (qualifier == PrintfQualifierLong)
-					retval = print_wstr(va_arg(ap, wchar_t *), width, precision, flags, ps);
+					retval = print_wstr(va_arg(ap, char32_t *), width, precision, flags, ps);
 				else
 					retval = print_str(va_arg(ap, char *), width, precision, flags, ps);
Index: uspace/lib/c/generic/io/vprintf.c
===================================================================
--- uspace/lib/c/generic/io/vprintf.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/io/vprintf.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -48,5 +48,5 @@
 }
 
-static int vprintf_wstr_write(const wchar_t *str, size_t size, void *stream)
+static int vprintf_wstr_write(const char32_t *str, size_t size, void *stream)
 {
 	size_t offset = 0;
@@ -54,9 +54,9 @@
 
 	while (offset < size) {
-		if (fputwc(str[chars], (FILE *) stream) <= 0)
+		if (fputuc(str[chars], (FILE *) stream) <= 0)
 			break;
 
 		chars++;
-		offset += sizeof(wchar_t);
+		offset += sizeof(char32_t);
 	}
 
Index: uspace/lib/c/generic/io/vsnprintf.c
===================================================================
--- uspace/lib/c/generic/io/vsnprintf.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/io/vsnprintf.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -88,5 +88,5 @@
 
 		while (index < size) {
-			wchar_t uc = str_decode(str, &index, size);
+			char32_t uc = str_decode(str, &index, size);
 
 			if (chr_encode(uc, data->dst, &data->len, data->size - 1) != EOK)
@@ -133,9 +133,9 @@
  *
  */
-static int vsnprintf_wstr_write(const wchar_t *str, size_t size, vsnprintf_data_t *data)
+static int vsnprintf_wstr_write(const char32_t *str, size_t size, vsnprintf_data_t *data)
 {
 	size_t index = 0;
 
-	while (index < (size / sizeof(wchar_t))) {
+	while (index < (size / sizeof(char32_t))) {
 		size_t left = data->size - data->len;
 
@@ -177,5 +177,5 @@
 	printf_spec_t ps = {
 		(int (*) (const char *, size_t, void *)) vsnprintf_str_write,
-		(int (*) (const wchar_t *, size_t, void *)) vsnprintf_wstr_write,
+		(int (*) (const char32_t *, size_t, void *)) vsnprintf_wstr_write,
 		&data
 	};
Index: uspace/lib/c/generic/loader.c
===================================================================
--- uspace/lib/c/generic/loader.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/loader.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -46,11 +46,13 @@
 #include "private/loader.h"
 
-/** Connect to a new program loader.
- *
- * Spawns a new program loader task and returns the connection structure.
+/** Spawn a new program loader.
+ *
+ * Spawn a new program loader task. The loader then independetly
+ * connects to the naming service.
  *
  * @param name Symbolic name to set on the newly created task.
  *
  * @return Error code.
+ *
  */
 errno_t loader_spawn(const char *name)
@@ -60,5 +62,12 @@
 }
 
-loader_t *loader_connect(void)
+/** Connect to a program loader.
+ *
+ * @param rc Placeholder for return code. Unused if NULL.
+ *
+ * @return Loader structure.
+ *
+ */
+loader_t *loader_connect(errno_t *rc)
 {
 	loader_t *ldr = malloc(sizeof(loader_t));
@@ -67,5 +76,5 @@
 
 	async_sess_t *sess =
-	    service_connect_blocking(SERVICE_LOADER, INTERFACE_LOADER, 0);
+	    service_connect_blocking(SERVICE_LOADER, INTERFACE_LOADER, 0, rc);
 	if (sess == NULL) {
 		free(ldr);
Index: uspace/lib/c/generic/loc.c
===================================================================
--- uspace/lib/c/generic/loc.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/loc.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -153,5 +153,5 @@
 				loc_supp_block_sess =
 				    service_connect_blocking(SERVICE_LOC,
-				    INTERFACE_LOC_SUPPLIER, 0);
+				    INTERFACE_LOC_SUPPLIER, 0, NULL);
 		}
 
@@ -172,5 +172,5 @@
 				loc_cons_block_sess =
 				    service_connect_blocking(SERVICE_LOC,
-				    INTERFACE_LOC_CONSUMER, 0);
+				    INTERFACE_LOC_CONSUMER, 0, NULL);
 		}
 
@@ -202,5 +202,5 @@
 			loc_supplier_sess =
 			    service_connect(SERVICE_LOC,
-			    INTERFACE_LOC_SUPPLIER, 0);
+			    INTERFACE_LOC_SUPPLIER, 0, NULL);
 
 		fibril_mutex_unlock(&loc_supplier_mutex);
@@ -216,5 +216,5 @@
 			loc_consumer_sess =
 			    service_connect(SERVICE_LOC,
-			    INTERFACE_LOC_CONSUMER, 0);
+			    INTERFACE_LOC_CONSUMER, 0, NULL);
 
 		fibril_mutex_unlock(&loc_consumer_mutex);
@@ -567,7 +567,7 @@
 
 	if (flags & IPC_FLAG_BLOCKING)
-		sess = service_connect_blocking(SERVICE_LOC, iface, handle);
+		sess = service_connect_blocking(SERVICE_LOC, iface, handle, NULL);
 	else
-		sess = service_connect(SERVICE_LOC, iface, handle);
+		sess = service_connect(SERVICE_LOC, iface, handle, NULL);
 
 	return sess;
@@ -819,7 +819,10 @@
 
 		alloc_size = act_size;
-		ids = realloc(ids, alloc_size);
-		if (ids == NULL)
+		service_id_t *tmp = realloc(ids, alloc_size);
+		if (tmp == NULL) {
+			free(ids);
 			return ENOMEM;
+		}
+		ids = tmp;
 	}
 
Index: uspace/lib/c/generic/malloc.c
===================================================================
--- uspace/lib/c/generic/malloc.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/malloc.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -35,4 +35,5 @@
 
 #include <malloc.h>
+#include <stdalign.h>
 #include <stdbool.h>
 #include <stddef.h>
@@ -81,21 +82,21 @@
 	(sizeof(heap_block_head_t) + sizeof(heap_block_foot_t))
 
+/** Calculate real size of a heap block.
+ *
+ * Add header and footer size.
+ *
+ */
+#define GROSS_SIZE(size)  ((size) + STRUCT_OVERHEAD)
+
+/** Calculate net size of a heap block.
+ *
+ * Subtract header and footer size.
+ *
+ */
+#define NET_SIZE(size)  ((size) - STRUCT_OVERHEAD)
+
 /** Overhead of each area. */
 #define AREA_OVERHEAD(size) \
-	(ALIGN_UP(size + sizeof(heap_area_t), BASE_ALIGN))
-
-/** Calculate real size of a heap block.
- *
- * Add header and footer size.
- *
- */
-#define GROSS_SIZE(size)  ((size) + STRUCT_OVERHEAD)
-
-/** Calculate net size of a heap block.
- *
- * Subtract header and footer size.
- *
- */
-#define NET_SIZE(size)  ((size) - STRUCT_OVERHEAD)
+	(ALIGN_UP(GROSS_SIZE(size) + sizeof(heap_area_t), BASE_ALIGN))
 
 /** Get first block in heap area.
@@ -198,4 +199,12 @@
 
 #define malloc_assert(expr) safe_assert(expr)
+
+/*
+ * Make sure the base alignment is sufficient.
+ */
+static_assert(BASE_ALIGN >= alignof(heap_area_t), "");
+static_assert(BASE_ALIGN >= alignof(heap_block_head_t), "");
+static_assert(BASE_ALIGN >= alignof(heap_block_foot_t), "");
+static_assert(BASE_ALIGN >= alignof(max_align_t), "");
 
 /** Serializes access to the heap from multiple threads. */
Index: uspace/lib/c/generic/ns.c
===================================================================
--- uspace/lib/c/generic/ns.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/ns.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -49,10 +49,11 @@
     async_port_handler_t handler, void *data)
 {
-	async_sess_t *sess = ns_session_get();
-	if (sess == NULL)
-		return EIO;
+	errno_t rc;
+	async_sess_t *sess = ns_session_get(&rc);
+	if (sess == NULL)
+		return rc;
 
 	port_id_t port;
-	errno_t rc = async_create_port(iface, handler, data, &port);
+	rc = async_create_port(iface, handler, data, &port);
 	if (rc != EOK)
 		return rc;
@@ -81,7 +82,8 @@
 	async_set_fallback_port_handler(handler, data);
 
-	async_sess_t *sess = ns_session_get();
-	if (sess == NULL)
-		return EIO;
+	errno_t rc;
+	async_sess_t *sess = ns_session_get(&rc);
+	if (sess == NULL)
+		return rc;
 
 	async_exch_t *exch = async_exchange_begin(sess);
@@ -89,5 +91,5 @@
 	ipc_call_t answer;
 	aid_t req = async_send_1(exch, NS_REGISTER_BROKER, service, &answer);
-	errno_t rc = async_connect_to_me(exch, INTERFACE_ANY, service, 0);
+	rc = async_connect_to_me(exch, INTERFACE_ANY, service, 0);
 
 	async_exchange_end(exch);
@@ -103,7 +105,18 @@
 }
 
-async_sess_t *service_connect(service_t service, iface_t iface, sysarg_t arg3)
-{
-	async_sess_t *sess = ns_session_get();
+/** Connect to a singleton service.
+ *
+ * @param service Singleton service ID.
+ * @param iface   Interface to connect to.
+ * @param arg3    Custom connection argument.
+ * @param rc      Placeholder for return code. Unused if NULL.
+ *
+ * @return New session on success or NULL on error.
+ *
+ */
+async_sess_t *service_connect(service_t service, iface_t iface, sysarg_t arg3,
+    errno_t *rc)
+{
+	async_sess_t *sess = ns_session_get(rc);
 	if (sess == NULL)
 		return NULL;
@@ -114,5 +127,5 @@
 
 	async_sess_t *csess =
-	    async_connect_me_to(exch, iface, service, arg3);
+	    async_connect_me_to(exch, iface, service, arg3, rc);
 	async_exchange_end(exch);
 
@@ -130,8 +143,18 @@
 }
 
+/** Wait and connect to a singleton service.
+ *
+ * @param service Singleton service ID.
+ * @param iface   Interface to connect to.
+ * @param arg3    Custom connection argument.
+ * @param rc      Placeholder for return code. Unused if NULL.
+ *
+ * @return New session on success or NULL on error.
+ *
+ */
 async_sess_t *service_connect_blocking(service_t service, iface_t iface,
-    sysarg_t arg3)
-{
-	async_sess_t *sess = ns_session_get();
+    sysarg_t arg3, errno_t *rc)
+{
+	async_sess_t *sess = ns_session_get(rc);
 	if (sess == NULL)
 		return NULL;
@@ -139,5 +162,5 @@
 	async_exch_t *exch = async_exchange_begin(sess);
 	async_sess_t *csess =
-	    async_connect_me_to_blocking(exch, iface, service, arg3);
+	    async_connect_me_to_blocking(exch, iface, service, arg3, rc);
 	async_exchange_end(exch);
 
@@ -157,30 +180,31 @@
 errno_t ns_ping(void)
 {
-	async_sess_t *sess = ns_session_get();
+	errno_t rc;
+	async_sess_t *sess = ns_session_get(&rc);
+	if (sess == NULL)
+		return rc;
+
+	async_exch_t *exch = async_exchange_begin(sess);
+	rc = async_req_0_0(exch, NS_PING);
+	async_exchange_end(exch);
+
+	return rc;
+}
+
+errno_t ns_intro(task_id_t id)
+{
+	errno_t rc;
+	async_sess_t *sess = ns_session_get(&rc);
 	if (sess == NULL)
 		return EIO;
 
 	async_exch_t *exch = async_exchange_begin(sess);
-	errno_t rc = async_req_0_0(exch, NS_PING);
-	async_exchange_end(exch);
-
-	return rc;
-}
-
-errno_t ns_intro(task_id_t id)
-{
-	async_exch_t *exch;
-	async_sess_t *sess = ns_session_get();
-	if (sess == NULL)
-		return EIO;
-
-	exch = async_exchange_begin(sess);
-	errno_t rc = async_req_2_0(exch, NS_ID_INTRO, LOWER32(id), UPPER32(id));
-	async_exchange_end(exch);
-
-	return rc;
-}
-
-async_sess_t *ns_session_get(void)
+	rc = async_req_2_0(exch, NS_ID_INTRO, LOWER32(id), UPPER32(id));
+	async_exchange_end(exch);
+
+	return rc;
+}
+
+async_sess_t *ns_session_get(errno_t *rc)
 {
 	async_exch_t *exch;
@@ -188,5 +212,5 @@
 	if (sess_ns == NULL) {
 		exch = async_exchange_begin(&session_ns);
-		sess_ns = async_connect_me_to(exch, 0, 0, 0);
+		sess_ns = async_connect_me_to(exch, 0, 0, 0, rc);
 		async_exchange_end(exch);
 		if (sess_ns == NULL)
Index: uspace/lib/c/generic/pci.c
===================================================================
--- uspace/lib/c/generic/pci.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/pci.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -163,7 +163,10 @@
 
 		alloc_size = act_size;
-		ids = realloc(ids, alloc_size);
-		if (ids == NULL)
+		service_id_t *tmp = realloc(ids, alloc_size);
+		if (tmp == NULL) {
+			free(ids);
 			return ENOMEM;
+		}
+		ids = tmp;
 	}
 
Index: uspace/lib/c/generic/rtld/module.c
===================================================================
--- uspace/lib/c/generic/rtld/module.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/rtld/module.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -40,4 +40,5 @@
 #include <errno.h>
 #include <loader/pcb.h>
+#include <stdalign.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -353,5 +354,5 @@
 #ifdef CONFIG_TLS_VARIANT_1
 	rtld->tls_size = sizeof(tcb_t);
-	rtld->tls_align = _Alignof(tcb_t);
+	rtld->tls_align = alignof(tcb_t);
 
 	list_foreach(rtld->modules, modules_link, module_t, m) {
@@ -366,5 +367,5 @@
 #else
 	rtld->tls_size = 0;
-	rtld->tls_align = _Alignof(tcb_t);
+	rtld->tls_align = alignof(tcb_t);
 
 	list_foreach(rtld->modules, modules_link, module_t, m) {
Index: uspace/lib/c/generic/stats.c
===================================================================
--- uspace/lib/c/generic/stats.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/stats.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -184,4 +184,30 @@
 }
 
+/** Get IPC connections statistics.
+ *
+ * @param count Number of records returned.
+ *
+ * @return Array of stats_ipcc_t structures.
+ *         If non-NULL then it should be eventually freed
+ *         by free().
+ *
+ */
+stats_ipcc_t *stats_get_ipccs(size_t *count)
+{
+	size_t size = 0;
+	stats_ipcc_t *stats_ipccs =
+	    (stats_ipcc_t *) sysinfo_get_data("system.ipccs", &size);
+
+	if ((size % sizeof(stats_ipcc_t)) != 0) {
+		if (stats_ipccs != NULL)
+			free(stats_ipccs);
+		*count = 0;
+		return NULL;
+	}
+
+	*count = size / sizeof(stats_ipcc_t);
+	return stats_ipccs;
+}
+
 /** Get exception statistics.
  *
Index: uspace/lib/c/generic/stdio/sstream.c
===================================================================
--- uspace/lib/c/generic/stdio/sstream.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/stdio/sstream.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -37,5 +37,5 @@
 #include <errno.h>
 #include <adt/list.h>
-#include <wchar.h>
+#include <uchar.h>
 #include "../private/stdio.h"
 #include "../private/sstream.h"
Index: uspace/lib/c/generic/str.c
===================================================================
--- uspace/lib/c/generic/str.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/str.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -42,5 +42,5 @@
  * 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
+ * represented as char32_t.@n
  *
  * Overview of the terminology:@n
@@ -50,6 +50,6 @@
  *  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
+ *  character             UTF-32 encoded Unicode character, stored in char32_t
+ *                        (unsigned 32 bit integer), code points 0 .. 1114111
  *                        are valid
  *
@@ -61,5 +61,5 @@
  *
  *  wide string           UTF-32 encoded NULL-terminated Unicode string,
- *                        wchar_t *
+ *                        char32_t *
  *
  *  [wide] string size    number of BYTES in a [wide] string (excluding
@@ -100,5 +100,5 @@
  * A specific character inside a [wide] string can be referred to by:@n
  *
- *  pointer (char *, wchar_t *)
+ *  pointer (char *, char32_t *)
  *  byte offset (size_t)
  *  character index (size_t)
@@ -119,11 +119,4 @@
 #include <mem.h>
 
-/** Check the condition if wchar_t is signed */
-#ifdef __WCHAR_UNSIGNED__
-#define WCHAR_SIGNED_CHECK(cond)  (true)
-#else
-#define WCHAR_SIGNED_CHECK(cond)  (cond)
-#endif
-
 /** Byte mask consisting of lowest @n bits (out of 8) */
 #define LO_MASK_8(n)  ((uint8_t) ((1 << (n)) - 1))
@@ -153,5 +146,5 @@
  *
  */
-wchar_t str_decode(const char *str, size_t *offset, size_t size)
+char32_t str_decode(const char *str, size_t *offset, size_t size)
 {
 	if (*offset + 1 > size)
@@ -190,5 +183,5 @@
 		return U_SPECIAL;
 
-	wchar_t ch = b0 & LO_MASK_8(b0_bits);
+	char32_t ch = b0 & LO_MASK_8(b0_bits);
 
 	/* Decode continuation bytes */
@@ -201,5 +194,5 @@
 
 		/* Shift data bits to ch */
-		ch = (ch << CONT_BITS) | (wchar_t) (b & LO_MASK_8(CONT_BITS));
+		ch = (ch << CONT_BITS) | (char32_t) (b & LO_MASK_8(CONT_BITS));
 		cbytes--;
 	}
@@ -223,5 +216,5 @@
  *
  */
-wchar_t str_decode_reverse(const char *str, size_t *offset, size_t size)
+char32_t str_decode_reverse(const char *str, size_t *offset, size_t size)
 {
 	if (*offset == 0)
@@ -266,5 +259,5 @@
  *         code was invalid.
  */
-errno_t chr_encode(const wchar_t ch, char *str, size_t *offset, size_t size)
+errno_t chr_encode(const char32_t ch, char *str, size_t *offset, size_t size)
 {
 	if (*offset >= size)
@@ -352,7 +345,7 @@
  *
  */
-size_t wstr_size(const wchar_t *str)
-{
-	return (wstr_length(str) * sizeof(wchar_t));
+size_t wstr_size(const char32_t *str)
+{
+	return (wstr_length(str) * sizeof(char32_t));
 }
 
@@ -417,7 +410,7 @@
  *
  */
-size_t wstr_nsize(const wchar_t *str, size_t max_size)
-{
-	return (wstr_nlength(str, max_size) * sizeof(wchar_t));
+size_t wstr_nsize(const char32_t *str, size_t max_size)
+{
+	return (wstr_nlength(str, max_size) * sizeof(char32_t));
 }
 
@@ -435,7 +428,7 @@
  *
  */
-size_t wstr_lsize(const wchar_t *str, size_t max_len)
-{
-	return (wstr_nlength(str, max_len * sizeof(wchar_t)) * sizeof(wchar_t));
+size_t wstr_lsize(const char32_t *str, size_t max_len)
+{
+	return (wstr_nlength(str, max_len * sizeof(char32_t)) * sizeof(char32_t));
 }
 
@@ -465,5 +458,5 @@
  *
  */
-size_t wstr_length(const wchar_t *wstr)
+size_t wstr_length(const char32_t *wstr)
 {
 	size_t len = 0;
@@ -502,13 +495,13 @@
  *
  */
-size_t wstr_nlength(const wchar_t *str, size_t size)
+size_t wstr_nlength(const char32_t *str, size_t size)
 {
 	size_t len = 0;
-	size_t limit = ALIGN_DOWN(size, sizeof(wchar_t));
+	size_t limit = ALIGN_DOWN(size, sizeof(char32_t));
 	size_t offset = 0;
 
 	while ((offset < limit) && (*str++ != 0)) {
 		len++;
-		offset += sizeof(wchar_t);
+		offset += sizeof(char32_t);
 	}
 
@@ -521,5 +514,5 @@
  * @return	Width of character in cells.
  */
-size_t chr_width(wchar_t ch)
+size_t chr_width(char32_t ch)
 {
 	return 1;
@@ -535,5 +528,5 @@
 	size_t width = 0;
 	size_t offset = 0;
-	wchar_t ch;
+	char32_t ch;
 
 	while ((ch = str_decode(str, &offset, STR_NO_LIMIT)) != 0)
@@ -548,7 +541,7 @@
  *
  */
-bool ascii_check(wchar_t ch)
-{
-	if (WCHAR_SIGNED_CHECK(ch >= 0) && (ch <= 127))
+bool ascii_check(char32_t ch)
+{
+	if (ch <= 127)
 		return true;
 
@@ -561,7 +554,7 @@
  *
  */
-bool chr_check(wchar_t ch)
-{
-	if (WCHAR_SIGNED_CHECK(ch >= 0) && (ch <= 1114111))
+bool chr_check(char32_t ch)
+{
+	if (ch <= 1114111)
 		return true;
 
@@ -589,6 +582,6 @@
 int str_cmp(const char *s1, const char *s2)
 {
-	wchar_t c1 = 0;
-	wchar_t c2 = 0;
+	char32_t c1 = 0;
+	char32_t c2 = 0;
 
 	size_t off1 = 0;
@@ -636,6 +629,6 @@
 int str_lcmp(const char *s1, const char *s2, size_t max_len)
 {
-	wchar_t c1 = 0;
-	wchar_t c2 = 0;
+	char32_t c1 = 0;
+	char32_t c2 = 0;
 
 	size_t off1 = 0;
@@ -688,6 +681,6 @@
 int str_casecmp(const char *s1, const char *s2)
 {
-	wchar_t c1 = 0;
-	wchar_t c2 = 0;
+	char32_t c1 = 0;
+	char32_t c2 = 0;
 
 	size_t off1 = 0;
@@ -736,6 +729,6 @@
 int str_lcasecmp(const char *s1, const char *s2, size_t max_len)
 {
-	wchar_t c1 = 0;
-	wchar_t c2 = 0;
+	char32_t c1 = 0;
+	char32_t c2 = 0;
 
 	size_t off1 = 0;
@@ -780,6 +773,6 @@
 bool str_test_prefix(const char *s, const char *p)
 {
-	wchar_t c1 = 0;
-	wchar_t c2 = 0;
+	char32_t c1 = 0;
+	char32_t c2 = 0;
 
 	size_t off1 = 0;
@@ -801,4 +794,30 @@
 
 	return false;
+}
+
+/** Get a string suffix.
+ *
+ * Return a string suffix defined by the prefix length.
+ *
+ * @param s             The string to get the suffix from.
+ * @param prefix_length Number of prefix characters to ignore.
+ *
+ * @return String suffix.
+ *
+ */
+const char *str_suffix(const char *s, size_t prefix_length)
+{
+	size_t off = 0;
+	size_t i = 0;
+
+	while (true) {
+		str_decode(s, &off, STR_NO_LIMIT);
+		i++;
+
+		if (i >= prefix_length)
+			break;
+	}
+
+	return s + off;
 }
 
@@ -824,5 +843,5 @@
 	size_t dest_off = 0;
 
-	wchar_t ch;
+	char32_t ch;
 	while ((ch = str_decode(src, &src_off, STR_NO_LIMIT)) != 0) {
 		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
@@ -857,5 +876,5 @@
 	size_t dest_off = 0;
 
-	wchar_t ch;
+	char32_t ch;
 	while ((ch = str_decode(src, &src_off, n)) != 0) {
 		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
@@ -961,7 +980,7 @@
  * @param src	Source wide string.
  */
-void wstr_to_str(char *dest, size_t size, const wchar_t *src)
-{
-	wchar_t ch;
+void wstr_to_str(char *dest, size_t size, const char32_t *src)
+{
+	char32_t ch;
 	size_t src_idx;
 	size_t dest_off;
@@ -996,5 +1015,5 @@
 {
 	size_t idx = 0, dest_off = 0;
-	wchar_t ch;
+	char32_t ch;
 	errno_t rc = EOK;
 
@@ -1040,5 +1059,5 @@
 	size_t offset = 0;
 	size_t idx = 0;
-	wchar_t c;
+	char32_t c;
 
 	assert(dlen > 0);
@@ -1097,9 +1116,9 @@
  * @return	New string.
  */
-char *wstr_to_astr(const wchar_t *src)
+char *wstr_to_astr(const char32_t *src)
 {
 	char dbuf[STR_BOUNDS(1)];
 	char *str;
-	wchar_t ch;
+	char32_t ch;
 
 	size_t src_idx;
@@ -1147,9 +1166,9 @@
  * @param src	Source string.
  */
-void str_to_wstr(wchar_t *dest, size_t dlen, const char *src)
+void str_to_wstr(char32_t *dest, size_t dlen, const char *src)
 {
 	size_t offset;
 	size_t di;
-	wchar_t c;
+	char32_t c;
 
 	assert(dlen > 0);
@@ -1176,9 +1195,9 @@
  * @param src	Source string.
  */
-wchar_t *str_to_awstr(const char *str)
+char32_t *str_to_awstr(const char *str)
 {
 	size_t len = str_length(str);
 
-	wchar_t *wstr = calloc(len + 1, sizeof(wchar_t));
+	char32_t *wstr = calloc(len + 1, sizeof(char32_t));
 	if (wstr == NULL)
 		return NULL;
@@ -1195,7 +1214,7 @@
  * @return Pointer to character in @a str or NULL if not found.
  */
-char *str_chr(const char *str, wchar_t ch)
-{
-	wchar_t acc;
+char *str_chr(const char *str, char32_t ch)
+{
+	char32_t acc;
 	size_t off = 0;
 	size_t last = 0;
@@ -1237,9 +1256,9 @@
  * @param ch  Character to remove.
  */
-void str_rtrim(char *str, wchar_t ch)
+void str_rtrim(char *str, char32_t ch)
 {
 	size_t off = 0;
 	size_t pos = 0;
-	wchar_t c;
+	char32_t c;
 	bool update_last_chunk = true;
 	char *last_chunk = NULL;
@@ -1265,7 +1284,7 @@
  * @param ch  Character to remove.
  */
-void str_ltrim(char *str, wchar_t ch)
-{
-	wchar_t acc;
+void str_ltrim(char *str, char32_t ch)
+{
+	char32_t acc;
 	size_t off = 0;
 	size_t pos = 0;
@@ -1293,7 +1312,7 @@
  * @return Pointer to character in @a str or NULL if not found.
  */
-char *str_rchr(const char *str, wchar_t ch)
-{
-	wchar_t acc;
+char *str_rchr(const char *str, char32_t ch)
+{
+	char32_t acc;
 	size_t off = 0;
 	size_t last = 0;
@@ -1323,5 +1342,5 @@
  *
  */
-bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos)
+bool wstr_linsert(char32_t *str, char32_t ch, size_t pos, size_t max_pos)
 {
 	size_t len = wstr_length(str);
@@ -1351,5 +1370,5 @@
  *
  */
-bool wstr_remove(wchar_t *str, size_t pos)
+bool wstr_remove(char32_t *str, size_t pos)
 {
 	size_t len = wstr_length(str);
@@ -1448,5 +1467,5 @@
 	size_t cur;
 	size_t tmp;
-	wchar_t ch;
+	char32_t ch;
 
 	/* Skip over leading delimiters. */
Index: uspace/lib/c/generic/str_error.c
===================================================================
--- uspace/lib/c/generic/str_error.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/str_error.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -63,5 +63,5 @@
 
 #undef __errno_entry
-#define __errno_entry(name, num, desc) "[" #name "]" desc,
+#define __errno_entry(name, num, desc) "[" #name "] " desc,
 
 static const char *err_desc[] = {
Index: uspace/lib/c/generic/task.c
===================================================================
--- uspace/lib/c/generic/task.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/task.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -181,7 +181,8 @@
 
 	/* Connect to a program loader. */
-	loader_t *ldr = loader_connect();
+	errno_t rc;
+	loader_t *ldr = loader_connect(&rc);
 	if (ldr == NULL)
-		return EREFUSED;
+		return rc;
 
 	bool wait_initialized = false;
@@ -189,5 +190,5 @@
 	/* Get task ID. */
 	task_id_t task_id;
-	errno_t rc = loader_get_task_id(ldr, &task_id);
+	rc = loader_get_task_id(ldr, &task_id);
 	if (rc != EOK)
 		goto error;
@@ -250,8 +251,7 @@
 	/* Start a debug session if requested */
 	if (rsess != NULL) {
-		ksess = async_connect_kbox(task_id);
+		ksess = async_connect_kbox(task_id, &rc);
 		if (ksess == NULL) {
 			/* Most likely debugging support is not compiled in */
-			rc = ENOTSUP;
 			goto error;
 		}
@@ -402,7 +402,8 @@
 errno_t task_setup_wait(task_id_t id, task_wait_t *wait)
 {
-	async_sess_t *sess_ns = ns_session_get();
+	errno_t rc;
+	async_sess_t *sess_ns = ns_session_get(&rc);
 	if (sess_ns == NULL)
-		return EIO;
+		return rc;
 
 	async_exch_t *exch = async_exchange_begin(sess_ns);
@@ -484,10 +485,11 @@
 errno_t task_retval(int val)
 {
-	async_sess_t *sess_ns = ns_session_get();
+	errno_t rc;
+	async_sess_t *sess_ns = ns_session_get(&rc);
 	if (sess_ns == NULL)
-		return EIO;
+		return rc;
 
 	async_exch_t *exch = async_exchange_begin(sess_ns);
-	errno_t rc = (errno_t) async_req_1_0(exch, NS_RETVAL, val);
+	rc = (errno_t) async_req_1_0(exch, NS_RETVAL, val);
 	async_exchange_end(exch);
 
Index: uspace/lib/c/generic/thread/tls.c
===================================================================
--- uspace/lib/c/generic/thread/tls.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/thread/tls.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -37,4 +37,5 @@
 
 #include <assert.h>
+#include <stdalign.h>
 #include <stddef.h>
 #include <align.h>
@@ -69,5 +70,5 @@
 #else
 	size_t tls_size = tls ? tls->p_memsz : 0;
-	return -ALIGN_UP((ptrdiff_t) tls_size, max(tls_align, _Alignof(tcb_t)));
+	return -ALIGN_UP((ptrdiff_t) tls_size, max(tls_align, alignof(tcb_t)));
 #endif
 }
@@ -104,8 +105,8 @@
 #else
 	size_t alloc_size =
-	    ALIGN_UP(tls_size, max(tls_align, _Alignof(tcb_t))) + sizeof(tcb_t);
-#endif
-
-	void *area = alloc(max(tls_align, _Alignof(tcb_t)), alloc_size);
+	    ALIGN_UP(tls_size, max(tls_align, alignof(tcb_t))) + sizeof(tcb_t);
+#endif
+
+	void *area = alloc(max(tls_align, alignof(tcb_t)), alloc_size);
 	if (!area)
 		return NULL;
@@ -187,5 +188,5 @@
 	tls_free_arch(tcb,
 	    ALIGN_UP(tls->p_memsz, tls->p_align) + sizeof(tcb_t),
-	    max(tls->p_align, _Alignof(tcb_t)));
+	    max(tls->p_align, alignof(tcb_t)));
 }
 
Index: uspace/lib/c/generic/udebug.c
===================================================================
--- uspace/lib/c/generic/udebug.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/udebug.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -42,5 +42,8 @@
 {
 	async_exch_t *exch = async_exchange_begin(sess);
-	return async_req_1_0(exch, IPC_M_DEBUG, UDEBUG_M_BEGIN);
+	errno_t rc = async_req_1_0(exch, IPC_M_DEBUG, UDEBUG_M_BEGIN);
+	async_exchange_end(exch);
+
+	return rc;
 }
 
@@ -48,5 +51,8 @@
 {
 	async_exch_t *exch = async_exchange_begin(sess);
-	return async_req_1_0(exch, IPC_M_DEBUG, UDEBUG_M_END);
+	errno_t rc = async_req_1_0(exch, IPC_M_DEBUG, UDEBUG_M_END);
+	async_exchange_end(exch);
+
+	return rc;
 }
 
@@ -54,5 +60,8 @@
 {
 	async_exch_t *exch = async_exchange_begin(sess);
-	return async_req_2_0(exch, IPC_M_DEBUG, UDEBUG_M_SET_EVMASK, mask);
+	errno_t rc = async_req_2_0(exch, IPC_M_DEBUG, UDEBUG_M_SET_EVMASK, mask);
+	async_exchange_end(exch);
+
+	return rc;
 }
 
@@ -65,4 +74,5 @@
 	errno_t rc = async_req_3_3(exch, IPC_M_DEBUG, UDEBUG_M_THREAD_READ,
 	    (sysarg_t) buffer, n, NULL, &a_copied, &a_needed);
+	async_exchange_end(exch);
 
 	*copied = (size_t) a_copied;
@@ -80,4 +90,5 @@
 	errno_t rc = async_req_3_3(exch, IPC_M_DEBUG, UDEBUG_M_NAME_READ,
 	    (sysarg_t) buffer, n, NULL, &a_copied, &a_needed);
+	async_exchange_end(exch);
 
 	*copied = (size_t) a_copied;
@@ -95,4 +106,5 @@
 	errno_t rc = async_req_3_3(exch, IPC_M_DEBUG, UDEBUG_M_AREAS_READ,
 	    (sysarg_t) buffer, n, NULL, &a_copied, &a_needed);
+	async_exchange_end(exch);
 
 	*copied = (size_t) a_copied;
@@ -105,6 +117,9 @@
 {
 	async_exch_t *exch = async_exchange_begin(sess);
-	return async_req_4_0(exch, IPC_M_DEBUG, UDEBUG_M_MEM_READ,
+	errno_t rc = async_req_4_0(exch, IPC_M_DEBUG, UDEBUG_M_MEM_READ,
 	    (sysarg_t) buffer, addr, n);
+	async_exchange_end(exch);
+
+	return rc;
 }
 
@@ -112,6 +127,9 @@
 {
 	async_exch_t *exch = async_exchange_begin(sess);
-	return async_req_3_0(exch, IPC_M_DEBUG, UDEBUG_M_ARGS_READ,
+	errno_t rc = async_req_3_0(exch, IPC_M_DEBUG, UDEBUG_M_ARGS_READ,
 	    tid, (sysarg_t) buffer);
+	async_exchange_end(exch);
+
+	return rc;
 }
 
@@ -119,6 +137,9 @@
 {
 	async_exch_t *exch = async_exchange_begin(sess);
-	return async_req_3_0(exch, IPC_M_DEBUG, UDEBUG_M_REGS_READ,
+	errno_t rc = async_req_3_0(exch, IPC_M_DEBUG, UDEBUG_M_REGS_READ,
 	    tid, (sysarg_t) buffer);
+	async_exchange_end(exch);
+
+	return rc;
 }
 
@@ -131,4 +152,5 @@
 	errno_t rc = async_req_2_3(exch, IPC_M_DEBUG, UDEBUG_M_GO,
 	    tid, &a_ev_type, val0, val1);
+	async_exchange_end(exch);
 
 	*ev_type = a_ev_type;
@@ -139,5 +161,8 @@
 {
 	async_exch_t *exch = async_exchange_begin(sess);
-	return async_req_2_0(exch, IPC_M_DEBUG, UDEBUG_M_STOP, tid);
+	errno_t rc = async_req_2_0(exch, IPC_M_DEBUG, UDEBUG_M_STOP, tid);
+	async_exchange_end(exch);
+
+	return rc;
 }
 
Index: uspace/lib/c/generic/uuid.c
===================================================================
--- uspace/lib/c/generic/uuid.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/uuid.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -189,6 +189,8 @@
 	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;
+	if (ret != 36) {
+		free(str);
+		return EINVAL;
+	}
 
 	*rstr = str;
Index: uspace/lib/c/generic/vbd.c
===================================================================
--- uspace/lib/c/generic/vbd.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/vbd.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -231,7 +231,10 @@
 
 		alloc_size = act_size;
-		ids = realloc(ids, alloc_size);
-		if (ids == NULL)
+		service_id_t *tmp = realloc(ids, alloc_size);
+		if (tmp == NULL) {
+			free(ids);
 			return ENOMEM;
+		}
+		ids = tmp;
 	}
 
Index: uspace/lib/c/generic/vfs/vfs.c
===================================================================
--- uspace/lib/c/generic/vfs/vfs.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/vfs/vfs.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -322,5 +322,5 @@
 	while (vfs_sess == NULL) {
 		vfs_sess = service_connect_blocking(SERVICE_VFS, INTERFACE_VFS,
-		    0);
+		    0, NULL);
 	}
 
Index: uspace/lib/c/generic/vol.c
===================================================================
--- uspace/lib/c/generic/vol.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/generic/vol.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -168,7 +168,10 @@
 
 		alloc_size = act_size;
-		ids = realloc(ids, alloc_size);
-		if (ids == NULL)
+		service_id_t *temp = realloc(ids, alloc_size);
+		if (temp == NULL) {
+			free(ids);
 			return ENOMEM;
+		}
+		ids = temp;
 	}
 
Index: uspace/lib/c/include/async.h
===================================================================
--- uspace/lib/c/include/async.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/include/async.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -275,12 +275,12 @@
 
 extern async_sess_t *async_connect_me_to(async_exch_t *, iface_t, sysarg_t,
-    sysarg_t);
+    sysarg_t, errno_t *);
 extern async_sess_t *async_connect_me_to_blocking(async_exch_t *, iface_t,
-    sysarg_t, sysarg_t);
-extern async_sess_t *async_connect_kbox(task_id_t);
+    sysarg_t, sysarg_t, errno_t *);
+extern async_sess_t *async_connect_kbox(task_id_t, errno_t *);
 
 extern errno_t async_connect_to_me(async_exch_t *, iface_t, sysarg_t, sysarg_t);
 
-extern errno_t async_hangup(async_sess_t *);
+extern void async_hangup(async_sess_t *);
 
 extern async_exch_t *async_exchange_begin(async_sess_t *);
Index: uspace/lib/c/include/io/charfield.h
===================================================================
--- uspace/lib/c/include/io/charfield.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/include/io/charfield.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -38,5 +38,5 @@
 
 #include <stdbool.h>
-#include <wchar.h>
+#include <uchar.h>
 #include <io/color.h>
 #include <io/style.h>
@@ -77,5 +77,5 @@
 
 typedef struct {
-	wchar_t ch;
+	char32_t ch;
 	char_attrs_t attrs;
 	char_flags_t flags;
Index: uspace/lib/c/include/io/chargrid.h
===================================================================
--- uspace/lib/c/include/io/chargrid.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/include/io/chargrid.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -79,5 +79,5 @@
 extern sysarg_t chargrid_get_top_row(chargrid_t *);
 
-extern sysarg_t chargrid_putwchar(chargrid_t *, wchar_t, bool);
+extern sysarg_t chargrid_putuchar(chargrid_t *, char32_t, bool);
 extern sysarg_t chargrid_newline(chargrid_t *);
 extern sysarg_t chargrid_tabstop(chargrid_t *, sysarg_t);
Index: uspace/lib/c/include/io/input.h
===================================================================
--- uspace/lib/c/include/io/input.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/include/io/input.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -50,5 +50,5 @@
 	errno_t (*active)(input_t *);
 	errno_t (*deactive)(input_t *);
-	errno_t (*key)(input_t *, kbd_event_type_t, keycode_t, keymod_t, wchar_t);
+	errno_t (*key)(input_t *, kbd_event_type_t, keycode_t, keymod_t, char32_t);
 	errno_t (*move)(input_t *, int, int);
 	errno_t (*abs_move)(input_t *, unsigned, unsigned, unsigned, unsigned);
Index: uspace/lib/c/include/io/kbd_event.h
===================================================================
--- uspace/lib/c/include/io/kbd_event.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/include/io/kbd_event.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -37,4 +37,5 @@
 
 #include <adt/list.h>
+#include <inttypes.h>
 #include <io/keycode.h>
 
@@ -59,5 +60,5 @@
 
 	/** The character that was generated or '\0' for none. */
-	wchar_t c;
+	char32_t c;
 } kbd_event_t;
 
Index: uspace/lib/c/include/io/printf_core.h
===================================================================
--- uspace/lib/c/include/io/printf_core.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/include/io/printf_core.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -38,4 +38,5 @@
 #include <stddef.h>
 #include <stdarg.h>
+#include <uchar.h>
 
 /** Structure for specifying output methods for different printf clones. */
@@ -45,5 +46,5 @@
 
 	/* Wide string output function, returns number of printed characters or EOF */
-	int (*wstr_write)(const wchar_t *, size_t, void *);
+	int (*wstr_write)(const char32_t *, size_t, void *);
 
 	/* User data - output stream specification, state, locks, etc. */
Index: uspace/lib/c/include/loader/loader.h
===================================================================
--- uspace/lib/c/include/loader/loader.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/include/loader/loader.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -44,5 +44,5 @@
 
 extern errno_t loader_spawn(const char *);
-extern loader_t *loader_connect(void);
+extern loader_t *loader_connect(errno_t *);
 extern errno_t loader_get_task_id(loader_t *, task_id_t *);
 extern errno_t loader_set_cwd(loader_t *);
Index: uspace/lib/c/include/ns.h
===================================================================
--- uspace/lib/c/include/ns.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/include/ns.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -43,10 +43,11 @@
     void *);
 extern errno_t service_register_broker(service_t, async_port_handler_t, void *);
-extern async_sess_t *service_connect(service_t, iface_t, sysarg_t);
-extern async_sess_t *service_connect_blocking(service_t, iface_t, sysarg_t);
+extern async_sess_t *service_connect(service_t, iface_t, sysarg_t, errno_t *);
+extern async_sess_t *service_connect_blocking(service_t, iface_t, sysarg_t,
+    errno_t *);
 
 extern errno_t ns_ping(void);
 extern errno_t ns_intro(task_id_t);
-extern async_sess_t *ns_session_get(void);
+extern async_sess_t *ns_session_get(errno_t *);
 
 #endif
Index: uspace/lib/c/include/stats.h
===================================================================
--- uspace/lib/c/include/stats.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/include/stats.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -52,4 +52,5 @@
 
 extern stats_thread_t *stats_get_threads(size_t *);
+extern stats_ipcc_t *stats_get_ipccs(size_t *);
 
 extern stats_exc_t *stats_get_exceptions(size_t *);
Index: uspace/lib/c/include/stdio.h
===================================================================
--- uspace/lib/c/include/stdio.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/include/stdio.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -42,4 +42,5 @@
 #include <_bits/size_t.h>
 #include <_bits/wchar_t.h>
+#include <_bits/uchar.h>
 #include <_bits/wint_t.h>
 #include <_bits/decls.h>
@@ -123,4 +124,7 @@
 extern wint_t fputwc(wchar_t, FILE *);
 extern wint_t putwchar(wchar_t);
+
+extern wint_t fputuc(char32_t, FILE *);
+extern wint_t putuchar(char32_t);
 
 /* Formatted string output functions */
Index: uspace/lib/c/include/stdlib.h
===================================================================
--- uspace/lib/c/include/stdlib.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/include/stdlib.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -38,4 +38,5 @@
 #include <_bits/size_t.h>
 #include <_bits/wchar_t.h>
+#include <_bits/uchar.h>
 #include <_bits/decls.h>
 #include <bsearch.h>
Index: uspace/lib/c/include/str.h
===================================================================
--- uspace/lib/c/include/str.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/include/str.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -67,28 +67,28 @@
 __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(wchar_t ch, char *str, size_t *offset, size_t sz);
+extern char32_t str_decode(const char *str, size_t *offset, size_t sz);
+extern char32_t str_decode_reverse(const char *str, size_t *offset, size_t sz);
+extern errno_t chr_encode(char32_t ch, char *str, size_t *offset, size_t sz);
 
 extern size_t str_size(const char *str);
-extern size_t wstr_size(const wchar_t *str);
+extern size_t wstr_size(const char32_t *str);
 
 extern size_t str_nsize(const char *str, size_t max_size);
-extern size_t wstr_nsize(const wchar_t *str, size_t max_size);
+extern size_t wstr_nsize(const char32_t *str, size_t max_size);
 
 extern size_t str_lsize(const char *str, size_t max_len);
-extern size_t wstr_lsize(const wchar_t *str, size_t max_len);
+extern size_t wstr_lsize(const char32_t *str, size_t max_len);
 
 extern size_t str_length(const char *str);
-extern size_t wstr_length(const wchar_t *wstr);
+extern size_t wstr_length(const char32_t *wstr);
 
 extern size_t str_nlength(const char *str, size_t size);
-extern size_t wstr_nlength(const wchar_t *str, size_t size);
+extern size_t wstr_nlength(const char32_t *str, size_t size);
 
-extern size_t chr_width(wchar_t ch);
+extern size_t chr_width(char32_t ch);
 extern size_t str_width(const char *str);
 
-extern bool ascii_check(wchar_t ch);
-extern bool chr_check(wchar_t ch);
+extern bool ascii_check(char32_t ch);
+extern bool chr_check(char32_t ch);
 
 extern int str_cmp(const char *s1, const char *s2);
@@ -98,4 +98,5 @@
 
 extern bool str_test_prefix(const char *s, const char *p);
+extern const char *str_suffix(const char *s, size_t prefix_length);
 
 extern void str_cpy(char *dest, size_t size, const char *src);
@@ -104,21 +105,21 @@
 
 extern errno_t spascii_to_str(char *dest, size_t size, const uint8_t *src, size_t n);
-extern void wstr_to_str(char *dest, size_t size, const wchar_t *src);
-extern char *wstr_to_astr(const wchar_t *src);
-extern void str_to_wstr(wchar_t *dest, size_t dlen, const char *src);
-extern wchar_t *str_to_awstr(const char *src);
+extern void wstr_to_str(char *dest, size_t size, const char32_t *src);
+extern char *wstr_to_astr(const char32_t *src);
+extern void str_to_wstr(char32_t *dest, size_t dlen, const char *src);
+extern char32_t *str_to_awstr(const char *src);
 extern errno_t utf16_to_str(char *dest, size_t size, const uint16_t *src);
 extern errno_t str_to_utf16(uint16_t *dest, size_t dlen, const char *src);
 extern size_t utf16_wsize(const uint16_t *ustr);
 
-extern char *str_chr(const char *str, wchar_t ch);
-extern char *str_rchr(const char *str, wchar_t ch);
+extern char *str_chr(const char *str, char32_t ch);
+extern char *str_rchr(const char *str, char32_t ch);
 extern char *str_str(const char *hs, const char *n);
 
-extern void str_rtrim(char *str, wchar_t ch);
-extern void str_ltrim(char *str, wchar_t ch);
+extern void str_rtrim(char *str, char32_t ch);
+extern void str_ltrim(char *str, char32_t ch);
 
-extern bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos);
-extern bool wstr_remove(wchar_t *str, size_t pos);
+extern bool wstr_linsert(char32_t *str, char32_t ch, size_t pos, size_t max_pos);
+extern bool wstr_remove(char32_t *str, size_t pos);
 
 extern char *str_dup(const char *src);
Index: uspace/lib/c/include/uchar.h
===================================================================
--- uspace/lib/c/include/uchar.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
+++ uspace/lib/c/include/uchar.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2020 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 libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_UCHAR_H_
+#define _LIBC_UCHAR_H_
+
+#include <_bits/uchar.h>
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/test/stdlib.c
===================================================================
--- uspace/lib/c/test/stdlib.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/c/test/stdlib.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -48,6 +48,6 @@
 	(void) sz;
 
-	/* Make sure wchar_t is defined */
-	wchar_t wc = L'\0';
+	/* Make sure char32_t is defined */
+	char32_t wc = L'\0';
 	(void) wc;
 
Index: uspace/lib/clui/tinput.c
===================================================================
--- uspace/lib/clui/tinput.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/clui/tinput.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -113,5 +113,5 @@
 static void tinput_display_tail(tinput_t *ti, size_t start, size_t pad)
 {
-	wchar_t *dbuf = malloc((INPUT_MAX_SIZE + 1) * sizeof(wchar_t));
+	char32_t *dbuf = malloc((INPUT_MAX_SIZE + 1) * sizeof(char32_t));
 	if (!dbuf)
 		return;
@@ -126,5 +126,5 @@
 	size_t p = start;
 	if (p < sa) {
-		memcpy(dbuf, ti->buffer + p, (sa - p) * sizeof(wchar_t));
+		memcpy(dbuf, ti->buffer + p, (sa - p) * sizeof(char32_t));
 		dbuf[sa - p] = '\0';
 		printf("%ls", dbuf);
@@ -137,5 +137,5 @@
 
 		memcpy(dbuf, ti->buffer + p,
-		    (sb - p) * sizeof(wchar_t));
+		    (sb - p) * sizeof(char32_t));
 		dbuf[sb - p] = '\0';
 		printf("%ls", dbuf);
@@ -148,5 +148,5 @@
 	if (p < ti->nc) {
 		memcpy(dbuf, ti->buffer + p,
-		    (ti->nc - p) * sizeof(wchar_t));
+		    (ti->nc - p) * sizeof(char32_t));
 		dbuf[ti->nc - p] = '\0';
 		printf("%ls", dbuf);
@@ -154,5 +154,5 @@
 
 	for (p = 0; p < pad; p++)
-		putwchar(' ');
+		putuchar(' ');
 
 	console_flush(ti->console);
@@ -192,5 +192,5 @@
 	tinput_console_set_lpos(ti, ti->text_coord + ti->nc);
 	console_flush(ti->console);
-	putwchar('\n');
+	putuchar('\n');
 }
 
@@ -212,5 +212,5 @@
 }
 
-static void tinput_insert_char(tinput_t *ti, wchar_t c)
+static void tinput_insert_char(tinput_t *ti, char32_t c)
 {
 	if (ti->nc == INPUT_MAX_SIZE)
@@ -263,5 +263,5 @@
 	size_t i = 0;
 	while (i < ilen) {
-		wchar_t c = str_decode(str, &off, STR_NO_LIMIT);
+		char32_t c = str_decode(str, &off, STR_NO_LIMIT);
 		if (c == '\0')
 			break;
@@ -506,5 +506,5 @@
 
 	memmove(ti->buffer + sa, ti->buffer + sb,
-	    (ti->nc - sb) * sizeof(wchar_t));
+	    (ti->nc - sb) * sizeof(char32_t));
 
 	ti->pos = ti->sel_start = sa;
@@ -526,5 +526,5 @@
 
 	if (sb < ti->nc) {
-		wchar_t tmp_c = ti->buffer[sb];
+		char32_t tmp_c = ti->buffer[sb];
 		ti->buffer[sb] = '\0';
 		str = wstr_to_astr(ti->buffer + sa);
@@ -602,5 +602,5 @@
 	size_t i;
 	size_t a_off, b_off;
-	wchar_t ca, cb;
+	char32_t ca, cb;
 
 	i = 0;
@@ -704,9 +704,11 @@
 			/* Extend array */
 			compl_len = 2 * compl_len;
-			compl = realloc(compl, compl_len * sizeof(char *));
-			if (compl == NULL) {
+			char **temp = realloc(compl, compl_len * sizeof(char *));
+			if (temp == NULL) {
+				free(compl);
 				printf("Error: Out of memory.\n");
 				break;
 			}
+			compl = temp;
 		}
 
Index: uspace/lib/clui/tinput.h
===================================================================
--- uspace/lib/clui/tinput.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/clui/tinput.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -63,5 +63,5 @@
  * @return		EOK on success, error code on failure.
  */
-typedef errno_t (*tinput_compl_init_fn)(wchar_t *text, size_t pos, size_t *cstart,
+typedef errno_t (*tinput_compl_init_fn)(char32_t *text, size_t pos, size_t *cstart,
     void **state);
 
@@ -111,5 +111,5 @@
 
 	/** Buffer holding text currently being edited */
-	wchar_t buffer[INPUT_MAX_SIZE + 1];
+	char32_t buffer[INPUT_MAX_SIZE + 1];
 
 	/** Linear position on screen where the prompt starts */
Index: uspace/lib/ddev/src/ddev.c
===================================================================
--- uspace/lib/ddev/src/ddev.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/ddev/src/ddev.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -95,9 +95,14 @@
 	exch = async_exchange_begin(ddev->sess);
 	rc = async_req_0_2(exch, DDEV_GET_GC, &arg2, &arg3);
-	sess = async_connect_me_to(exch, INTERFACE_GC, arg2, arg3);
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		return rc;
+	}
+
+	sess = async_connect_me_to(exch, INTERFACE_GC, arg2, arg3, &rc);
 	async_exchange_end(exch);
 
 	if (sess == NULL)
-		return EIO;
+		return rc;
 
 	rc = ipc_gc_create(sess, &gc);
Index: uspace/lib/display/src/display.c
===================================================================
--- uspace/lib/display/src/display.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/display/src/display.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -218,4 +218,5 @@
  * @param window Window
  * @param rgc Place to store pointer to new graphics context
+ * @return EOK on success or an error code
  */
 errno_t display_window_get_gc(display_window_t *window, gfx_context_t **rgc)
@@ -227,8 +228,8 @@
 
 	exch = async_exchange_begin(window->display->sess);
-	sess = async_connect_me_to(exch, INTERFACE_GC, 0, window->id);
+	sess = async_connect_me_to(exch, INTERFACE_GC, 0, window->id, &rc);
 	if (sess == NULL) {
 		async_exchange_end(exch);
-		return EIO;
+		return rc;
 	}
 
Index: uspace/lib/draw/font.c
===================================================================
--- uspace/lib/draw/font.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/draw/font.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -64,5 +64,5 @@
 }
 
-errno_t font_resolve_glyph(font_t *font, wchar_t c, glyph_id_t *glyph_id)
+errno_t font_resolve_glyph(font_t *font, char32_t c, glyph_id_t *glyph_id)
 {
 	return font->backend->resolve_glyph(font->backend_data, c, glyph_id);
@@ -95,5 +95,5 @@
 	size_t off = 0;
 	while (true) {
-		wchar_t c = str_decode(text, &off, STR_NO_LIMIT);
+		char32_t c = str_decode(text, &off, STR_NO_LIMIT);
 		if (c == 0)
 			break;
@@ -138,5 +138,5 @@
 	size_t off = 0;
 	while (true) {
-		wchar_t c = str_decode(text, &off, STR_NO_LIMIT);
+		char32_t c = str_decode(text, &off, STR_NO_LIMIT);
 		if (c == 0)
 			break;
Index: uspace/lib/draw/font/bitmap_backend.c
===================================================================
--- uspace/lib/draw/font/bitmap_backend.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/draw/font/bitmap_backend.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -67,5 +67,5 @@
 }
 
-static errno_t bb_resolve_glyph(void *backend_data, wchar_t c, glyph_id_t *glyph_id)
+static errno_t bb_resolve_glyph(void *backend_data, char32_t c, glyph_id_t *glyph_id)
 {
 	bitmap_backend_data_t *data = (bitmap_backend_data_t *) backend_data;
Index: uspace/lib/draw/font/embedded.c
===================================================================
--- uspace/lib/draw/font/embedded.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/draw/font/embedded.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -43,5 +43,5 @@
 #include <draw/drawctx.h>
 
-static errno_t fde_resolve_glyph(void *unused, const wchar_t chr,
+static errno_t fde_resolve_glyph(void *unused, const char32_t chr,
     glyph_id_t *glyph_id)
 {
Index: uspace/lib/draw/font/pcf.c
===================================================================
--- uspace/lib/draw/font/pcf.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/draw/font/pcf.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -143,5 +143,5 @@
 }
 
-static errno_t pcf_resolve_glyph(void *opaque_data, const wchar_t chr,
+static errno_t pcf_resolve_glyph(void *opaque_data, const char32_t chr,
     glyph_id_t *glyph_id)
 {
Index: uspace/lib/draw/gfx/font-8x16.c
===================================================================
--- uspace/lib/draw/gfx/font-8x16.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/draw/gfx/font-8x16.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -47,5 +47,5 @@
  *
  */
-uint16_t fb_font_glyph(const wchar_t ch, bool *found)
+uint16_t fb_font_glyph(const char32_t ch, bool *found)
 {
 	if (found)
Index: uspace/lib/draw/include/draw/font.h
===================================================================
--- uspace/lib/draw/include/draw/font.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/draw/include/draw/font.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -97,5 +97,5 @@
 typedef struct {
 	errno_t (*get_font_metrics)(void *, font_metrics_t *);
-	errno_t (*resolve_glyph)(void *, wchar_t, glyph_id_t *);
+	errno_t (*resolve_glyph)(void *, char32_t, glyph_id_t *);
 	errno_t (*get_glyph_metrics)(void *, glyph_id_t, glyph_metrics_t *);
 	errno_t (*render_glyph)(void *, drawctx_t *, source_t *, sysarg_t,
@@ -110,5 +110,5 @@
 
 typedef struct {
-	errno_t (*resolve_glyph)(void *, const wchar_t, glyph_id_t *);
+	errno_t (*resolve_glyph)(void *, const char32_t, glyph_id_t *);
 	errno_t (*load_glyph_surface)(void *, glyph_id_t, surface_t **);
 	errno_t (*load_glyph_metrics)(void *, glyph_id_t, glyph_metrics_t *);
@@ -118,5 +118,5 @@
 extern font_t *font_create(font_backend_t *, void *);
 extern errno_t font_get_metrics(font_t *, font_metrics_t *);
-extern errno_t font_resolve_glyph(font_t *, wchar_t, glyph_id_t *);
+extern errno_t font_resolve_glyph(font_t *, char32_t, glyph_id_t *);
 extern errno_t font_get_glyph_metrics(font_t *, glyph_id_t, glyph_metrics_t *);
 extern errno_t font_render_glyph(font_t *, drawctx_t *, source_t *,
Index: uspace/lib/draw/include/draw/gfx.h
===================================================================
--- uspace/lib/draw/include/draw/gfx.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/draw/include/draw/gfx.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -40,4 +40,5 @@
 #include <stdbool.h>
 #include <stddef.h>
+#include <uchar.h>
 
 #define CURSOR_WIDTH   11
@@ -52,5 +53,5 @@
 extern uint8_t cursor_mask[];
 
-extern uint16_t fb_font_glyph(const wchar_t, bool *);
+extern uint16_t fb_font_glyph(const char32_t, bool *);
 extern uint8_t fb_font[FONT_GLYPHS][FONT_SCANLINES];
 
Index: uspace/lib/ext4/src/superblock.c
===================================================================
--- uspace/lib/ext4/src/superblock.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/ext4/src/superblock.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -889,5 +889,5 @@
 	size_t i;
 	size_t wi;
-	wchar_t ch;
+	char32_t ch;
 	errno_t rc;
 
@@ -896,5 +896,5 @@
 	while (sb->volume_name[i] != '\0' && i < sizeof(sb->volume_name)) {
 		/* ISO 8859-1 codes map to identical Unicode code points */
-		ch = (wchar_t)(uint8_t)sb->volume_name[i];
+		ch = (char32_t)(uint8_t)sb->volume_name[i];
 		rc = chr_encode(ch, buf, &wi, bufsz - 1);
 		if (rc != EOK)
@@ -917,5 +917,5 @@
 {
 	size_t off;
-	wchar_t ch;
+	char32_t ch;
 	size_t wi;
 
Index: uspace/lib/fmtutil/fmtutil.c
===================================================================
--- uspace/lib/fmtutil/fmtutil.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/fmtutil/fmtutil.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -62,8 +62,8 @@
 
 /** Line consumer that prints the lines aligned according to spec */
-static errno_t print_line(wchar_t *wstr, size_t chars, bool last, void *data)
+static errno_t print_line(char32_t *wstr, size_t chars, bool last, void *data)
 {
 	printmode_t *pm = (printmode_t *) data;
-	wchar_t old_char = wstr[chars];
+	char32_t old_char = wstr[chars];
 	wstr[chars] = 0;
 	errno_t rc = print_aligned_w(wstr, pm->width, last, pm->alignment);
@@ -78,5 +78,5 @@
 	pm.newline_always = false;
 	pm.width = width;
-	wchar_t *wstr = str_to_awstr(str);
+	char32_t *wstr = str_to_awstr(str);
 	if (wstr == NULL) {
 		return ENOMEM;
@@ -87,5 +87,5 @@
 }
 
-errno_t print_aligned_w(const wchar_t *wstr, size_t width, bool last,
+errno_t print_aligned_w(const char32_t *wstr, size_t width, bool last,
     align_mode_t mode)
 {
@@ -95,14 +95,14 @@
 		for (i = 0; i < width; i++) {
 			if (i < len)
-				putwchar(wstr[i]);
+				putuchar(wstr[i]);
 			else
-				putwchar(' ');
+				putuchar(' ');
 		}
 	} else if (mode == ALIGN_RIGHT) {
 		for (i = 0; i < width; i++) {
 			if (i < width - len)
-				putwchar(' ');
+				putuchar(' ');
 			else
-				putwchar(wstr[i - (width - len)]);
+				putuchar(wstr[i - (width - len)]);
 		}
 	} else if (mode == ALIGN_CENTER) {
@@ -110,7 +110,7 @@
 		for (i = 0; i < width; i++) {
 			if ((i < padding) || ((i - padding) >= len))
-				putwchar(' ');
+				putuchar(' ');
 			else
-				putwchar(wstr[i - padding]);
+				putuchar(wstr[i - padding]);
 		}
 	} else if (mode == ALIGN_JUSTIFY) {
@@ -146,10 +146,10 @@
 				    (words - 1)));
 				for (j = 0; j < spaces; j++) {
-					putwchar(' ');
+					putuchar(' ');
 				}
 				done_chars += spaces;
 			}
 			while (i < len && wstr[i] != ' ') {
-				putwchar(wstr[i++]);
+				putuchar(wstr[i++]);
 				done_chars++;
 			}
@@ -158,5 +158,5 @@
 	skip_words:
 		while (done_chars < width) {
-			putwchar(' ');
+			putuchar(' ');
 			done_chars++;
 		}
@@ -169,5 +169,5 @@
 errno_t print_aligned(const char *str, size_t width, bool last, align_mode_t mode)
 {
-	wchar_t *wstr = str_to_awstr(str);
+	char32_t *wstr = str_to_awstr(str);
 	if (wstr == NULL) {
 		return ENOMEM;
@@ -178,5 +178,5 @@
 }
 
-errno_t wrap(wchar_t *wstr, size_t width, line_consumer_fn consumer, void *data)
+errno_t wrap(char32_t *wstr, size_t width, line_consumer_fn consumer, void *data)
 {
 	size_t word_start = 0;
Index: uspace/lib/fmtutil/fmtutil.h
===================================================================
--- uspace/lib/fmtutil/fmtutil.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/fmtutil/fmtutil.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -44,7 +44,7 @@
  * @returns EOK on success or an error code on failure
  */
-typedef errno_t (*line_consumer_fn)(wchar_t *, size_t, bool, void *);
+typedef errno_t (*line_consumer_fn)(char32_t *, size_t, bool, void *);
 
-extern errno_t print_aligned_w(const wchar_t *, size_t, bool, align_mode_t);
+extern errno_t print_aligned_w(const char32_t *, size_t, bool, align_mode_t);
 extern errno_t print_aligned(const char *, size_t, bool, align_mode_t);
 extern errno_t print_wrapped(const char *, size_t, align_mode_t);
@@ -58,3 +58,3 @@
  * @param data user data to pass to the consumer function
  */
-extern errno_t wrap(wchar_t *, size_t, line_consumer_fn, void *);
+extern errno_t wrap(char32_t *, size_t, line_consumer_fn, void *);
Index: uspace/lib/gui/terminal.c
===================================================================
--- uspace/lib/gui/terminal.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/gui/terminal.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -420,5 +420,5 @@
 			if (event->type == CEV_KEY && event->ev.key.type == KEY_PRESS &&
 			    event->ev.key.c != 0) {
-				wchar_t tmp[2] = {
+				char32_t tmp[2] = {
 					event->ev.key.c,
 					0
@@ -437,5 +437,5 @@
 }
 
-static void term_write_char(terminal_t *term, wchar_t ch)
+static void term_write_char(terminal_t *term, char32_t ch)
 {
 	sysarg_t updated = 0;
@@ -456,5 +456,5 @@
 		break;
 	default:
-		updated = chargrid_putwchar(term->frontbuf, ch, true);
+		updated = chargrid_putuchar(term->frontbuf, ch, true);
 	}
 
Index: uspace/lib/label/src/mbr.c
===================================================================
--- uspace/lib/label/src/mbr.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/label/src/mbr.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -328,6 +328,8 @@
 
 	label = calloc(1, sizeof(label_t));
-	if (label == NULL)
-		return ENOMEM;
+	if (label == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
 
 	list_initialize(&label->parts);
Index: uspace/lib/nic/src/nic_impl.c
===================================================================
--- uspace/lib/nic/src/nic_impl.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/nic/src/nic_impl.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -554,4 +554,6 @@
 	if (nic_data->wol_virtues.caps_max[type] < 0) {
 		fibril_rwlock_write_unlock(&nic_data->wv_lock);
+		free(virtue->data);
+		free(virtue);
 		return EINVAL;
 	}
@@ -559,4 +561,6 @@
 	    nic_data->wol_virtues.caps_max[type]) {
 		fibril_rwlock_write_unlock(&nic_data->wv_lock);
+		free(virtue->data);
+		free(virtue);
 		return ELIMIT;
 	}
Index: uspace/lib/posix/src/stdio.c
===================================================================
--- uspace/lib/posix/src/stdio.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/posix/src/stdio.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -249,5 +249,5 @@
  * @return The number of written characters.
  */
-static int _dprintf_wstr_write(const wchar_t *str, size_t size, void *fd)
+static int _dprintf_wstr_write(const char32_t *str, size_t size, void *fd)
 {
 	size_t offset = 0;
@@ -268,5 +268,5 @@
 
 		chars++;
-		offset += sizeof(wchar_t);
+		offset += sizeof(char32_t);
 	}
 
Index: uspace/lib/usbdev/src/request.c
===================================================================
--- uspace/lib/usbdev/src/request.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/usbdev/src/request.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -756,5 +756,5 @@
 	/* Prepare dynamically allocated variables. */
 	uint8_t *string = NULL;
-	wchar_t *string_chars = NULL;
+	char32_t *string_chars = NULL;
 
 	/* Get the actual descriptor. */
@@ -783,5 +783,5 @@
 
 	const size_t string_char_count = string_size / 2;
-	string_chars = malloc(sizeof(wchar_t) * (string_char_count + 1));
+	string_chars = malloc(sizeof(char32_t) * (string_char_count + 1));
 	if (string_chars == NULL) {
 		rc = ENOMEM;
Index: uspace/lib/usbhid/src/hiddescriptor.c
===================================================================
--- uspace/lib/usbhid/src/hiddescriptor.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/usbhid/src/hiddescriptor.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -366,4 +366,5 @@
 	/* usage path context initialization */
 	if (!(usage_path = usb_hid_report_path())) {
+		free(report_item);
 		return ENOMEM;
 	}
Index: uspace/lib/virtio/virtio.c
===================================================================
--- uspace/lib/virtio/virtio.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/lib/virtio/virtio.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -35,4 +35,5 @@
 #include <align.h>
 #include <macros.h>
+#include <stdalign.h>
 
 #include <ddf/log.h>
@@ -230,9 +231,9 @@
 	 */
 	size_t mem_size = sizeof(virtq_desc_t[size]);
-	mem_size = ALIGN_UP(mem_size, _Alignof(virtq_avail_t));
+	mem_size = ALIGN_UP(mem_size, alignof(virtq_avail_t));
 	avail_offset = mem_size;
 	mem_size += sizeof(virtq_avail_t) + sizeof(ioport16_t[size]) +
 	    sizeof(ioport16_t);
-	mem_size = ALIGN_UP(mem_size, _Alignof(virtq_used_t));
+	mem_size = ALIGN_UP(mem_size, alignof(virtq_used_t));
 	used_offset = mem_size;
 	mem_size += sizeof(virtq_used_t) + sizeof(virtq_used_elem_t[size]) +
Index: uspace/srv/fs/cdfs/cdfs.c
===================================================================
--- uspace/srv/fs/cdfs/cdfs.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/fs/cdfs/cdfs.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -75,12 +75,13 @@
 	}
 
+	errno_t rc;
 	async_sess_t *vfs_sess = service_connect_blocking(SERVICE_VFS,
-	    INTERFACE_VFS_DRIVER, 0);
+	    INTERFACE_VFS_DRIVER, 0, &rc);
 	if (!vfs_sess) {
-		printf("%s: Unable to connect to VFS\n", NAME);
+		printf("%s: Unable to connect to VFS: %s\n", NAME, str_error(rc));
 		return -1;
 	}
 
-	errno_t rc = fs_register(vfs_sess, &cdfs_vfs_info, &cdfs_ops,
+	rc = fs_register(vfs_sess, &cdfs_vfs_info, &cdfs_ops,
 	    &cdfs_libfs_ops);
 	if (rc != EOK) {
Index: uspace/srv/fs/exfat/exfat.c
===================================================================
--- uspace/srv/fs/exfat/exfat.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/fs/exfat/exfat.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -77,7 +77,7 @@
 
 	async_sess_t *vfs_sess = service_connect_blocking(SERVICE_VFS,
-	    INTERFACE_VFS_DRIVER, 0);
+	    INTERFACE_VFS_DRIVER, 0, &rc);
 	if (!vfs_sess) {
-		printf(NAME ": failed to connect to VFS\n");
+		printf(NAME ": failed to connect to VFS: %s\n", str_error(rc));
 		return -1;
 	}
Index: uspace/srv/fs/exfat/exfat_dentry.c
===================================================================
--- uspace/srv/fs/exfat/exfat_dentry.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/fs/exfat/exfat_dentry.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -110,5 +110,5 @@
 }
 
-bool exfat_valid_char(wchar_t ch)
+bool exfat_valid_char(char32_t ch)
 {
 	if (ch >= 0x01 && ch <= 0x1F)
@@ -134,5 +134,5 @@
 {
 	size_t off = 0;
-	wchar_t ch;
+	char32_t ch;
 
 	while ((ch = str_decode(name, &off, STR_NO_LIMIT)) != 0) {
Index: uspace/srv/fs/exfat/exfat_dentry.h
===================================================================
--- uspace/srv/fs/exfat/exfat_dentry.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/fs/exfat/exfat_dentry.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -37,4 +37,5 @@
 #include <stdint.h>
 #include <stdbool.h>
+#include <uchar.h>
 
 #define EXFAT_FILENAME_LEN	255
@@ -156,5 +157,5 @@
     uint16_t *);
 
-extern bool exfat_valid_char(wchar_t);
+extern bool exfat_valid_char(char32_t);
 extern bool exfat_valid_name(const char *);
 
Index: uspace/srv/fs/ext4fs/ext4fs.c
===================================================================
--- uspace/srv/fs/ext4fs/ext4fs.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/fs/ext4fs/ext4fs.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -43,4 +43,5 @@
 #include <ipc/services.h>
 #include <str.h>
+#include <str_error.h>
 #include "ext4/ops.h"
 #include "../../vfs/vfs.h"
@@ -66,14 +67,16 @@
 	}
 
+	errno_t rc;
 	async_sess_t *vfs_sess = service_connect_blocking(SERVICE_VFS,
-	    INTERFACE_VFS_DRIVER, 0);
+	    INTERFACE_VFS_DRIVER, 0, &rc);
 	if (!vfs_sess) {
-		printf("%s: Failed to connect to VFS\n", NAME);
+		printf("%s: Failed to connect to VFS: %s\n", NAME, str_error(rc));
 		return 2;
 	}
 
-	errno_t rc = ext4_global_init();
+	rc = ext4_global_init();
 	if (rc != EOK) {
-		printf("%s: Global initialization failed\n", NAME);
+		printf("%s: Global initialization failed: %s\n", NAME,
+		    str_error(rc));
 		return rc;
 	}
@@ -82,5 +85,6 @@
 	    &ext4_libfs_ops);
 	if (rc != EOK) {
-		printf("%s: Failed to register file system\n", NAME);
+		printf("%s: Failed to register file system: %s\n", NAME,
+		    str_error(rc));
 		return rc;
 	}
Index: uspace/srv/fs/fat/fat.c
===================================================================
--- uspace/srv/fs/fat/fat.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/fs/fat/fat.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -77,7 +77,7 @@
 
 	async_sess_t *vfs_sess = service_connect_blocking(SERVICE_VFS,
-	    INTERFACE_VFS_DRIVER, 0);
+	    INTERFACE_VFS_DRIVER, 0, &rc);
 	if (!vfs_sess) {
-		printf(NAME ": failed to connect to VFS\n");
+		printf(NAME ": failed to connect to VFS: %s\n", str_error(rc));
 		return -1;
 	}
Index: uspace/srv/fs/fat/fat_dentry.c
===================================================================
--- uspace/srv/fs/fat/fat_dentry.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/fs/fat/fat_dentry.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -360,5 +360,5 @@
 void str_to_ascii(char *dst, const char *src, size_t count, uint8_t pad)
 {
-	wchar_t ch;
+	char32_t ch;
 	size_t off = 0;
 	size_t i = 0;
@@ -381,5 +381,5 @@
 bool fat_valid_name(const char *name)
 {
-	wchar_t ch;
+	char32_t ch;
 	size_t offset = 0;
 	bool result = true;
Index: uspace/srv/fs/locfs/locfs.c
===================================================================
--- uspace/srv/fs/locfs/locfs.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/fs/locfs/locfs.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -78,12 +78,13 @@
 	}
 
+	errno_t rc;
 	async_sess_t *vfs_sess = service_connect_blocking(SERVICE_VFS,
-	    INTERFACE_VFS_DRIVER, 0);
+	    INTERFACE_VFS_DRIVER, 0, &rc);
 	if (!vfs_sess) {
-		printf("%s: Unable to connect to VFS\n", NAME);
+		printf("%s: Unable to connect to VFS: %s\n", NAME, str_error(rc));
 		return -1;
 	}
 
-	errno_t rc = fs_register(vfs_sess, &locfs_vfs_info, &locfs_ops,
+	rc = fs_register(vfs_sess, &locfs_vfs_info, &locfs_ops,
 	    &locfs_libfs_ops);
 	if (rc != EOK) {
Index: uspace/srv/fs/mfs/mfs.c
===================================================================
--- uspace/srv/fs/mfs/mfs.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/fs/mfs/mfs.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -74,8 +74,7 @@
 
 	async_sess_t *vfs_sess = service_connect_blocking(SERVICE_VFS,
-	    INTERFACE_VFS_DRIVER, 0);
-
+	    INTERFACE_VFS_DRIVER, 0, &rc);
 	if (!vfs_sess) {
-		printf(NAME ": failed to connect to VFS\n");
+		printf(NAME ": failed to connect to VFS: %s\n", str_error(rc));
 		rc = errno;
 		goto err;
Index: uspace/srv/fs/tmpfs/tmpfs.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/fs/tmpfs/tmpfs.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -80,12 +80,13 @@
 	}
 
+	errno_t rc;
 	async_sess_t *vfs_sess = service_connect_blocking(SERVICE_VFS,
-	    INTERFACE_VFS_DRIVER, 0);
+	    INTERFACE_VFS_DRIVER, 0, &rc);
 	if (!vfs_sess) {
-		printf("%s: Unable to connect to VFS\n", NAME);
+		printf("%s: Unable to connect to VFS: %s\n", NAME, str_error(rc));
 		return -1;
 	}
 
-	errno_t rc = fs_register(vfs_sess, &tmpfs_vfs_info, &tmpfs_ops,
+	rc = fs_register(vfs_sess, &tmpfs_vfs_info, &tmpfs_ops,
 	    &tmpfs_libfs_ops);
 	if (rc != EOK) {
Index: uspace/srv/fs/udf/udf.c
===================================================================
--- uspace/srv/fs/udf/udf.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/fs/udf/udf.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -73,12 +73,14 @@
 	}
 
+	errno_t rc;
 	async_sess_t *vfs_sess =
-	    service_connect_blocking(SERVICE_VFS, INTERFACE_VFS_DRIVER, 0);
+	    service_connect_blocking(SERVICE_VFS, INTERFACE_VFS_DRIVER, 0, &rc);
 	if (!vfs_sess) {
-		log_msg(LOG_DEFAULT, LVL_FATAL, "Failed to connect to VFS");
+		log_msg(LOG_DEFAULT, LVL_FATAL, "Failed to connect to VFS: %s",
+		    str_error(rc));
 		return 2;
 	}
 
-	errno_t rc = fs_register(vfs_sess, &udf_vfs_info, &udf_ops,
+	rc = fs_register(vfs_sess, &udf_vfs_info, &udf_ops,
 	    &udf_libfs_ops);
 	if (rc != EOK)
Index: uspace/srv/fs/udf/udf_ops.c
===================================================================
--- uspace/srv/fs/udf/udf_ops.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/fs/udf/udf_ops.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -328,6 +328,8 @@
 	/* initialize block cache */
 	errno_t rc = block_init(service_id, MAX_SIZE);
-	if (rc != EOK)
-		return rc;
+	if (rc != EOK) {
+		free(instance);
+		return rc;
+	}
 
 	rc = fs_instance_create(service_id, instance);
Index: uspace/srv/hid/console/console.c
===================================================================
--- uspace/srv/hid/console/console.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/hid/console/console.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -105,5 +105,5 @@
 static errno_t input_ev_active(input_t *);
 static errno_t input_ev_deactive(input_t *);
-static errno_t input_ev_key(input_t *, kbd_event_type_t, keycode_t, keymod_t, wchar_t);
+static errno_t input_ev_key(input_t *, kbd_event_type_t, keycode_t, keymod_t, char32_t);
 static errno_t input_ev_move(input_t *, int, int);
 static errno_t input_ev_abs_move(input_t *, unsigned, unsigned, unsigned, unsigned);
@@ -250,5 +250,5 @@
 
 static errno_t input_ev_key(input_t *input, kbd_event_type_t type, keycode_t key,
-    keymod_t mods, wchar_t c)
+    keymod_t mods, char32_t c)
 {
 	if ((key >= KC_F1) && (key <= KC_F1 + CONSOLE_COUNT) &&
@@ -293,5 +293,5 @@
 
 /** Process a character from the client (TTY emulation). */
-static void cons_write_char(console_t *cons, wchar_t ch)
+static void cons_write_char(console_t *cons, char32_t ch)
 {
 	sysarg_t updated = 0;
@@ -312,5 +312,5 @@
 		break;
 	default:
-		updated = chargrid_putwchar(cons->frontbuf, ch, true);
+		updated = chargrid_putuchar(cons->frontbuf, ch, true);
 	}
 
@@ -371,5 +371,5 @@
 			/* Accept key presses of printable chars only. */
 			if ((event->type == KEY_PRESS) && (event->c != 0)) {
-				wchar_t tmp[2] = { event->c, 0 };
+				char32_t tmp[2] = { event->c, 0 };
 				wstr_to_str(cons->char_remains, UTF8_CHAR_BUFFER_SIZE, tmp);
 				cons->char_remains_len = str_size(cons->char_remains);
Index: uspace/srv/hid/display/input.c
===================================================================
--- uspace/srv/hid/display/input.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/hid/display/input.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -34,4 +34,5 @@
 
 #include <errno.h>
+#include <inttypes.h>
 #include <io/input.h>
 #include <io/log.h>
@@ -44,5 +45,5 @@
 static errno_t ds_input_ev_active(input_t *);
 static errno_t ds_input_ev_deactive(input_t *);
-static errno_t ds_input_ev_key(input_t *, kbd_event_type_t, keycode_t, keymod_t, wchar_t);
+static errno_t ds_input_ev_key(input_t *, kbd_event_type_t, keycode_t, keymod_t, char32_t);
 static errno_t ds_input_ev_move(input_t *, int, int);
 static errno_t ds_input_ev_abs_move(input_t *, unsigned, unsigned, unsigned, unsigned);
@@ -69,5 +70,5 @@
 
 static errno_t ds_input_ev_key(input_t *input, kbd_event_type_t type,
-    keycode_t key, keymod_t mods, wchar_t c)
+    keycode_t key, keymod_t mods, char32_t c)
 {
 	ds_display_t *disp = (ds_display_t *) input->user;
Index: uspace/srv/hid/input/layout.c
===================================================================
--- uspace/srv/hid/input/layout.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/hid/input/layout.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -69,5 +69,5 @@
 
 /** Parse keyboard event. */
-wchar_t layout_parse_ev(layout_t *layout, kbd_event_t *ev)
+char32_t layout_parse_ev(layout_t *layout, kbd_event_t *ev)
 {
 	return (*layout->ops->parse_ev)(layout, ev);
Index: uspace/srv/hid/input/layout.h
===================================================================
--- uspace/srv/hid/input/layout.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/hid/input/layout.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -53,5 +53,5 @@
 	errno_t (*create)(layout_t *);
 	void (*destroy)(layout_t *);
-	wchar_t (*parse_ev)(layout_t *, kbd_event_t *);
+	char32_t (*parse_ev)(layout_t *, kbd_event_t *);
 } layout_ops_t;
 
@@ -64,5 +64,5 @@
 extern layout_t *layout_create(layout_ops_t *);
 extern void layout_destroy(layout_t *);
-extern wchar_t layout_parse_ev(layout_t *, kbd_event_t *);
+extern char32_t layout_parse_ev(layout_t *, kbd_event_t *);
 
 #endif
Index: uspace/srv/hid/input/layout/ar.c
===================================================================
--- uspace/srv/hid/input/layout/ar.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/hid/input/layout/ar.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -44,5 +44,5 @@
 static errno_t ar_create(layout_t *);
 static void ar_destroy(layout_t *);
-static wchar_t ar_parse_ev(layout_t *, kbd_event_t *ev);
+static char32_t ar_parse_ev(layout_t *, kbd_event_t *ev);
 
 layout_ops_t ar_ops = {
@@ -52,5 +52,5 @@
 };
 
-static wchar_t map_not_shifted[] = {
+static char32_t map_not_shifted[] = {
 	[KC_BACKTICK] = L'ذ',
 
@@ -110,5 +110,5 @@
 };
 
-static wchar_t map_shifted[] = {
+static char32_t map_shifted[] = {
 	[KC_BACKTICK] = L'ّ',
 
@@ -168,5 +168,5 @@
 };
 
-static wchar_t map_neutral[] = {
+static char32_t map_neutral[] = {
 	[KC_BACKSPACE] = '\b',
 	[KC_TAB] = '\t',
@@ -181,5 +181,5 @@
 };
 
-static wchar_t map_numeric[] = {
+static char32_t map_numeric[] = {
 	[KC_N7] = '7',
 	[KC_N8] = '8',
@@ -196,5 +196,5 @@
 };
 
-static wchar_t translate(unsigned int key, wchar_t *map, size_t map_length)
+static char32_t translate(unsigned int key, char32_t *map, size_t map_length)
 {
 	if (key >= map_length)
@@ -212,7 +212,7 @@
 }
 
-static wchar_t ar_parse_ev(layout_t *state, kbd_event_t *ev)
-{
-	wchar_t c;
+static char32_t ar_parse_ev(layout_t *state, kbd_event_t *ev)
+{
+	char32_t c;
 
 	/* Produce no characters when Ctrl or Alt is pressed. */
@@ -220,12 +220,12 @@
 		return 0;
 
-	c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(wchar_t));
+	c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(char32_t));
 	if (c != 0)
 		return c;
 
 	if ((ev->mods & KM_SHIFT) != 0)
-		c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(wchar_t));
+		c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(char32_t));
 	else
-		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(wchar_t));
+		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(char32_t));
 
 	if (c != 0)
@@ -233,5 +233,5 @@
 
 	if ((ev->mods & KM_NUM_LOCK) != 0)
-		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(wchar_t));
+		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(char32_t));
 	else
 		c = 0;
Index: uspace/srv/hid/input/layout/cz.c
===================================================================
--- uspace/srv/hid/input/layout/cz.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/hid/input/layout/cz.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -45,5 +45,5 @@
 static errno_t cz_create(layout_t *);
 static void cz_destroy(layout_t *);
-static wchar_t cz_parse_ev(layout_t *, kbd_event_t *ev);
+static char32_t cz_parse_ev(layout_t *, kbd_event_t *ev);
 
 enum m_state {
@@ -63,5 +63,5 @@
 };
 
-static wchar_t map_lcase[] = {
+static char32_t map_lcase[] = {
 	[KC_Q] = 'q',
 	[KC_W] = 'w',
@@ -94,5 +94,5 @@
 };
 
-static wchar_t map_ucase[] = {
+static char32_t map_ucase[] = {
 	[KC_Q] = 'Q',
 	[KC_W] = 'W',
@@ -125,5 +125,5 @@
 };
 
-static wchar_t map_not_shifted[] = {
+static char32_t map_not_shifted[] = {
 	[KC_BACKTICK] = ';',
 
@@ -141,5 +141,5 @@
 };
 
-static wchar_t map_shifted[] = {
+static char32_t map_shifted[] = {
 	[KC_1] = '1',
 	[KC_2] = '2',
@@ -167,5 +167,5 @@
 };
 
-static wchar_t map_ns_nocaps[] = {
+static char32_t map_ns_nocaps[] = {
 	[KC_2] = L'ě',
 	[KC_3] = L'š',
@@ -182,5 +182,5 @@
 };
 
-static wchar_t map_ns_caps[] = {
+static char32_t map_ns_caps[] = {
 	[KC_2] = L'Ě',
 	[KC_3] = L'Š',
@@ -197,5 +197,5 @@
 };
 
-static wchar_t map_neutral[] = {
+static char32_t map_neutral[] = {
 	[KC_BACKSPACE] = '\b',
 	[KC_TAB] = '\t',
@@ -210,5 +210,5 @@
 };
 
-static wchar_t map_numeric[] = {
+static char32_t map_numeric[] = {
 	[KC_N7] = '7',
 	[KC_N8] = '8',
@@ -225,5 +225,5 @@
 };
 
-static wchar_t map_hacek_lcase[] = {
+static char32_t map_hacek_lcase[] = {
 	[KC_E] = L'ě',
 	[KC_R] = L'ř',
@@ -239,5 +239,5 @@
 };
 
-static wchar_t map_hacek_ucase[] = {
+static char32_t map_hacek_ucase[] = {
 	[KC_E] = L'Ě',
 	[KC_R] = L'Ř',
@@ -253,5 +253,5 @@
 };
 
-static wchar_t map_carka_lcase[] = {
+static char32_t map_carka_lcase[] = {
 	[KC_E] = L'é',
 	[KC_U] = L'ú',
@@ -264,5 +264,5 @@
 };
 
-static wchar_t map_carka_ucase[] = {
+static char32_t map_carka_ucase[] = {
 	[KC_E] = L'É',
 	[KC_U] = L'Ú',
@@ -275,5 +275,5 @@
 };
 
-static wchar_t translate(unsigned int key, wchar_t *map, size_t map_length)
+static char32_t translate(unsigned int key, char32_t *map, size_t map_length)
 {
 	if (key >= map_length)
@@ -282,7 +282,7 @@
 }
 
-static wchar_t parse_ms_hacek(layout_cz_t *cz_state, kbd_event_t *ev)
-{
-	wchar_t c;
+static char32_t parse_ms_hacek(layout_cz_t *cz_state, kbd_event_t *ev)
+{
+	char32_t c;
 
 	cz_state->mstate = ms_start;
@@ -293,14 +293,14 @@
 
 	if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
-		c = translate(ev->key, map_hacek_ucase, sizeof(map_hacek_ucase) / sizeof(wchar_t));
+		c = translate(ev->key, map_hacek_ucase, sizeof(map_hacek_ucase) / sizeof(char32_t));
 	else
-		c = translate(ev->key, map_hacek_lcase, sizeof(map_hacek_lcase) / sizeof(wchar_t));
+		c = translate(ev->key, map_hacek_lcase, sizeof(map_hacek_lcase) / sizeof(char32_t));
 
 	return c;
 }
 
-static wchar_t parse_ms_carka(layout_cz_t *cz_state, kbd_event_t *ev)
-{
-	wchar_t c;
+static char32_t parse_ms_carka(layout_cz_t *cz_state, kbd_event_t *ev)
+{
+	char32_t c;
 
 	cz_state->mstate = ms_start;
@@ -311,14 +311,14 @@
 
 	if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
-		c = translate(ev->key, map_carka_ucase, sizeof(map_carka_ucase) / sizeof(wchar_t));
+		c = translate(ev->key, map_carka_ucase, sizeof(map_carka_ucase) / sizeof(char32_t));
 	else
-		c = translate(ev->key, map_carka_lcase, sizeof(map_carka_lcase) / sizeof(wchar_t));
+		c = translate(ev->key, map_carka_lcase, sizeof(map_carka_lcase) / sizeof(char32_t));
 
 	return c;
 }
 
-static wchar_t parse_ms_start(layout_cz_t *cz_state, kbd_event_t *ev)
-{
-	wchar_t c;
+static char32_t parse_ms_start(layout_cz_t *cz_state, kbd_event_t *ev)
+{
+	char32_t c;
 
 	/* Produce no characters when Ctrl or Alt is pressed. */
@@ -335,5 +335,5 @@
 	}
 
-	c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(wchar_t));
+	c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(char32_t));
 	if (c != 0)
 		return c;
@@ -341,7 +341,7 @@
 	if ((ev->mods & KM_SHIFT) == 0) {
 		if ((ev->mods & KM_CAPS_LOCK) != 0)
-			c = translate(ev->key, map_ns_caps, sizeof(map_ns_caps) / sizeof(wchar_t));
+			c = translate(ev->key, map_ns_caps, sizeof(map_ns_caps) / sizeof(char32_t));
 		else
-			c = translate(ev->key, map_ns_nocaps, sizeof(map_ns_nocaps) / sizeof(wchar_t));
+			c = translate(ev->key, map_ns_nocaps, sizeof(map_ns_nocaps) / sizeof(char32_t));
 
 		if (c != 0)
@@ -350,7 +350,7 @@
 
 	if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
-		c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(wchar_t));
+		c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(char32_t));
 	else
-		c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(wchar_t));
+		c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(char32_t));
 
 	if (c != 0)
@@ -358,7 +358,7 @@
 
 	if ((ev->mods & KM_SHIFT) != 0)
-		c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(wchar_t));
+		c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(char32_t));
 	else
-		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(wchar_t));
+		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(char32_t));
 
 	if (c != 0)
@@ -366,5 +366,5 @@
 
 	if ((ev->mods & KM_NUM_LOCK) != 0)
-		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(wchar_t));
+		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(char32_t));
 	else
 		c = 0;
@@ -409,5 +409,5 @@
 }
 
-static wchar_t cz_parse_ev(layout_t *state, kbd_event_t *ev)
+static char32_t cz_parse_ev(layout_t *state, kbd_event_t *ev)
 {
 	layout_cz_t *cz_state = (layout_cz_t *) state->layout_priv;
Index: uspace/srv/hid/input/layout/fr_azerty.c
===================================================================
--- uspace/srv/hid/input/layout/fr_azerty.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/hid/input/layout/fr_azerty.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -43,5 +43,5 @@
 static errno_t fr_azerty_create (layout_t *);
 static void fr_azerty_destroy (layout_t *);
-static wchar_t fr_azerty_parse_ev (layout_t *, kbd_event_t *);
+static char32_t fr_azerty_parse_ev (layout_t *, kbd_event_t *);
 
 layout_ops_t fr_azerty_ops = {
@@ -51,5 +51,5 @@
 };
 
-static wchar_t map_lcase[] = {
+static char32_t map_lcase[] = {
 	[KC_Q] = 'a',
 	[KC_W] = 'z',
@@ -82,5 +82,5 @@
 };
 
-static wchar_t map_ucase[] = {
+static char32_t map_ucase[] = {
 	[KC_Q] = 'A',
 	[KC_W] = 'Z',
@@ -117,5 +117,5 @@
 };
 
-static wchar_t map_not_shifted[] = {
+static char32_t map_not_shifted[] = {
 	[KC_BACKTICK] = L'²',
 
@@ -146,5 +146,5 @@
 };
 
-static wchar_t map_shifted[] = {
+static char32_t map_shifted[] = {
 	[KC_M] = '?',
 	[KC_BACKTICK] = '~',
@@ -176,5 +176,5 @@
 };
 
-static wchar_t map_neutral[] = {
+static char32_t map_neutral[] = {
 	[KC_BACKSPACE] = '\b',
 	[KC_TAB] = '\t',
@@ -189,5 +189,5 @@
 };
 
-static wchar_t map_numeric[] = {
+static char32_t map_numeric[] = {
 	[KC_N7] = '7',
 	[KC_N8] = '8',
@@ -204,5 +204,5 @@
 };
 
-static wchar_t translate (unsigned int key, wchar_t *map, size_t map_len)
+static char32_t translate (unsigned int key, char32_t *map, size_t map_len)
 {
 	if (key >= map_len)
@@ -221,17 +221,17 @@
 }
 
-static wchar_t fr_azerty_parse_ev (layout_t *s, kbd_event_t *e)
+static char32_t fr_azerty_parse_ev (layout_t *s, kbd_event_t *e)
 {
 	if ((e->mods & (KM_CTRL | KM_ALT)))
 		return 0; // Produce no characters when Ctrl or Alt is pressed
 
-	wchar_t c = translate (e->key, map_neutral, sizeof (map_neutral) / sizeof (wchar_t));
+	char32_t c = translate (e->key, map_neutral, sizeof (map_neutral) / sizeof (char32_t));
 	if (c)
 		return c;
 
 	if ((e->mods & KM_SHIFT))
-		c = translate (e->key, map_shifted, sizeof (map_shifted) / sizeof (wchar_t));
+		c = translate (e->key, map_shifted, sizeof (map_shifted) / sizeof (char32_t));
 	else
-		c = translate (e->key, map_not_shifted, sizeof (map_not_shifted) / sizeof (wchar_t));
+		c = translate (e->key, map_not_shifted, sizeof (map_not_shifted) / sizeof (char32_t));
 
 	if (c)
@@ -239,7 +239,7 @@
 
 	if (((e->mods & KM_SHIFT)) ^ ((e->mods & KM_CAPS_LOCK)))
-		c = translate (e->key, map_ucase, sizeof (map_ucase) / sizeof (wchar_t));
+		c = translate (e->key, map_ucase, sizeof (map_ucase) / sizeof (char32_t));
 	else
-		c = translate (e->key, map_lcase, sizeof (map_lcase) / sizeof (wchar_t));
+		c = translate (e->key, map_lcase, sizeof (map_lcase) / sizeof (char32_t));
 
 	if (c)
@@ -247,5 +247,5 @@
 
 	if ((e->mods & KM_NUM_LOCK))
-		c = translate (e->key, map_numeric, sizeof (map_numeric) / sizeof (wchar_t));
+		c = translate (e->key, map_numeric, sizeof (map_numeric) / sizeof (char32_t));
 	else
 		c = 0;
Index: uspace/srv/hid/input/layout/us_dvorak.c
===================================================================
--- uspace/srv/hid/input/layout/us_dvorak.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/hid/input/layout/us_dvorak.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -43,5 +43,5 @@
 static errno_t us_dvorak_create(layout_t *);
 static void us_dvorak_destroy(layout_t *);
-static wchar_t us_dvorak_parse_ev(layout_t *, kbd_event_t *ev);
+static char32_t us_dvorak_parse_ev(layout_t *, kbd_event_t *ev);
 
 layout_ops_t us_dvorak_ops = {
@@ -51,5 +51,5 @@
 };
 
-static wchar_t map_lcase[] = {
+static char32_t map_lcase[] = {
 	[KC_R] = 'p',
 	[KC_T] = 'y',
@@ -84,5 +84,5 @@
 };
 
-static wchar_t map_ucase[] = {
+static char32_t map_ucase[] = {
 	[KC_R] = 'P',
 	[KC_T] = 'Y',
@@ -117,5 +117,5 @@
 };
 
-static wchar_t map_not_shifted[] = {
+static char32_t map_not_shifted[] = {
 	[KC_BACKTICK] = '`',
 
@@ -147,5 +147,5 @@
 };
 
-static wchar_t map_shifted[] = {
+static char32_t map_shifted[] = {
 	[KC_BACKTICK] = '~',
 
@@ -177,5 +177,5 @@
 };
 
-static wchar_t map_neutral[] = {
+static char32_t map_neutral[] = {
 	[KC_BACKSPACE] = '\b',
 	[KC_TAB] = '\t',
@@ -190,5 +190,5 @@
 };
 
-static wchar_t map_numeric[] = {
+static char32_t map_numeric[] = {
 	[KC_N7] = '7',
 	[KC_N8] = '8',
@@ -205,5 +205,5 @@
 };
 
-static wchar_t translate(unsigned int key, wchar_t *map, size_t map_length)
+static char32_t translate(unsigned int key, char32_t *map, size_t map_length)
 {
 	if (key >= map_length)
@@ -221,7 +221,7 @@
 }
 
-static wchar_t us_dvorak_parse_ev(layout_t *state, kbd_event_t *ev)
-{
-	wchar_t c;
+static char32_t us_dvorak_parse_ev(layout_t *state, kbd_event_t *ev)
+{
+	char32_t c;
 
 	/* Produce no characters when Ctrl or Alt is pressed. */
@@ -229,12 +229,12 @@
 		return 0;
 
-	c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(wchar_t));
+	c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(char32_t));
 	if (c != 0)
 		return c;
 
 	if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
-		c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(wchar_t));
+		c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(char32_t));
 	else
-		c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(wchar_t));
+		c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(char32_t));
 
 	if (c != 0)
@@ -242,7 +242,7 @@
 
 	if ((ev->mods & KM_SHIFT) != 0)
-		c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(wchar_t));
+		c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(char32_t));
 	else
-		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(wchar_t));
+		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(char32_t));
 
 	if (c != 0)
@@ -250,5 +250,5 @@
 
 	if ((ev->mods & KM_NUM_LOCK) != 0)
-		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(wchar_t));
+		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(char32_t));
 	else
 		c = 0;
Index: uspace/srv/hid/input/layout/us_qwerty.c
===================================================================
--- uspace/srv/hid/input/layout/us_qwerty.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/hid/input/layout/us_qwerty.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -43,5 +43,5 @@
 static errno_t us_qwerty_create(layout_t *);
 static void us_qwerty_destroy(layout_t *);
-static wchar_t us_qwerty_parse_ev(layout_t *, kbd_event_t *ev);
+static char32_t us_qwerty_parse_ev(layout_t *, kbd_event_t *ev);
 
 layout_ops_t us_qwerty_ops = {
@@ -51,5 +51,5 @@
 };
 
-static wchar_t map_lcase[] = {
+static char32_t map_lcase[] = {
 	[KC_Q] = 'q',
 	[KC_W] = 'w',
@@ -82,5 +82,5 @@
 };
 
-static wchar_t map_ucase[] = {
+static char32_t map_ucase[] = {
 	[KC_Q] = 'Q',
 	[KC_W] = 'W',
@@ -113,5 +113,5 @@
 };
 
-static wchar_t map_not_shifted[] = {
+static char32_t map_not_shifted[] = {
 	[KC_BACKTICK] = '`',
 
@@ -142,5 +142,5 @@
 };
 
-static wchar_t map_shifted[] = {
+static char32_t map_shifted[] = {
 	[KC_BACKTICK] = '~',
 
@@ -171,5 +171,5 @@
 };
 
-static wchar_t map_neutral[] = {
+static char32_t map_neutral[] = {
 	[KC_BACKSPACE] = '\b',
 	[KC_TAB] = '\t',
@@ -184,5 +184,5 @@
 };
 
-static wchar_t map_numeric[] = {
+static char32_t map_numeric[] = {
 	[KC_N7] = '7',
 	[KC_N8] = '8',
@@ -199,5 +199,5 @@
 };
 
-static wchar_t translate(unsigned int key, wchar_t *map, size_t map_length)
+static char32_t translate(unsigned int key, char32_t *map, size_t map_length)
 {
 	if (key >= map_length)
@@ -215,7 +215,7 @@
 }
 
-static wchar_t us_qwerty_parse_ev(layout_t *state, kbd_event_t *ev)
-{
-	wchar_t c;
+static char32_t us_qwerty_parse_ev(layout_t *state, kbd_event_t *ev)
+{
+	char32_t c;
 
 	/* Produce no characters when Ctrl or Alt is pressed. */
@@ -223,12 +223,12 @@
 		return 0;
 
-	c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(wchar_t));
+	c = translate(ev->key, map_neutral, sizeof(map_neutral) / sizeof(char32_t));
 	if (c != 0)
 		return c;
 
 	if (((ev->mods & KM_SHIFT) != 0) ^ ((ev->mods & KM_CAPS_LOCK) != 0))
-		c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(wchar_t));
+		c = translate(ev->key, map_ucase, sizeof(map_ucase) / sizeof(char32_t));
 	else
-		c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(wchar_t));
+		c = translate(ev->key, map_lcase, sizeof(map_lcase) / sizeof(char32_t));
 
 	if (c != 0)
@@ -236,7 +236,7 @@
 
 	if ((ev->mods & KM_SHIFT) != 0)
-		c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(wchar_t));
+		c = translate(ev->key, map_shifted, sizeof(map_shifted) / sizeof(char32_t));
 	else
-		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(wchar_t));
+		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(char32_t));
 
 	if (c != 0)
@@ -244,5 +244,5 @@
 
 	if ((ev->mods & KM_NUM_LOCK) != 0)
-		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(wchar_t));
+		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(char32_t));
 	else
 		c = 0;
Index: uspace/srv/hid/output/ctl/serial.c
===================================================================
--- uspace/srv/hid/output/ctl/serial.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/hid/output/ctl/serial.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -57,5 +57,5 @@
 	vt100_goto(state, col, row);
 	vt100_set_attr(state, field->attrs);
-	vt100_putwchar(state, field->ch);
+	vt100_putuchar(state, field->ch);
 }
 
@@ -122,9 +122,9 @@
 };
 
-errno_t serial_init(vt100_putwchar_t putwchar_fn,
+errno_t serial_init(vt100_putuchar_t putuchar_fn,
     vt100_control_puts_t control_puts_fn, vt100_flush_t flush_fn)
 {
 	vt100_state_t *state =
-	    vt100_state_create(SERIAL_COLS, SERIAL_ROWS, putwchar_fn,
+	    vt100_state_create(SERIAL_COLS, SERIAL_ROWS, putuchar_fn,
 	    control_puts_fn, flush_fn);
 	if (state == NULL)
Index: uspace/srv/hid/output/ctl/serial.h
===================================================================
--- uspace/srv/hid/output/ctl/serial.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/hid/output/ctl/serial.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -37,5 +37,5 @@
 #include "../proto/vt100.h"
 
-extern errno_t serial_init(vt100_putwchar_t, vt100_control_puts_t, vt100_flush_t);
+extern errno_t serial_init(vt100_putuchar_t, vt100_control_puts_t, vt100_flush_t);
 
 #endif
Index: uspace/srv/hid/output/gfx/font-8x16.c
===================================================================
--- uspace/srv/hid/output/gfx/font-8x16.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/hid/output/gfx/font-8x16.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -45,5 +45,5 @@
  *
  */
-uint16_t fb_font_glyph(const wchar_t ch)
+uint16_t fb_font_glyph(const char32_t ch)
 {
 	if (ch == 0x0000)
Index: uspace/srv/hid/output/gfx/font-8x16.h
===================================================================
--- uspace/srv/hid/output/gfx/font-8x16.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/hid/output/gfx/font-8x16.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -42,5 +42,5 @@
 #define FONT_SCANLINES  16
 
-extern uint16_t fb_font_glyph(const wchar_t);
+extern uint16_t fb_font_glyph(const char32_t);
 extern uint8_t fb_font[FONT_GLYPHS][FONT_SCANLINES];
 
Index: uspace/srv/hid/output/port/chardev.c
===================================================================
--- uspace/srv/hid/output/port/chardev.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/hid/output/port/chardev.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -78,5 +78,5 @@
 }
 
-static void chardev_putwchar(wchar_t ch)
+static void chardev_putuchar(char32_t ch)
 {
 	if (chardev_bused == chardev_buf_size)
@@ -93,5 +93,5 @@
 	p = str;
 	while (*p != '\0')
-		chardev_putwchar(*p++);
+		chardev_putuchar(*p++);
 }
 
@@ -199,5 +199,5 @@
 	}
 
-	serial_init(chardev_putwchar, chardev_control_puts, chardev_flush);
+	serial_init(chardev_putuchar, chardev_control_puts, chardev_flush);
 
 	discovery_finished = true;
Index: uspace/srv/hid/output/port/kfb.c
===================================================================
--- uspace/srv/hid/output/port/kfb.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/hid/output/port/kfb.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -79,5 +79,5 @@
 
 /** Function to draw a character. */
-typedef void (*draw_char_t)(sysarg_t, sysarg_t, bool, wchar_t, pixel_t,
+typedef void (*draw_char_t)(sysarg_t, sysarg_t, bool, char32_t, pixel_t,
     pixel_t);
 
@@ -287,5 +287,5 @@
  *
  */
-static void draw_char_aligned(sysarg_t x, sysarg_t y, bool inverted, wchar_t ch,
+static void draw_char_aligned(sysarg_t x, sysarg_t y, bool inverted, char32_t ch,
     pixel_t bgcolor, pixel_t fgcolor)
 {
@@ -350,5 +350,5 @@
  */
 static void draw_char_fallback(sysarg_t x, sysarg_t y, bool inverted,
-    wchar_t ch, pixel_t bgcolor, pixel_t fgcolor)
+    char32_t ch, pixel_t bgcolor, pixel_t fgcolor)
 {
 	/* Character glyph */
Index: uspace/srv/hid/output/proto/vt100.c
===================================================================
--- uspace/srv/hid/output/proto/vt100.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/hid/output/proto/vt100.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -140,5 +140,5 @@
 
 vt100_state_t *vt100_state_create(sysarg_t cols, sysarg_t rows,
-    vt100_putwchar_t putwchar_fn, vt100_control_puts_t control_puts_fn,
+    vt100_putuchar_t putuchar_fn, vt100_control_puts_t control_puts_fn,
     vt100_flush_t flush_fn)
 {
@@ -147,5 +147,5 @@
 		return NULL;
 
-	state->putwchar = putwchar_fn;
+	state->putuchar = putuchar_fn;
 	state->control_puts = control_puts_fn;
 	state->flush = flush_fn;
@@ -220,7 +220,7 @@
 }
 
-void vt100_putwchar(vt100_state_t *state, wchar_t ch)
-{
-	state->putwchar(ch == 0 ? ' ' : ch);
+void vt100_putuchar(vt100_state_t *state, char32_t ch)
+{
+	state->putuchar(ch == 0 ? ' ' : ch);
 	state->cur_col++;
 
Index: uspace/srv/hid/output/proto/vt100.h
===================================================================
--- uspace/srv/hid/output/proto/vt100.h	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/hid/output/proto/vt100.h	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -36,5 +36,5 @@
 #include <io/charfield.h>
 
-typedef void (*vt100_putwchar_t)(wchar_t ch);
+typedef void (*vt100_putuchar_t)(char32_t ch);
 typedef void (*vt100_control_puts_t)(const char *str);
 typedef void (*vt100_flush_t)(void);
@@ -48,10 +48,10 @@
 	char_attrs_t cur_attrs;
 
-	vt100_putwchar_t putwchar;
+	vt100_putuchar_t putuchar;
 	vt100_control_puts_t control_puts;
 	vt100_flush_t flush;
 } vt100_state_t;
 
-extern vt100_state_t *vt100_state_create(sysarg_t, sysarg_t, vt100_putwchar_t,
+extern vt100_state_t *vt100_state_create(sysarg_t, sysarg_t, vt100_putuchar_t,
     vt100_control_puts_t, vt100_flush_t);
 extern void vt100_state_destroy(vt100_state_t *);
@@ -64,5 +64,5 @@
 extern void vt100_set_attr(vt100_state_t *, char_attrs_t);
 extern void vt100_cursor_visibility(vt100_state_t *, bool);
-extern void vt100_putwchar(vt100_state_t *, wchar_t);
+extern void vt100_putuchar(vt100_state_t *, char32_t);
 extern void vt100_flush(vt100_state_t *);
 
Index: uspace/srv/hid/remcons/user.c
===================================================================
--- uspace/srv/hid/remcons/user.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/hid/remcons/user.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -218,5 +218,5 @@
  * @param c Pressed character.
  */
-static kbd_event_t *new_kbd_event(kbd_event_type_t type, wchar_t c)
+static kbd_event_t *new_kbd_event(kbd_event_type_t type, char32_t c)
 {
 	kbd_event_t *event = malloc(sizeof(kbd_event_t));
Index: uspace/srv/locsrv/locsrv.c
===================================================================
--- uspace/srv/locsrv/locsrv.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/locsrv/locsrv.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -125,5 +125,5 @@
 	size_t offset = 0;
 	size_t offset_prev = 0;
-	wchar_t c;
+	char32_t c;
 
 	while ((c = str_decode(fqsn, &offset, STR_NO_LIMIT)) != 0) {
Index: uspace/srv/net/dnsrsrv/dns_msg.c
===================================================================
--- uspace/srv/net/dnsrsrv/dns_msg.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/net/dnsrsrv/dns_msg.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -97,5 +97,5 @@
 {
 	size_t off;
-	wchar_t c;
+	char32_t c;
 	size_t lsize;
 	size_t pi, di;
Index: uspace/srv/volsrv/part.c
===================================================================
--- uspace/srv/volsrv/part.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/volsrv/part.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -129,5 +129,5 @@
 
 		if (!already_known) {
-			log_msg(LOG_DEFAULT, LVL_NOTE, "Found partition '%lu'",
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "Found partition '%lu'",
 			    (unsigned long) svcs[i]);
 			rc = vol_part_add_locked(parts, svcs[i]);
@@ -155,5 +155,5 @@
 
 		if (!still_exists) {
-			log_msg(LOG_DEFAULT, LVL_NOTE, "Partition '%zu' is gone",
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "Partition '%zu' is gone",
 			    part->svc_id);
 			vol_part_remove_locked(part);
@@ -210,5 +210,5 @@
 	errno_t rc;
 
-	log_msg(LOG_DEFAULT, LVL_NOTE, "Probe partition %s", part->svc_name);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Probe partition %s", part->svc_name);
 
 	assert(fibril_mutex_is_locked(&part->parts->lock));
@@ -223,5 +223,5 @@
 
 	if (fst->name != NULL) {
-		log_msg(LOG_DEFAULT, LVL_NOTE, "Found %s, label '%s'",
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Found %s, label '%s'",
 		    fst->name, info.label);
 		label = str_dup(info.label);
@@ -317,9 +317,9 @@
 	if (str_size(part->volume->mountp) > 0) {
 		cfg_mp = part->volume->mountp;
-		log_msg(LOG_DEFAULT, LVL_NOTE, "Configured mount point '%s'",
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Configured mount point '%s'",
 		    cfg_mp);
 	} else {
 		cfg_mp = vol_part_def_mountp(part);
-		log_msg(LOG_DEFAULT, LVL_NOTE, "Default mount point '%s'",
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Default mount point '%s'",
 		    cfg_mp);
 	}
@@ -334,5 +334,5 @@
 		}
 
-		log_msg(LOG_DEFAULT, LVL_NOTE, "Determine MP label='%s'", part->label);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Determine MP label='%s'", part->label);
 		err = asprintf(&mp, "/vol/%s", part->label);
 		if (err < 0) {
@@ -378,5 +378,5 @@
 	if (mp_auto) {
 		/* Create directory for automatic mount point */
-		log_msg(LOG_DEFAULT, LVL_NOTE, "Create mount point '%s'", mp);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Create mount point '%s'", mp);
 		rc = vfs_link_path(mp, KIND_DIRECTORY, NULL);
 		if (rc != EOK) {
@@ -388,12 +388,15 @@
 	}
 
-	log_msg(LOG_DEFAULT, LVL_NOTE, "Call vfs_mount_path mp='%s' fstype='%s' svc_name='%s'",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Call vfs_mount_path mp='%s' fstype='%s' svc_name='%s'",
 	    mp, fstype_str(part->fstype), part->svc_name);
 	rc = vfs_mount_path(mp, fstype_str(part->fstype),
 	    part->svc_name, "", 0, 0);
 	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_NOTE, "Failed mounting to %s", mp);
-	}
-	log_msg(LOG_DEFAULT, LVL_NOTE, "Mount to %s -> %d\n", mp, rc);
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed mounting %s at %s to %s",
+		    fstype_str(part->fstype), part->svc_name, mp);
+	} else {
+		log_msg(LOG_DEFAULT, LVL_NOTE, "Mounted %s at %s to %s\n",
+		    fstype_str(part->fstype), part->svc_name, mp);
+	}
 
 	part->cur_mp = mp;
@@ -409,5 +412,5 @@
 
 	assert(fibril_mutex_is_locked(&parts->lock));
-	log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_add_locked(%zu)", sid);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_add_locked(%zu)", sid);
 
 	/* Check for duplicates */
@@ -418,5 +421,5 @@
 	}
 
-	log_msg(LOG_DEFAULT, LVL_NOTE, "partition %zu is new", sid);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "partition %zu is new", sid);
 
 	part = vol_part_new();
@@ -443,5 +446,5 @@
 	list_append(&part->lparts, &parts->parts);
 
-	log_msg(LOG_DEFAULT, LVL_NOTE, "Added partition %zu", part->svc_id);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Added partition %zu", part->svc_id);
 
 	return EOK;
@@ -455,10 +458,10 @@
 {
 	assert(fibril_mutex_is_locked(&part->parts->lock));
-	log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_remove_locked(%zu)",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_remove_locked(%zu)",
 	    part->svc_id);
 
 	list_remove(&part->lparts);
 
-	log_msg(LOG_DEFAULT, LVL_NOTE, "Removed partition.");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Removed partition.");
 	vol_part_del_ref(part);
 }
Index: uspace/srv/volsrv/volsrv.c
===================================================================
--- uspace/srv/volsrv/volsrv.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/volsrv/volsrv.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -256,5 +256,5 @@
 	errno_t rc;
 
-	log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_insert_by_path_srv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_insert_by_path_srv()");
 
 	rc = async_data_write_accept((void **)&path, true, 0, VOL_MOUNTP_MAXLEN,
@@ -360,5 +360,5 @@
 	errno_t rc;
 
-	log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_mkfs_srv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_mkfs_srv()");
 
 	sid = ipc_get_arg1(icall);
@@ -373,5 +373,5 @@
 
 	if (label != NULL) {
-		log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_mkfs_srv: label='%s'",
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_mkfs_srv: label='%s'",
 		    label);
 	}
@@ -385,5 +385,5 @@
 
 	if (mountp != NULL) {
-		log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_mkfs_srv: mountp='%s'",
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_mkfs_srv: mountp='%s'",
 		    mountp);
 	}
@@ -422,5 +422,5 @@
 	errno_t rc;
 
-	log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_set_mountp_srv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_set_mountp_srv()");
 
 	sid = ipc_get_arg1(icall);
@@ -434,5 +434,5 @@
 
 	if (mountp != NULL) {
-		log_msg(LOG_DEFAULT, LVL_NOTE,
+		log_msg(LOG_DEFAULT, LVL_DEBUG,
 		    "vol_part_set_mountp_srv: mountp='%s'", mountp);
 	}
@@ -464,5 +464,5 @@
 	errno_t rc;
 
-	log_msg(LOG_DEFAULT, LVL_NOTE, "vol_get_volumes_srv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_get_volumes_srv()");
 
 	if (!async_data_read_receive(&call, &size)) {
Index: uspace/srv/volsrv/volume.c
===================================================================
--- uspace/srv/volsrv/volume.c	(revision 1a1c75ed7ed0a3fffd885999172cc41341962b44)
+++ uspace/srv/volsrv/volume.c	(revision ddb844e7f3c7c26ca821db9add6e4c048aaf9a7b)
@@ -96,5 +96,5 @@
 static void vol_volume_delete(vol_volume_t *volume)
 {
-	log_msg(LOG_DEFAULT, LVL_NOTE, "Freeing volume %p", volume);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Freeing volume %p", volume);
 
 	free(volume->label);
@@ -219,5 +219,5 @@
 {
 	assert(fibril_mutex_is_locked(&volumes->lock));
-	log_msg(LOG_DEFAULT, LVL_NOTE, "vol_volume_add_locked(%p)", volume);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_volume_add_locked(%p)", volume);
 
 	volume->volumes = volumes;
