Index: kernel/genarch/Makefile.inc
===================================================================
--- kernel/genarch/Makefile.inc	(revision b2fa1204c76e1eaec329888181d281aac04ed61e)
+++ kernel/genarch/Makefile.inc	(revision 6a3d0c7d3c6877f7abc3f9784c37e626fd07986f)
@@ -90,7 +90,7 @@
 endif
 
-ifeq ($(CONFIG_ARM926_UART),y)
+ifeq ($(CONFIG_PL011_UART),y)
 	GENARCH_SOURCES += \
-		genarch/src/drivers/arm926_uart/arm926_uart.c
+		genarch/src/drivers/pl011/pl011.c
 endif
 
@@ -123,4 +123,9 @@
 	GENARCH_SOURCES += \
 		genarch/src/drivers/am335x/timer.c
+endif
+
+ifeq ($(CONFIG_BCM2835_MAILBOX),y)
+	GENARCH_SOURCES += \
+		genarch/src/drivers/bcm2835/mbox.c
 endif
 
Index: kernel/genarch/include/genarch/drivers/arm926_uart/arm926_uart.h
===================================================================
--- kernel/genarch/include/genarch/drivers/arm926_uart/arm926_uart.h	(revision b2fa1204c76e1eaec329888181d281aac04ed61e)
+++ 	(revision )
@@ -1,169 +1,0 @@
-/*
- * Copyright (c) 2012 Jan Vesely
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup genarch
- * @{
- */
-/**
- * @file
- * @brief ARM926 on-chip UART (PrimeCell UART, PL011) driver.
- */
-
-#ifndef KERN_ARM926_UART_H_
-#define KERN_ARM926_UART_H_
-
-#include <ddi/irq.h>
-#include <console/chardev.h>
-#include <typedefs.h>
-
-
-/** ARM926 User Guide ch. 4.8.5 (p. 106 in the pdf) */
-#define ARM926_UART0_BASE_ADDRESS   0x16000000
-#define ARM926_UART1_BASE_ADDRESS   0x16000000
-
-/** ARM926 User Guide ch. A.1 (p. 124 in the pdf) */
-#define ARM926_UART0_IRQ   1
-#define ARM926_UART1_IRQ   2
-
-/** PrimeCell UART TRM ch. 3.3 (p. 49 in the pdf) */
-typedef struct {
-	/** UART data register */
-	ioport32_t data;
-#define ARM926_UART_DATA_DATA_MASK   0xff
-#define ARM926_UART_DATA_FE_FLAG   (1 <<  7)
-#define ARM926_UART_DATA_PE_FLAG   (1 <<  9)
-#define ARM926_UART_DATA_BE_FLAG   (1 << 10)
-#define ARM926_UART_DATA_OE_FLAG   (1 << 11)
-
-	union {
-		/* Same values that are in upper bits of data register*/
-		const ioport32_t status;
-#define ARM926_UART_STATUS_FE_FLAG   (1 << 0)
-#define ARM926_UART_STATUS_PE_FLAG   (1 << 1)
-#define ARM926_UART_STATUS_BE_FLAG   (1 << 2)
-#define ARM926_UART_STATUS_OE_FLAG   (1 << 3)
-		/* Writing anything clears all errors */
-		ioport32_t error_clear;
-	};
-	uint32_t padd0_[4];
-
-	const ioport32_t flag;
-#define ARM926_UART_FLAG_CTS_FLAG    (1 << 0)
-#define ARM926_UART_FLAG_DSR_FLAG    (1 << 1)
-#define ARM926_UART_FLAG_DCD_FLAG    (1 << 2)
-#define ARM926_UART_FLAG_BUSY_FLAG   (1 << 3)
-#define ARM926_UART_FLAG_RXFE_FLAG   (1 << 4)
-#define ARM926_UART_FLAG_TXFF_FLAG   (1 << 5)
-#define ARM926_UART_FLAG_RXFF_FLAG   (1 << 6)
-#define ARM926_UART_FLAG_TXFE_FLAG   (1 << 7)
-#define ARM926_UART_FLAG_RI_FLAG     (1 << 8)
-	uint32_t padd1_;
-
-	ioport32_t irda_low_power;
-#define ARM926_UART_IRDA_LOW_POWER_MASK   0xff
-
-	ioport32_t int_baud_divisor;
-#define ARM926_UART_INT_BAUD_DIVISOR_MASK   0xffff
-
-	ioport32_t fract_baud_divisor;
-#define ARM926_UART_FRACT_BAUD_DIVISOR_MASK   0x1f
-
-	ioport32_t line_control_high;
-#define ARM926_UART_CONTROLHI_BRK_FLAG    (1 << 0)
-#define ARM926_UART_CONTROLHI_PEN_FLAG    (1 << 1)
-#define ARM926_UART_CONTROLHI_EPS_FLAG    (1 << 2)
-#define ARM926_UART_CONTROLHI_STP2_FLAG   (1 << 3)
-#define ARM926_UART_CONTROLHI_FEN_FLAG    (1 << 4)
-#define ARM926_UART_CONTROLHI_WLEN_MASK   0x3
-#define ARM926_UART_CONTROLHI_WLEN_SHIFT    5
-#define ARM926_UART_CONTROLHI_SPS_FLAG    (1 << 5)
-
-	ioport32_t control;
-#define ARM926_UART_CONTROL_UARTEN_FLAG   (1 << 0)
-#define ARM926_UART_CONTROL_SIREN_FLAG    (1 << 1)
-#define ARM926_UART_CONTROL_SIRLP_FLAG    (1 << 2)
-#define ARM926_UART_CONTROL_LBE_FLAG      (1 << 7)
-#define ARM926_UART_CONTROL_TXE_FLAG      (1 << 8)
-#define ARM926_UART_CONTROL_RXE_FLAG      (1 << 9)
-#define ARM926_UART_CONTROL_DTR_FLAG     (1 << 10)
-#define ARM926_UART_CONTROL_RTS_FLAG     (1 << 11)
-#define ARM926_UART_CONTROL_OUT1_FLAG    (1 << 12)
-#define ARM926_UART_CONTROL_OUT2_FLAG    (1 << 13)
-#define ARM926_UART_CONTROL_RTSE_FLAG    (1 << 14)
-#define ARM926_UART_CONTROL_CTSE_FLAG    (1 << 15)
-
-	ioport32_t interrupt_fifo;
-#define ARM926_UART_INTERRUPTFIFO_TX_MASK   0x7
-#define ARM926_UART_INTERRUPTFIFO_TX_SHIFT    0
-#define ARM926_UART_INTERRUPTFIFO_RX_MASK   0x7
-#define ARM926_UART_INTERRUPTFIFO_RX_SHIFT    3
-
-	/** Interrupt mask register */
-	ioport32_t interrupt_mask;
-	/** Pending interrupts before applying the mask */
-	const ioport32_t raw_interrupt_status;
-	/** Pending interrupts after applying the mask */
-	const ioport32_t masked_interrupt_status;
-	/** Write 1s to clear pending interrupts */
-	ioport32_t interrupt_clear;
-#define ARM926_UART_INTERRUPT_RIM_FLAG    (1 << 0)
-#define ARM926_UART_INTERRUPT_CTSM_FLAG   (1 << 1)
-#define ARM926_UART_INTERRUPT_DCDM_FLAG   (1 << 2)
-#define ARM926_UART_INTERRUPT_DSRM_FLAG   (1 << 3)
-#define ARM926_UART_INTERRUPT_RX_FLAG     (1 << 4)
-#define ARM926_UART_INTERRUPT_TX_FLAG     (1 << 5)
-#define ARM926_UART_INTERRUPT_RT_FLAG     (1 << 6)
-#define ARM926_UART_INTERRUPT_FE_FLAG     (1 << 7)
-#define ARM926_UART_INTERRUPT_PE_FLAG     (1 << 8)
-#define ARM926_UART_INTERRUPT_BE_FLAG     (1 << 9)
-#define ARM926_UART_INTERRUPT_OE_FLAG    (1 << 10)
-#define ARM926_UART_INTERRUPT_ALL           0x3ff
-
-	ioport32_t dma_control;
-#define ARM926_UART_DMACONTROL_RXDMAEN_FLAG    (1 << 0)
-#define ARM926_UART_DMACONTROL_TXDMAEN_FLAG    (1 << 1)
-#define ARM926_UART_DMACONTROL_DMAONERR_FLAG   (1 << 2)
-
-	// TODO There is some reserved space here followed by
-	// peripheral identification registers.
-} arm926_uart_regs_t;
-
-typedef struct {
-	arm926_uart_regs_t *regs;
-	indev_t *indev;
-	outdev_t outdev;
-	irq_t irq;
-} arm926_uart_t;
-
-bool arm926_uart_init(arm926_uart_t *, inr_t, uintptr_t, size_t);
-void arm926_uart_input_wire(arm926_uart_t *, indev_t *);
-
-#endif
-/**
- * @}
- */
Index: kernel/genarch/include/genarch/drivers/bcm2835/irc.h
===================================================================
--- kernel/genarch/include/genarch/drivers/bcm2835/irc.h	(revision 6a3d0c7d3c6877f7abc3f9784c37e626fd07986f)
+++ kernel/genarch/include/genarch/drivers/bcm2835/irc.h	(revision 6a3d0c7d3c6877f7abc3f9784c37e626fd07986f)
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2012 Jan Vesely
+ * Copyright (c) 2013 Beniamino Galvani
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/** @addtogroup genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief Broadcom BCM2835 on-chip interrupt controller driver.
+ */
+
+#ifndef KERN_BCM2835_IRQC_H_
+#define KERN_BCM2835_IRQC_H_
+
+#include <typedefs.h>
+
+#define BANK_GPU0	0
+#define BANK_GPU1	1
+#define BANK_ARM	2
+
+#define IRQ_TO_BANK(x)	((x) >> 5)
+#define IRQ_TO_NUM(x)	((x) & 0x1f)
+
+#define MAKE_IRQ(b,n)	(((b) << 5) | ((n) & 0x1f))
+
+#define BCM2835_UART_IRQ	MAKE_IRQ(BANK_GPU1, 25)
+#define BCM2835_TIMER1_IRQ	MAKE_IRQ(BANK_GPU0,  1)
+
+#define IRQ_PEND_ARM_M		0xFF
+#define IRQ_PEND_GPU0_M		(1 << 8)
+#define IRQ_PEND_GPU1_M		(1 << 9)
+#define IRQ_PEND_SHORT_M	0x1FFC00
+#define IRQ_PEND_SHORT_S	10
+
+unsigned shortcut_inums[] = {7, 9, 10, 18, 19, 53, 54, 55, 56, 57, 62};
+
+typedef struct {
+	ioport32_t	irq_basic_pending;
+	ioport32_t	irq_pending1;
+	ioport32_t	irq_pending2;
+
+	ioport32_t	fiq_control;
+
+	ioport32_t	irq_enable[3];
+	ioport32_t	irq_disable[3];
+} bcm2835_irc_t;
+
+#define BCM2835_IRC_ADDR 0x2000b200
+#define BCM2835_IRQ_COUNT 96
+
+static inline void bcm2835_irc_dump(bcm2835_irc_t *regs)
+{
+#define DUMP_REG(name) \
+	printf("%s : %08x\n", #name, regs->name);
+
+	DUMP_REG(irq_basic_pending);
+	DUMP_REG(irq_pending1);
+	DUMP_REG(irq_pending2);
+	DUMP_REG(fiq_control);
+
+	for (int i = 0; i < 3; ++i) {
+		DUMP_REG(irq_enable[i]);
+		DUMP_REG(irq_disable[i]);
+	}
+#undef DUMP_REG
+}
+
+static inline void bcm2835_irc_init(bcm2835_irc_t *regs)
+{
+	/* Disable all interrupts */
+	regs->irq_disable[BANK_GPU0] = 0xffffffff;
+	regs->irq_disable[BANK_GPU1] = 0xffffffff;
+	regs->irq_disable[BANK_ARM]  = 0xffffffff;
+
+	/* Disable FIQ generation */
+	regs->fiq_control = 0;
+}
+
+static inline int ffs(unsigned int x)
+{
+	int ret;
+
+	asm volatile (
+		"clz r0, %[x]\n"
+		"rsb %[ret], r0, #32\n"
+		: [ret] "=r" (ret)
+		: [x] "r" (x)
+		: "r0" );
+
+	return ret;
+}
+
+static inline unsigned bcm2835_irc_inum_get(bcm2835_irc_t *regs)
+{
+	uint32_t pending;
+	int inum = -1;
+
+	pending = regs->irq_basic_pending;
+
+	/*
+	 * The basic pending register shows interrupts pending from ARM
+	 * peripherals and it also contains, in order to speed up processing,
+	 * additional information about pending GPU interrupts:
+	 *
+	 *  - bits 0-7 are associated to ARM peripherals
+	 *  - bit 8 is 1 when at least one bit is set in pending register 1
+	 *  - bit 9 is 1 when at least one bit is set in pending register 2
+	 *  - bits 10-20 indicate pending status of selected GPU peripherals
+	 *
+	 *  Reference: BCM2835 ARM Peripherals, p.113
+	 */
+
+	if (pending & IRQ_PEND_ARM_M) {
+		inum = MAKE_IRQ(BANK_ARM, ffs(pending & IRQ_PEND_ARM_M) - 1);
+	} else if (pending & IRQ_PEND_SHORT_M) {
+		int pos = (pending & IRQ_PEND_SHORT_M) >> IRQ_PEND_SHORT_S;
+		inum = shortcut_inums[ffs(pos) - 1];
+	} else if (pending & IRQ_PEND_GPU0_M) {
+		inum = MAKE_IRQ(BANK_GPU0, ffs(regs->irq_pending1) - 1);
+	} else if (pending & IRQ_PEND_GPU1_M) {
+		inum = MAKE_IRQ(BANK_GPU1, ffs(regs->irq_pending2) - 1);
+	}
+
+	if (inum < 0) {
+		printf("Spurious interrupt!\n");
+		bcm2835_irc_dump(regs);
+		inum = 0;
+	}
+
+	return inum;
+}
+
+static inline void bcm2835_irc_enable(bcm2835_irc_t *regs, unsigned inum)
+{
+	ASSERT(inum < BCM2835_IRQ_COUNT);
+	regs->irq_enable[IRQ_TO_BANK(inum)] |= (1 << IRQ_TO_NUM(inum));
+}
+
+static inline void bcm2835_irc_disable(bcm2835_irc_t *regs, unsigned inum)
+{
+	ASSERT(inum < BCM2835_IRQ_COUNT);
+	regs->irq_disable[IRQ_TO_BANK(inum)] |= (1 << IRQ_TO_NUM(inum));
+}
+
+#endif /* KERN_BCM2835_IRQC_H_ */
+
+/**
+ * @}
+ */
Index: kernel/genarch/include/genarch/drivers/bcm2835/mbox.h
===================================================================
--- kernel/genarch/include/genarch/drivers/bcm2835/mbox.h	(revision 6a3d0c7d3c6877f7abc3f9784c37e626fd07986f)
+++ kernel/genarch/include/genarch/drivers/bcm2835/mbox.h	(revision 6a3d0c7d3c6877f7abc3f9784c37e626fd07986f)
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2013 Beniamino Galvani
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/** @addtogroup genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief BCM2835 mailbox communication routines
+ */
+
+#ifndef _BCM2835_MBOX_H_
+#define _BCM2835_MBOX_H_
+
+#include <genarch/fb/fb.h>
+#include <arch/mm/page.h>
+#include <align.h>
+
+#define BCM2835_MBOX0_ADDR	0x2000B880
+
+enum {
+	MBOX_CHAN_PM		= 0,
+	MBOX_CHAN_FB		= 1,
+	MBOX_CHAN_UART		= 2,
+	MBOX_CHAN_VCHIQ		= 3,
+	MBOX_CHAN_LED		= 4,
+	MBOX_CHAN_BTN		= 5,
+	MBOX_CHAN_TS		= 6,
+	MBOX_CHAN_PROP_A2V	= 8,
+	MBOX_CHAN_PROP_V2A	= 9
+};
+
+enum {
+	TAG_GET_FW_REV		= 0x00000001,
+	TAG_GET_BOARD_MODEL	= 0x00010001,
+	TAG_GET_BOARD_REV	= 0x00010002,
+	TAG_GET_BOARD_MAC	= 0x00010003,
+	TAG_GET_BOARD_SERIAL	= 0x00010004,
+	TAG_GET_ARM_MEMORY	= 0x00010005,
+	TAG_GET_VC_MEMORY	= 0x00010006,
+	TAG_GET_CLOCKS		= 0x00010007,
+	TAG_GET_CMD_LINE	= 0x00050001,
+};
+
+enum {
+	MBOX_PROP_CODE_REQ	= 0x00000000,
+	MBOX_PROP_CODE_RESP_OK	= 0x80000000,
+	MBOX_PROP_CODE_RESP_ERR	= 0x80000001
+};
+
+#define MBOX_STATUS_FULL	(1 << 31)
+#define MBOX_STATUS_EMPTY	(1 << 30)
+
+#define MBOX_COMPOSE(chan, value) (((chan) & 0xf) | ((value) & ~0xf))
+#define MBOX_MSG_CHAN(msg)	((msg) & 0xf)
+#define MBOX_MSG_VALUE(msg)	((msg) & ~0xf)
+
+#define KA2VCA(addr)		(KA2PA(addr) + 0x40000000)
+
+#define MBOX_ADDR_ALIGN		16
+
+#define MBOX_BUFF_ALLOC(name, type)					\
+	char tmp_ ## name[sizeof(type) + MBOX_ADDR_ALIGN] = { 0 };      \
+	type *name = (type *)ALIGN_UP((uintptr_t)tmp_ ## name, MBOX_ADDR_ALIGN);
+
+typedef struct {
+	ioport32_t read;
+	ioport32_t unused[3];
+	ioport32_t peek;
+	ioport32_t sender;
+	ioport32_t status;
+	ioport32_t config;
+	ioport32_t write;
+} bcm2835_mbox_t;
+
+typedef struct {
+	ioport32_t size;
+	ioport32_t code;
+} mbox_prop_buf_hdr_t;
+
+typedef struct {
+	ioport32_t tag_id;
+	ioport32_t buf_size;
+	ioport32_t val_len;
+} mbox_tag_hdr_t;
+
+typedef struct {
+	ioport32_t base;
+	ioport32_t size;
+} mbox_tag_getmem_resp_t;
+
+typedef struct {
+	mbox_prop_buf_hdr_t	buf_hdr;
+	mbox_tag_hdr_t		tag_hdr;
+	mbox_tag_getmem_resp_t	data;
+	uint32_t		zero;
+} mbox_getmem_buf_t;
+
+typedef struct {
+	ioport32_t width;
+	ioport32_t height;
+	ioport32_t virt_width;
+	ioport32_t virt_height;
+	ioport32_t pitch;
+	ioport32_t bpp;
+	ioport32_t x_offset;
+	ioport32_t y_offset;
+	ioport32_t addr;
+	ioport32_t size;
+} bcm2835_fb_desc_t;
+
+bool bcm2835_prop_get_memory(uint32_t *base, uint32_t *size);
+bool bcm2835_fb_init(fb_properties_t *prop);
+
+#endif
+/**
+ * @}
+ */
Index: kernel/genarch/include/genarch/drivers/bcm2835/timer.h
===================================================================
--- kernel/genarch/include/genarch/drivers/bcm2835/timer.h	(revision 6a3d0c7d3c6877f7abc3f9784c37e626fd07986f)
+++ kernel/genarch/include/genarch/drivers/bcm2835/timer.h	(revision 6a3d0c7d3c6877f7abc3f9784c37e626fd07986f)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2013 Beniamino Galvani
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/** @addtogroup genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief Broadcom BCM2835 system timer driver.
+ */
+
+#ifndef KERN_BCM2835_TIMER_H_
+
+#include <typedefs.h>
+#include <mm/km.h>
+
+#define BCM2835_TIMER_ADDR 0x20003000
+#define BCM2835_CLOCK_FREQ 1000000
+
+typedef struct {
+	/** System Timer Control/Status */
+	ioport32_t cs;
+#define BCM2835_TIMER_CS_M0 (1 << 0)
+#define BCM2835_TIMER_CS_M1 (1 << 1)
+#define BCM2835_TIMER_CS_M2 (1 << 2)
+#define BCM2835_TIMER_CS_M3 (1 << 3)
+	/** System Timer Counter Lower 32 bits */
+	ioport32_t clo;
+	/** System Timer Counter Higher 32 bits */
+	ioport32_t chi;
+	/** System Timer Compare 0 */
+	ioport32_t c0;
+	/** System Timer Compare 1 */
+	ioport32_t c1;
+	/** System Timer Compare 2 */
+	ioport32_t c2;
+	/** System Timer Compare 3 */
+	ioport32_t c3;
+} bcm2835_timer_t;
+
+
+static inline void bcm2835_timer_start(bcm2835_timer_t* timer)
+{
+	ASSERT(timer);
+	/* Clear pending interrupt on channel 1 */
+	timer->cs |= BCM2835_TIMER_CS_M1;
+	/* Initialize compare value for match channel 1 */
+	timer->c1 = timer->clo + (BCM2835_CLOCK_FREQ / HZ);
+}
+
+static inline void bcm2835_timer_irq_ack(bcm2835_timer_t* timer)
+{
+	ASSERT(timer);
+	/* Clear pending interrupt on channel 1 */
+	timer->cs |= BCM2835_TIMER_CS_M1;
+	/* Reprogram compare value for match channel 1 */
+	timer->c1 = timer->clo + (BCM2835_CLOCK_FREQ / HZ);
+}
+
+#endif /* KERN_BCM2835_TIMER_H_ */
Index: kernel/genarch/include/genarch/drivers/pl011/pl011.h
===================================================================
--- kernel/genarch/include/genarch/drivers/pl011/pl011.h	(revision 6a3d0c7d3c6877f7abc3f9784c37e626fd07986f)
+++ kernel/genarch/include/genarch/drivers/pl011/pl011.h	(revision 6a3d0c7d3c6877f7abc3f9784c37e626fd07986f)
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2012 Jan Vesely
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief ARM PrimeCell PL011 UART driver.
+ */
+
+#ifndef KERN_PL011_H_
+#define KERN_PL011_H_
+
+#include <ddi/irq.h>
+#include <console/chardev.h>
+#include <typedefs.h>
+
+/** PrimeCell UART TRM ch. 3.3 (p. 49 in the pdf) */
+typedef struct {
+	/** UART data register */
+	ioport32_t data;
+#define PL011_UART_DATA_DATA_MASK   0xff
+#define PL011_UART_DATA_FE_FLAG   (1 <<  7)
+#define PL011_UART_DATA_PE_FLAG   (1 <<  9)
+#define PL011_UART_DATA_BE_FLAG   (1 << 10)
+#define PL011_UART_DATA_OE_FLAG   (1 << 11)
+
+	union {
+		/* Same values that are in upper bits of data register*/
+		const ioport32_t status;
+#define PL011_UART_STATUS_FE_FLAG   (1 << 0)
+#define PL011_UART_STATUS_PE_FLAG   (1 << 1)
+#define PL011_UART_STATUS_BE_FLAG   (1 << 2)
+#define PL011_UART_STATUS_OE_FLAG   (1 << 3)
+		/* Writing anything clears all errors */
+		ioport32_t error_clear;
+	};
+	uint32_t padd0_[4];
+
+	const ioport32_t flag;
+#define PL011_UART_FLAG_CTS_FLAG    (1 << 0)
+#define PL011_UART_FLAG_DSR_FLAG    (1 << 1)
+#define PL011_UART_FLAG_DCD_FLAG    (1 << 2)
+#define PL011_UART_FLAG_BUSY_FLAG   (1 << 3)
+#define PL011_UART_FLAG_RXFE_FLAG   (1 << 4)
+#define PL011_UART_FLAG_TXFF_FLAG   (1 << 5)
+#define PL011_UART_FLAG_RXFF_FLAG   (1 << 6)
+#define PL011_UART_FLAG_TXFE_FLAG   (1 << 7)
+#define PL011_UART_FLAG_RI_FLAG     (1 << 8)
+	uint32_t padd1_;
+
+	ioport32_t irda_low_power;
+#define PL011_UART_IRDA_LOW_POWER_MASK   0xff
+
+	ioport32_t int_baud_divisor;
+#define PL011_UART_INT_BAUD_DIVISOR_MASK   0xffff
+
+	ioport32_t fract_baud_divisor;
+#define PL011_UART_FRACT_BAUD_DIVISOR_MASK   0x1f
+
+	ioport32_t line_control_high;
+#define PL011_UART_CONTROLHI_BRK_FLAG    (1 << 0)
+#define PL011_UART_CONTROLHI_PEN_FLAG    (1 << 1)
+#define PL011_UART_CONTROLHI_EPS_FLAG    (1 << 2)
+#define PL011_UART_CONTROLHI_STP2_FLAG   (1 << 3)
+#define PL011_UART_CONTROLHI_FEN_FLAG    (1 << 4)
+#define PL011_UART_CONTROLHI_WLEN_MASK   0x3
+#define PL011_UART_CONTROLHI_WLEN_SHIFT    5
+#define PL011_UART_CONTROLHI_SPS_FLAG    (1 << 5)
+
+	ioport32_t control;
+#define PL011_UART_CONTROL_UARTEN_FLAG   (1 << 0)
+#define PL011_UART_CONTROL_SIREN_FLAG    (1 << 1)
+#define PL011_UART_CONTROL_SIRLP_FLAG    (1 << 2)
+#define PL011_UART_CONTROL_LBE_FLAG      (1 << 7)
+#define PL011_UART_CONTROL_TXE_FLAG      (1 << 8)
+#define PL011_UART_CONTROL_RXE_FLAG      (1 << 9)
+#define PL011_UART_CONTROL_DTR_FLAG     (1 << 10)
+#define PL011_UART_CONTROL_RTS_FLAG     (1 << 11)
+#define PL011_UART_CONTROL_OUT1_FLAG    (1 << 12)
+#define PL011_UART_CONTROL_OUT2_FLAG    (1 << 13)
+#define PL011_UART_CONTROL_RTSE_FLAG    (1 << 14)
+#define PL011_UART_CONTROL_CTSE_FLAG    (1 << 15)
+
+	ioport32_t interrupt_fifo;
+#define PL011_UART_INTERRUPTFIFO_TX_MASK   0x7
+#define PL011_UART_INTERRUPTFIFO_TX_SHIFT    0
+#define PL011_UART_INTERRUPTFIFO_RX_MASK   0x7
+#define PL011_UART_INTERRUPTFIFO_RX_SHIFT    3
+
+	/** Interrupt mask register */
+	ioport32_t interrupt_mask;
+	/** Pending interrupts before applying the mask */
+	const ioport32_t raw_interrupt_status;
+	/** Pending interrupts after applying the mask */
+	const ioport32_t masked_interrupt_status;
+	/** Write 1s to clear pending interrupts */
+	ioport32_t interrupt_clear;
+#define PL011_UART_INTERRUPT_RIM_FLAG    (1 << 0)
+#define PL011_UART_INTERRUPT_CTSM_FLAG   (1 << 1)
+#define PL011_UART_INTERRUPT_DCDM_FLAG   (1 << 2)
+#define PL011_UART_INTERRUPT_DSRM_FLAG   (1 << 3)
+#define PL011_UART_INTERRUPT_RX_FLAG     (1 << 4)
+#define PL011_UART_INTERRUPT_TX_FLAG     (1 << 5)
+#define PL011_UART_INTERRUPT_RT_FLAG     (1 << 6)
+#define PL011_UART_INTERRUPT_FE_FLAG     (1 << 7)
+#define PL011_UART_INTERRUPT_PE_FLAG     (1 << 8)
+#define PL011_UART_INTERRUPT_BE_FLAG     (1 << 9)
+#define PL011_UART_INTERRUPT_OE_FLAG    (1 << 10)
+#define PL011_UART_INTERRUPT_ALL           0x3ff
+
+	ioport32_t dma_control;
+#define PL011_UART_DMACONTROL_RXDMAEN_FLAG    (1 << 0)
+#define PL011_UART_DMACONTROL_TXDMAEN_FLAG    (1 << 1)
+#define PL011_UART_DMACONTROL_DMAONERR_FLAG   (1 << 2)
+
+	// TODO There is some reserved space here followed by
+	// peripheral identification registers.
+} pl011_uart_regs_t;
+
+typedef struct {
+	pl011_uart_regs_t *regs;
+	indev_t *indev;
+	outdev_t outdev;
+	irq_t irq;
+} pl011_uart_t;
+
+bool pl011_uart_init(pl011_uart_t *, inr_t, uintptr_t);
+void pl011_uart_input_wire(pl011_uart_t *, indev_t *);
+
+#endif
+/**
+ * @}
+ */
Index: kernel/genarch/src/drivers/arm926_uart/arm926_uart.c
===================================================================
--- kernel/genarch/src/drivers/arm926_uart/arm926_uart.c	(revision b2fa1204c76e1eaec329888181d281aac04ed61e)
+++ 	(revision )
@@ -1,140 +1,0 @@
-/*
- * Copyright (c) 2012 Jan Vesely
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup genarch
- * @{
- */
-/**
- * @file
- * @brief ARM926 on-chip UART (PrimeCell UART, PL011) driver.
- */
-
-#include <genarch/drivers/arm926_uart/arm926_uart.h>
-#include <console/chardev.h>
-#include <console/console.h>
-#include <ddi/device.h>
-#include <arch/asm.h>
-#include <mm/slab.h>
-#include <mm/page.h>
-#include <mm/km.h>
-#include <sysinfo/sysinfo.h>
-#include <str.h>
-
-static void arm926_uart_sendb(arm926_uart_t *uart, uint8_t byte)
-{
-	/* Wait for space becoming available in Tx FIFO. */
-	// TODO make pio_read accept consts pointers and remove the cast
-	while ((pio_read_32((ioport32_t*)&uart->regs->flag) & ARM926_UART_FLAG_TXFF_FLAG) != 0)
-		;
-
-	pio_write_32(&uart->regs->data, byte);
-}
-
-static void arm926_uart_putchar(outdev_t *dev, wchar_t ch)
-{
-	arm926_uart_t *uart = dev->data;
-
-	if (!ascii_check(ch)) {
-		arm926_uart_sendb(uart, U_SPECIAL);
-	} else {
-		if (ch == '\n')
-			arm926_uart_sendb(uart, (uint8_t) '\r');
-		arm926_uart_sendb(uart, (uint8_t) ch);
-	}
-}
-
-static outdev_operations_t arm926_uart_ops = {
-	.write = arm926_uart_putchar,
-	.redraw = NULL,
-};
-
-static irq_ownership_t arm926_uart_claim(irq_t *irq)
-{
-	return IRQ_ACCEPT;
-}
-
-static void arm926_uart_irq_handler(irq_t *irq)
-{
-	arm926_uart_t *uart = irq->instance;
-
-	// TODO make pio_read accept const pointers and remove the cast
-	while ((pio_read_32((ioport32_t*)&uart->regs->flag) & ARM926_UART_FLAG_RXFE_FLAG) == 0) {
-		/* We ignore all error flags here */
-		const uint8_t data = pio_read_32(&uart->regs->data);
-		if (uart->indev)
-			indev_push_character(uart->indev, data);
-	}
-	/* Ack interrupts */
-	pio_write_32(&uart->regs->interrupt_clear, ARM926_UART_INTERRUPT_ALL);
-}
-
-bool arm926_uart_init(
-    arm926_uart_t *uart, inr_t interrupt, uintptr_t addr, size_t size)
-{
-	ASSERT(uart);
-	uart->regs = (void*)km_map(addr, size, PAGE_NOT_CACHEABLE);
-
-	ASSERT(uart->regs);
-
-	/* Enable hw flow control */
-	uart->regs->control = 0 |
-	    ARM926_UART_CONTROL_UARTEN_FLAG |
-	    ARM926_UART_CONTROL_RTSE_FLAG |
-	    ARM926_UART_CONTROL_CTSE_FLAG;
-
-	/* Mask all interrupts */
-	uart->regs->interrupt_mask = 0;
-
-	outdev_initialize("arm926_uart_dev", &uart->outdev, &arm926_uart_ops);
-	uart->outdev.data = uart;
-
-	/* Initialize IRQ */
-	irq_initialize(&uart->irq);
-        uart->irq.devno = device_assign_devno();
-        uart->irq.inr = interrupt;
-        uart->irq.claim = arm926_uart_claim;
-        uart->irq.handler = arm926_uart_irq_handler;
-        uart->irq.instance = uart;
-
-	return true;
-}
-
-void arm926_uart_input_wire(arm926_uart_t *uart, indev_t *indev)
-{
-	ASSERT(uart);
-	ASSERT(indev);
-
-	uart->indev = indev;
-	irq_register(&uart->irq);
-	/* Enable receive interrupt */
-	uart->regs->interrupt_mask |= ARM926_UART_INTERRUPT_RX_FLAG;
-}
-
-/** @}
- */
-
Index: kernel/genarch/src/drivers/bcm2835/mbox.c
===================================================================
--- kernel/genarch/src/drivers/bcm2835/mbox.c	(revision 6a3d0c7d3c6877f7abc3f9784c37e626fd07986f)
+++ kernel/genarch/src/drivers/bcm2835/mbox.c	(revision 6a3d0c7d3c6877f7abc3f9784c37e626fd07986f)
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2013 Beniamino Galvani
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/** @addtogroup genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief BCM2835 mailbox communication routines
+ */
+
+#include <mm/km.h>
+#include <typedefs.h>
+#include <genarch/drivers/bcm2835/mbox.h>
+
+static void mbox_write(bcm2835_mbox_t *mbox, uint8_t chan, uint32_t value)
+{
+	while (mbox->status & MBOX_STATUS_FULL) ;
+	mbox->write = MBOX_COMPOSE(chan, value);
+}
+
+static uint32_t mbox_read(bcm2835_mbox_t *mbox, uint8_t chan)
+{
+	uint32_t msg;
+
+	do {
+		while (mbox->status & MBOX_STATUS_EMPTY) ;
+		msg = mbox->read;
+	} while (MBOX_MSG_CHAN(msg) != chan);
+
+	return MBOX_MSG_VALUE(msg);
+}
+
+bool bcm2835_prop_get_memory(uint32_t *base, uint32_t *size)
+{
+	bool ret;
+	MBOX_BUFF_ALLOC(req, mbox_getmem_buf_t);
+
+	req->buf_hdr.size = sizeof(mbox_getmem_buf_t);
+	req->buf_hdr.code = MBOX_PROP_CODE_REQ;
+	req->tag_hdr.tag_id = TAG_GET_ARM_MEMORY;
+	req->tag_hdr.buf_size = sizeof(mbox_tag_getmem_resp_t);
+	req->tag_hdr.val_len = 0;
+	req->zero = 0;
+
+	mbox_write((bcm2835_mbox_t *)BCM2835_MBOX0_ADDR,
+		   MBOX_CHAN_PROP_A2V, KA2VCA((uint32_t)req));
+	mbox_read((bcm2835_mbox_t *)BCM2835_MBOX0_ADDR,
+		  MBOX_CHAN_PROP_A2V);
+
+	if (req->buf_hdr.code == MBOX_PROP_CODE_RESP_OK) {
+		*base = req->data.base;
+		*size = req->data.size;
+		ret = true;
+	} else {
+		ret = false;
+	}
+
+	return ret;
+}
+
+bool bcm2835_fb_init(fb_properties_t *prop)
+{
+	bcm2835_mbox_t *fb_mbox;
+	bool ret = false;
+        MBOX_BUFF_ALLOC(fb_desc, bcm2835_fb_desc_t);
+
+	fb_mbox = (void *) km_map(BCM2835_MBOX0_ADDR, sizeof(bcm2835_mbox_t),
+				  PAGE_NOT_CACHEABLE);
+
+	fb_desc->width = 640;
+	fb_desc->height = 480;
+	fb_desc->virt_width = fb_desc->width;
+	fb_desc->virt_height = fb_desc->height;
+	fb_desc->pitch = 0;			/* Set by VC */
+	fb_desc->bpp = 16;
+	fb_desc->x_offset = 0;
+	fb_desc->y_offset = 0;
+	fb_desc->addr = 0;			/* Set by VC */
+	fb_desc->size = 0;			/* Set by VC */
+
+	mbox_write(fb_mbox, MBOX_CHAN_FB, KA2VCA(fb_desc));
+
+	if (mbox_read(fb_mbox, MBOX_CHAN_FB)) {
+		printf("BCM2835 framebuffer initialization failed\n");
+		goto out;
+	}
+
+	prop->addr = fb_desc->addr;
+	prop->offset = 0;
+	prop->x = fb_desc->width;
+	prop->y = fb_desc->height;
+	prop->scan = fb_desc->pitch;
+	prop->visual = VISUAL_RGB_5_6_5_LE;
+
+	printf("BCM2835 framebuffer at 0x%08x (%dx%d)\n", prop->addr,
+	       prop->x, prop->y);
+	ret = true;
+out:
+	km_unmap((uintptr_t)fb_mbox, sizeof(bcm2835_mbox_t));
+	return ret;
+}
+
+/**
+ * @}
+ */
Index: kernel/genarch/src/drivers/pl011/pl011.c
===================================================================
--- kernel/genarch/src/drivers/pl011/pl011.c	(revision 6a3d0c7d3c6877f7abc3f9784c37e626fd07986f)
+++ kernel/genarch/src/drivers/pl011/pl011.c	(revision 6a3d0c7d3c6877f7abc3f9784c37e626fd07986f)
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2012 Jan Vesely
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief ARM PrimeCell PL011 UART driver.
+ */
+
+#include <genarch/drivers/pl011/pl011.h>
+#include <console/chardev.h>
+#include <console/console.h>
+#include <ddi/device.h>
+#include <arch/asm.h>
+#include <mm/slab.h>
+#include <mm/page.h>
+#include <mm/km.h>
+#include <sysinfo/sysinfo.h>
+#include <str.h>
+
+static void pl011_uart_sendb(pl011_uart_t *uart, uint8_t byte)
+{
+	/* Wait for space becoming available in Tx FIFO. */
+	// TODO make pio_read accept consts pointers and remove the cast
+	while ((pio_read_32((ioport32_t*)&uart->regs->flag) & PL011_UART_FLAG_TXFF_FLAG) != 0)
+		;
+
+	pio_write_32(&uart->regs->data, byte);
+}
+
+static void pl011_uart_putchar(outdev_t *dev, wchar_t ch)
+{
+	pl011_uart_t *uart = dev->data;
+
+	if (!ascii_check(ch)) {
+		pl011_uart_sendb(uart, U_SPECIAL);
+	} else {
+		if (ch == '\n')
+			pl011_uart_sendb(uart, (uint8_t) '\r');
+		pl011_uart_sendb(uart, (uint8_t) ch);
+	}
+}
+
+static outdev_operations_t pl011_uart_ops = {
+	.write = pl011_uart_putchar,
+	.redraw = NULL,
+};
+
+static irq_ownership_t pl011_uart_claim(irq_t *irq)
+{
+	return IRQ_ACCEPT;
+}
+
+static void pl011_uart_irq_handler(irq_t *irq)
+{
+	pl011_uart_t *uart = irq->instance;
+
+	// TODO make pio_read accept const pointers and remove the cast
+	while ((pio_read_32((ioport32_t*)&uart->regs->flag) & PL011_UART_FLAG_RXFE_FLAG) == 0) {
+		/* We ignore all error flags here */
+		const uint8_t data = pio_read_32(&uart->regs->data);
+		if (uart->indev)
+			indev_push_character(uart->indev, data);
+	}
+	/* Ack interrupts */
+	pio_write_32(&uart->regs->interrupt_clear, PL011_UART_INTERRUPT_ALL);
+}
+
+bool pl011_uart_init(pl011_uart_t *uart, inr_t interrupt, uintptr_t addr)
+{
+	ASSERT(uart);
+	uart->regs = (void*)km_map(addr, sizeof(pl011_uart_regs_t),
+				   PAGE_NOT_CACHEABLE);
+	ASSERT(uart->regs);
+
+	/* Disable UART */
+	uart->regs->control &= ~ PL011_UART_CONTROL_UARTEN_FLAG;
+
+	/* Enable hw flow control */
+	uart->regs->control |=
+		PL011_UART_CONTROL_RTSE_FLAG |
+		PL011_UART_CONTROL_CTSE_FLAG;
+
+	/* Mask all interrupts */
+	uart->regs->interrupt_mask = 0;
+	/* Clear interrupts */
+	uart->regs->interrupt_clear = PL011_UART_INTERRUPT_ALL;
+	/* Enable UART, TX and RX */
+	uart->regs->control |=
+		PL011_UART_CONTROL_UARTEN_FLAG |
+		PL011_UART_CONTROL_TXE_FLAG |
+		PL011_UART_CONTROL_RXE_FLAG;
+
+	outdev_initialize("pl011_uart_dev", &uart->outdev, &pl011_uart_ops);
+	uart->outdev.data = uart;
+
+	/* Initialize IRQ */
+	irq_initialize(&uart->irq);
+	uart->irq.devno = device_assign_devno();
+	uart->irq.inr = interrupt;
+	uart->irq.claim = pl011_uart_claim;
+	uart->irq.handler = pl011_uart_irq_handler;
+	uart->irq.instance = uart;
+
+	return true;
+}
+
+void pl011_uart_input_wire(pl011_uart_t *uart, indev_t *indev)
+{
+	ASSERT(uart);
+	ASSERT(indev);
+
+	uart->indev = indev;
+	irq_register(&uart->irq);
+	/* Enable receive interrupts */
+	uart->regs->interrupt_mask |=
+		PL011_UART_INTERRUPT_RX_FLAG |
+		PL011_UART_INTERRUPT_RT_FLAG;
+}
+
+/** @}
+ */
+
