Index: kernel/genarch/include/genarch/drivers/arm926_uart/arm926_uart.h
===================================================================
--- kernel/genarch/include/genarch/drivers/arm926_uart/arm926_uart.h	(revision 208b5f542c8db6c9ce6844cd62a6794e94185293)
+++ 	(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 61b5b73da4751fa87cc6b1c1d81fe4796bc905e1)
+++ kernel/genarch/include/genarch/drivers/bcm2835/irc.h	(revision 61b5b73da4751fa87cc6b1c1d81fe4796bc905e1)
@@ -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 61b5b73da4751fa87cc6b1c1d81fe4796bc905e1)
+++ kernel/genarch/include/genarch/drivers/bcm2835/mbox.h	(revision 61b5b73da4751fa87cc6b1c1d81fe4796bc905e1)
@@ -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 61b5b73da4751fa87cc6b1c1d81fe4796bc905e1)
+++ kernel/genarch/include/genarch/drivers/bcm2835/timer.h	(revision 61b5b73da4751fa87cc6b1c1d81fe4796bc905e1)
@@ -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 61b5b73da4751fa87cc6b1c1d81fe4796bc905e1)
+++ kernel/genarch/include/genarch/drivers/pl011/pl011.h	(revision 61b5b73da4751fa87cc6b1c1d81fe4796bc905e1)
@@ -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
+/**
+ * @}
+ */
