--- old/usr/src/lib/libdisasm/common/dis_arm.c	2015-02-07 19:01:07.151100073 -0500
+++ new/usr/src/lib/libdisasm/common/dis_arm.c	2015-02-07 19:01:07.158547603 -0500
@@ -1276,28 +1276,52 @@
 arm_dis_lsexcl(uint32_t in, char *buf, size_t buflen)
 {
 	arm_cond_code_t cc;
-	arm_reg_t rn, rd, rm;
+	arm_reg_t rx, ry, rz;
 	int lbit;
 	size_t len;
 
+	/*
+	 * To make things confusing enough, the names of bitfields between
+	 * ldrex and strex are not totally consistent.  Specifically,
+	 *    STREX rd, rt, [rn]
+	 *       rn = 19:16
+	 *       rd = 15:12
+	 *       rt = 3:0
+	 *
+	 *    LDREX rt, [rn]
+	 *       rn = 19:16
+	 *       rt = 15:12
+	 *
+	 * To avoid having to do too many mental gymnastics, let's just
+	 * think of the bitfields as:
+	 *
+	 *       rx = 19:16
+	 *       ry = 15:12
+	 *       rz = 3:0
+	 *
+	 * And so we print the instructions as:
+	 *    STREX ry, rz, [rx]
+	 *    LDREX ry, [rx]
+	 */
+
 	cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT;
-	rn = (in & ARM_ELS_RN_MASK) >> ARM_ELS_RN_SHIFT;
-	rd = (in & ARM_ELS_RD_MASK) >> ARM_ELS_RD_SHIFT;
-	rm = in & ARM_ELS_RN_MASK;
+	rx = (in & ARM_ELS_RN_MASK) >> ARM_ELS_RN_SHIFT;
+	ry = (in & ARM_ELS_RD_MASK) >> ARM_ELS_RD_SHIFT;
+	rz = (in & ARM_ELS_LOW_AM_MASK);
 	lbit = in & ARM_ELS_LBIT_MASK;
 
 	len = snprintf(buf, buflen, "%s%sex %s, ",
 	    lbit != 0 ? "ldr" : "str",
-	    arm_cond_names[cc], arm_reg_names[rd]);
+	    arm_cond_names[cc], arm_reg_names[ry]);
 	if (len >= buflen)
 		return (-1);
 
 	if (lbit)
 		len += snprintf(buf + len, buflen - len, "[%s]",
-		    arm_reg_names[rn]);
+		    arm_reg_names[rx]);
 	else
 		len += snprintf(buf + len, buflen - len, "%s, [%s]",
-		    arm_reg_names[rm], arm_reg_names[rn]);
+		    arm_reg_names[rz], arm_reg_names[rx]);
 	return (len >= buflen ? -1 : 0);
 }
 
--- old/usr/src/uts/arm/misc/fake_stubs.c	2015-02-07 19:01:07.443666633 -0500
+++ new/usr/src/uts/arm/misc/fake_stubs.c	2015-02-07 19:01:07.450793756 -0500
@@ -62,7 +62,6 @@
 STUB(cas32)
 STUB(cas64)
 STUB(copyoutstr)
-STUB(getfp)
 STUB(htonl)
 STUB(htons)
 STUB(indir)
--- old/usr/src/uts/arm/ml/arm_subr.s	2015-02-07 19:01:07.656697208 -0500
+++ new/usr/src/uts/arm/ml/arm_subr.s	2015-02-07 19:01:07.663784710 -0500
@@ -61,3 +61,8 @@
 	SET_SIZE(arm_smt_pause)
 
 #endif	/* __lint */
+
+	ENTRY(getfp)
+	mov	r0, r9
+	bx	lr
+	SET_SIZE(getfp)
--- old/usr/src/uts/armv6/bcm2835/Makefile.files	2015-02-07 19:01:07.857807969 -0500
+++ new/usr/src/uts/armv6/bcm2835/Makefile.files	2015-02-07 19:01:07.865048330 -0500
@@ -16,9 +16,9 @@
 
 BCM2835_OBJS =			\
 	bcm2835_bsmdep.o	\
+	bcm2835_uart.o		\
 	boot_console.o		\
-	locore.o		\
-	miniuart.o
+	locore.o
 
 BCM2835_LOADER_OBJS = \
 	bcm2835_ldep.o	
--- old/usr/src/uts/armv6/bcm2835/loader/bcm2835_ldep.c	2015-02-07 19:01:08.058058959 -0500
+++ new/usr/src/uts/armv6/bcm2835/loader/bcm2835_ldep.c	2015-02-07 19:01:08.065282011 -0500
@@ -18,38 +18,41 @@
 #include <sys/atag.h>
 
 /*
- * The primary serial console that we end up using is not in fact a normal UART,
- * but is instead actually a mini-uart that shares interrupts and registers with
- * the SPI masters as well. While the RPi also supports another more traditional
- * UART, that isn't what we are actually hooking up to generally with the
- * adafruit cable. We already wasted our time having to figure that out. -_-
+ * The primary serial console that we end up using is the normal UART, not
+ * the mini-uart that shares interrupts and registers with the SPI masters
+ * as well.
  */
 
-#define	AUX_BASE	0x20215000
-#define	AUX_ENABLES	0x4
-#define	AUX_MU_IO_REG	0x40
-#define	AUX_MU_IER_REG	0x44
-#define	AUX_MU_IIR_REG	0x48
-#define	AUX_MU_LCR_REG	0x4C
-#define	AUX_MU_MCR_REG	0x50
-#define	AUX_MU_LSR_REG	0x54
-#define	AUX_MU_CNTL_REG	0x60
-#define	AUX_MU_BAUD	0x68
+#define	UART_BASE		0x20201000
+#define	UART_DR			0x0
+#define	UART_FR			0x18
+#define	UART_IBRD		0x24
+#define	UART_FBRD		0x28
+#define	UART_LCRH		0x2c
+#define	UART_CR			0x30
+#define	UART_ICR		0x44
+
+#define	UART_FR_RXFE		0x10		/* RX fifo empty */
+#define	UART_FR_TXFF		0x20		/* TX fifo full */
+
+#define	UART_LCRH_FEN		0x00000010	/* fifo enable */
+#define	UART_LCRH_WLEN_8	0x00000060	/* 8 bits */
+
+#define	UART_CR_UARTEN		0x001		/* uart enable */
+#define	UART_CR_TXE		0x100		/* TX enable */
+#define	UART_CR_RXE		0x200		/* RX enable */
 
-#define	AUX_MU_RX_READY	0x01
-#define	AUX_MU_TX_READY	0x20
 
 /*
- * For the mini UART, all we care about are pins 14 and 15 for the UART.
- * Specifically, alt5 for GPIO14 is TXD1 and GPIO15 is RXD1. Those are
- * controlled by FSEL1.
+ * All we care about are pins 14 and 15 for the UART.  Specifically, alt0
+ * for GPIO14 is TXD0 and GPIO15 is RXD0. Those are controlled by FSEL1.
  */
 #define	GPIO_BASE	0x20200000
 #define	GPIO_FSEL1	0x4
 #define	GPIO_PUD	0x94
 #define	GPIO_PUDCLK0	0x98
 
-#define	GPIO_SEL_ALT5	0x2
+#define GPIO_SEL_ALT0	0x4
 #define	GPIO_UART_MASK	0xfffc0fff
 #define	GPIO_UART_TX_SHIFT	12
 #define	GPIO_UART_RX_SHIFT	15
@@ -75,7 +78,7 @@
  * A simple nop
  */
 static void
-bcm2835_miniuart_nop(void)
+uart_nop(void)
 {
 	__asm__ volatile("mov r0, r0\n" : : :);
 }
@@ -97,50 +100,37 @@
 	uint32_t v;
 	int i;
 
-	/* Enable the mini UAT */
-	arm_reg_write(AUX_BASE + AUX_ENABLES, 0x1);
-
-	/* Disable interrupts */
-	arm_reg_write(AUX_BASE + AUX_MU_IER_REG, 0x0);
-
-	/* Disable the RX and TX */
-	arm_reg_write(AUX_BASE + AUX_MU_CNTL_REG, 0x0);
-
-	/*
-	 * Enable 8-bit word length. External sources tell us the PRM is buggy
-	 * here and that even though bit 1 is reserved, we need to actually set
-	 * it to get 8-bit words.
-	 */
-	arm_reg_write(AUX_BASE + AUX_MU_LCR_REG, 0x3);
-
-	/* Set RTS high */
-	arm_reg_write(AUX_BASE + AUX_MU_MCR_REG, 0x0);
-
-	/* Disable interrupts */
-	arm_reg_write(AUX_BASE + AUX_MU_IER_REG, 0x0);
-
-	/* Set baud rate */
-	arm_reg_write(AUX_BASE + AUX_MU_IIR_REG, 0xc6);
-	arm_reg_write(AUX_BASE + AUX_MU_BAUD, 0x10e);
+	/* disable UART */
+	arm_reg_write(UART_BASE + UART_CR, 0);
 
 	/* TODO: Factor out the gpio bits */
 	v = arm_reg_read(GPIO_BASE + GPIO_FSEL1);
 	v &= GPIO_UART_MASK;
-	v |= GPIO_SEL_ALT5 << GPIO_UART_RX_SHIFT;
-	v |= GPIO_SEL_ALT5 << GPIO_UART_TX_SHIFT;
+	v |= GPIO_SEL_ALT0 << GPIO_UART_RX_SHIFT;
+	v |= GPIO_SEL_ALT0 << GPIO_UART_TX_SHIFT;
 	arm_reg_write(GPIO_BASE + GPIO_FSEL1, v);
 
 	arm_reg_write(GPIO_BASE + GPIO_PUD, GPIO_PUD_DISABLE);
 	for (i = 0; i < 150; i++)
-		bcm2835_miniuart_nop();
+		uart_nop();
 	arm_reg_write(GPIO_BASE + GPIO_PUDCLK0, GPIO_PUDCLK_UART);
 	for (i = 0; i < 150; i++)
-		bcm2835_miniuart_nop();
-	// XXX: GPIO_PUD_DISABLE again?
+		uart_nop();
 	arm_reg_write(GPIO_BASE + GPIO_PUDCLK0, 0);
 
-	/* Finally, go back and enable RX and TX */
-	arm_reg_write(AUX_BASE + AUX_MU_CNTL_REG, 0x3);
+	/* clear all interrupts */
+	arm_reg_write(UART_BASE + UART_ICR, 0x7ff);
+
+	/* set the baud rate */
+	arm_reg_write(UART_BASE + UART_IBRD, 1);
+	arm_reg_write(UART_BASE + UART_FBRD, 40);
+
+	/* select 8-bit, enable FIFOs */
+	arm_reg_write(UART_BASE + UART_LCRH, UART_LCRH_WLEN_8 | UART_LCRH_FEN);
+
+	/* enable UART */
+	arm_reg_write(UART_BASE + UART_CR, UART_CR_UARTEN | UART_CR_TXE |
+	    UART_CR_RXE);
 }
 
 void
@@ -149,11 +139,11 @@
 	if (c == '\n')
 		fakeload_backend_putc('\r');
 
-	for (;;) {
-		if (arm_reg_read(AUX_BASE + AUX_MU_LSR_REG) & AUX_MU_TX_READY)
-			break;
-	}
-	arm_reg_write(AUX_BASE + AUX_MU_IO_REG, c & 0x7f);
+	while (arm_reg_read(UART_BASE + UART_FR) & UART_FR_TXFF)
+		;
+	arm_reg_write(UART_BASE + UART_DR, c & 0x7f);
+	if (c == '\n')
+		fakeload_backend_putc('\r');
 }
 
 /*
@@ -175,8 +165,8 @@
 
 	aim.aim_header.ah_size = ATAG_ILLUMOS_MAPPING_SIZE;
 	aim.aim_header.ah_tag = ATAG_ILLUMOS_MAPPING;
-	aim.aim_paddr = AUX_BASE;
-	aim.aim_vaddr = AUX_BASE;
+	aim.aim_paddr = UART_BASE;
+	aim.aim_vaddr = UART_BASE;
 	aim.aim_vlen = 0x1000;
 	aim.aim_plen = 0x1000;
 	aim.aim_mapflags = PF_R | PF_W | PF_NORELOC | PF_DEVICE;
--- old/usr/src/uts/armv6/bcm2835/ml/locore.s	2015-02-07 19:01:08.267380840 -0500
+++ new/usr/src/uts/armv6/bcm2835/ml/locore.s	2015-02-07 19:01:08.274586612 -0500
@@ -18,99 +18,11 @@
 #include <sys/machparam.h>
 #include <sys/cpu_asm.h>
 
-/*
- * Every story needs a beginning. This is ours.
- */
-
-/*
- * We are in a primordial world here. The BMC2835 is going to come along and
- * boot us at _start. Normally we would go ahead and use a main() function, but
- * for now, we'll do that ourselves. As we've started the world, we also need to
- * set up a few things about us, for example our stack pointer. To help us out,
- * it's useful to remember the rough memory map. Remember, this is for physcial
- * addresses. There is no virtual memory here. These sizes are often manipulated
- * by the 'configuration' in the bootloader.
- *
- * +----------------+ <---- Max physical memory
- * |                |
- * |                |
- * |                |
- * +----------------+
- * |                |
- * |      I/O       |
- * |  Peripherals   |
- * |                |
- * +----------------+ <---- I/O base 0x20000000 (corresponds to 0x7E000000)
- * |                |
- * |     Main       |
- * |    Memory      |
- * |                |
- * +----------------+ <---- Top of SDRAM
- * |                |
- * |       VC       |
- * |     SDRAM      |
- * |                |
- * +----------------+ <---- Split determined by bootloader config
- * |                |
- * |      ARM       |
- * |     SDRAM      |
- * |                |
- * +----------------+ <---- Bottom of physical memory 0x00000000
- *
- * With the Raspberry Pi Model B, we have 512 MB of SDRAM. That means we have a
- * range of addresses from [0, 0x20000000). If we assume that the minimum amount
- * of DRAM is given to the GPU - 32 MB, that means we really have the following
- * range: [0, 0x1e000000).
- *
- * By default, this binary will be loaded into 0x8000. For now, that means we
- * will set our initial stack to 0x10000000.
- */
-
-/*
- * Recall that _start is the traditional entry point for an ELF binary.
- */
-	ENTRY(_start)
-	ldr sp, =t0stack
-	ldr r4, =DEFAULTSTKSZ
-	add sp, r4
-	bic sp, sp, #0xff
-
-	/*
-	 * establish bogus stacks for exceptional CPU states, our exception
-	 * code should never make use of these, and we want loud and violent
-	 * failure should we accidentally try.
-	 */
-	cps #(CPU_MODE_UND)
-	mov sp, #-1
-	cps #(CPU_MODE_ABT)
-	mov sp, #-1
-	cps #(CPU_MODE_FIQ)
-	mov sp, #-1
-	cps #(CPU_MODE_IRQ)
-	mov sp, #-1
-	cps #(CPU_MODE_SVC)
-
-	/* Enable highvecs (moves the base of the exception vector) */
-	mrc	p15, 0, r3, c1, c0, 0
-	mov	r4, #1
-	lsl	r4, r4, #13
-	orr	r3, r3, r4
-	mcr	p15, 0, r3, c1, c0, 0
-
+	ENTRY(_mach_start)
 	/* Enable access to p10 and p11 (privileged mode only) */
 	mrc	p15, 0, r0, c1, c0, 2
 	orr	r0, #0x00500000
 	mcr	p15, 0, r0, c1, c0, 2
 
-	bl _fakebop_start
-	SET_SIZE(_start)
-
-	ENTRY(arm_reg_read)
-	ldr r0, [r0]
-	bx lr
-	SET_SIZE(arm_reg_read)
-
-	ENTRY(arm_reg_write)
-	str r1, [r0]
-	bx lr
-	SET_SIZE(arm_reg_write)
+	bx	r14
+	SET_SIZE(_mach_start)
--- /dev/null	2015-02-07 19:01:08.000000000 -0500
+++ new/usr/src/uts/armv6/bcm2835/os/bcm2835_uart.c	2015-02-07 19:01:08.474759853 -0500
@@ -0,0 +1,140 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2013 (c) Joyent, Inc.  All rights reserved.
+ * Copyright 2015 (c) Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ */
+
+/*
+ * A simple uart driver for the RPi.
+ */
+#include <sys/types.h>
+
+#include "bcm2835_uart.h"
+
+extern uint32_t arm_reg_read(uint32_t);
+extern void arm_reg_write(uint32_t, uint32_t);
+
+/*
+ * The primary serial console that we end up using is the normal UART, not
+ * the mini-uart that shares interrupts and registers with the SPI masters
+ * as well.
+ */
+
+#define	UART_BASE		0x20201000
+#define	UART_DR			0x0
+#define	UART_FR			0x18
+#define	UART_IBRD		0x24
+#define	UART_FBRD		0x28
+#define	UART_LCRH		0x2c
+#define	UART_CR			0x30
+#define	UART_ICR		0x44
+
+#define	UART_FR_RXFE		0x10		/* RX fifo empty */
+#define	UART_FR_TXFF		0x20		/* TX fifo full */
+
+#define	UART_LCRH_FEN		0x00000010	/* fifo enable */
+#define	UART_LCRH_WLEN_8	0x00000060	/* 8 bits */
+
+#define	UART_CR_UARTEN		0x001		/* uart enable */
+#define	UART_CR_TXE		0x100		/* TX enable */
+#define	UART_CR_RXE		0x200		/* RX enable */
+
+
+/*
+ * All we care about are pins 14 and 15 for the UART.  Specifically, alt0
+ * for GPIO14 is TXD0 and GPIO15 is RXD0. Those are controlled by FSEL1.
+ */
+#define	GPIO_BASE	0x20200000
+#define	GPIO_FSEL1	0x4
+#define	GPIO_PUD	0x94
+#define	GPIO_PUDCLK0	0x98
+
+#define GPIO_SEL_ALT0	0x4
+#define	GPIO_UART_MASK	0xfffc0fff
+#define	GPIO_UART_TX_SHIFT	12
+#define	GPIO_UART_RX_SHIFT	15
+
+#define	GPIO_PUD_DISABLE	0x0
+#define	GPIO_PUDCLK_UART	0x0000c000
+
+/*
+ * A simple nop
+ */
+static void
+bcm2835_uart_nop(void)
+{
+	__asm__ volatile("mov r0, r0\n" : : :);
+}
+
+void
+bcm2835_uart_init(void)
+{
+	uint32_t v;
+	int i;
+
+	/* disable UART */
+	arm_reg_write(UART_BASE + UART_CR, 0);
+
+	/* TODO: Factor out the gpio bits */
+	v = arm_reg_read(GPIO_BASE + GPIO_FSEL1);
+	v &= GPIO_UART_MASK;
+	v |= GPIO_SEL_ALT0 << GPIO_UART_RX_SHIFT;
+	v |= GPIO_SEL_ALT0 << GPIO_UART_TX_SHIFT;
+	arm_reg_write(GPIO_BASE + GPIO_FSEL1, v);
+
+	arm_reg_write(GPIO_BASE + GPIO_PUD, GPIO_PUD_DISABLE);
+	for (i = 0; i < 150; i++)
+		bcm2835_uart_nop();
+	arm_reg_write(GPIO_BASE + GPIO_PUDCLK0, GPIO_PUDCLK_UART);
+	for (i = 0; i < 150; i++)
+		bcm2835_uart_nop();
+	arm_reg_write(GPIO_BASE + GPIO_PUDCLK0, 0);
+
+	/* clear all interrupts */
+	arm_reg_write(UART_BASE + UART_ICR, 0x7ff);
+
+	/* set the baud rate */
+	arm_reg_write(UART_BASE + UART_IBRD, 1);
+	arm_reg_write(UART_BASE + UART_FBRD, 40);
+
+	/* select 8-bit, enable FIFOs */
+	arm_reg_write(UART_BASE + UART_LCRH, UART_LCRH_WLEN_8 | UART_LCRH_FEN);
+
+	/* enable UART */
+	arm_reg_write(UART_BASE + UART_CR, UART_CR_UARTEN | UART_CR_TXE |
+	    UART_CR_RXE);
+}
+
+void
+bcm2835_uart_putc(uint8_t c)
+{
+	while (arm_reg_read(UART_BASE + UART_FR) & UART_FR_TXFF)
+		;
+	arm_reg_write(UART_BASE + UART_DR, c & 0x7f);
+	if (c == '\n')
+		bcm2835_uart_putc('\r');
+}
+
+uint8_t
+bcm2835_uart_getc(void)
+{
+	while (arm_reg_read(UART_BASE + UART_FR) & UART_FR_RXFE)
+		;
+	return (arm_reg_read(UART_BASE + UART_DR) & 0x7f);
+}
+
+int
+bcm2835_uart_isc(void)
+{
+	return ((arm_reg_read(UART_BASE + UART_FR) & UART_FR_RXFE) == 0);
+}
--- /dev/null	2015-02-07 19:01:08.000000000 -0500
+++ new/usr/src/uts/armv6/bcm2835/os/bcm2835_uart.h	2015-02-07 19:01:08.579005969 -0500
@@ -0,0 +1,39 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2013 (c) Joyent, Inc.  All rights reserved.
+ * Copyright 2015 (c) Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ */
+
+#ifndef _BCM2835_UART_H
+#define	_BCM2835_UART_H
+
+/*
+ * Interface to the BCM2835's uart.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+
+void bcm2835_uart_init(void);
+void bcm2835_uart_putc(uint8_t);
+uint8_t bcm2835_uart_getc(void);
+int bcm2835_uart_isc(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BCM2835_UART_H */
--- old/usr/src/uts/armv6/bcm2835/os/boot_console.c	2015-02-07 19:01:08.677275475 -0500
+++ new/usr/src/uts/armv6/bcm2835/os/boot_console.c	2015-02-07 19:01:08.684486931 -0500
@@ -17,12 +17,12 @@
  * bcm2835 boot console implementation
  */
 
-#include "miniuart.h"
+#include "bcm2835_uart.h"
 
 /*
  * There are a few different potential boot consoles that we could have on the
  * bcm2835. There is both a mini uart and a full functioning uart. Generally,
- * people will use the mini uart, but we want to support both. As such we have a
+ * people will use one of them, but we want to support both. As such we have a
  * single global ops vector that we set once during bcons_init and never again.
  */
 #define	BMC2835_CONSNAME_MAX	24
@@ -36,15 +36,15 @@
 static bcm2835_consops_t consops;
 
 /*
- * For now, we only support the mini uart.
+ * For now, we only support the real uart.
  */
 void
 bcons_init(char *bstr)
 {
-	bcm2835_miniuart_init();
-	consops.bco_putc = bcm2835_miniuart_putc;
-	consops.bco_getc = bcm2835_miniuart_getc;
-	consops.bco_isc = bcm2835_miniuart_isc;
+	bcm2835_uart_init();
+	consops.bco_putc = bcm2835_uart_putc;
+	consops.bco_getc = bcm2835_uart_getc;
+	consops.bco_isc = bcm2835_uart_isc;
 }
 
 void
--- old/usr/src/uts/armv6/bcm2835/os/miniuart.c	2015-02-07 19:01:08.886983254 -0500
+++ /dev/null	2015-02-07 19:01:08.000000000 -0500
@@ -1,150 +0,0 @@
-/*
- * This file and its contents are supplied under the terms of the
- * Common Development and Distribution License ("CDDL"), version 1.0.
- * You may only use this file in accordance with the terms of version
- * 1.0 of the CDDL.
- *
- * A full copy of the text of the CDDL should have accompanied this
- * source.  A copy of the CDDL is also available via the Internet at
- * http://www.illumos.org/license/CDDL.
- */
-
-/*
- * Copyright 2013 (c) Joyent, Inc.  All rights reserved.
- */
-
-/*
- * A simple uart driver for the RPi.
- */
-#include <sys/types.h>
-
-extern uint32_t arm_reg_read(uint32_t);
-extern void arm_reg_write(uint32_t, uint32_t);
-
-/*
- * The primary serial console that we end up using is not in fact a normal UART,
- * but is instead actually a mini-uart that shares interrupts and registers with
- * the SPI masters as well. While the RPi also supports another more traditional
- * UART, that isn't what we are actually hooking up to generally with the
- * adafruit cable. We already wasted our time having to figure that out. -_-
- */
-
-#define	AUX_BASE	0x20215000
-#define	AUX_ENABLES	0x4
-#define	AUX_MU_IO_REG	0x40
-#define	AUX_MU_IER_REG	0x44
-#define	AUX_MU_IIR_REG	0x48
-#define	AUX_MU_LCR_REG	0x4C
-#define	AUX_MU_MCR_REG	0x50
-#define	AUX_MU_LSR_REG	0x54
-#define	AUX_MU_CNTL_REG	0x60
-#define	AUX_MU_BAUD	0x68
-
-#define	AUX_MU_RX_READY	0x01
-#define	AUX_MU_TX_READY	0x20
-
-/*
- * For the mini UART, all we care about are pins 14 and 15 for the UART.
- * Specifically, alt5 for GPIO14 is TXD1 and GPIO15 is RXD1. Those are
- * controlled by FSEL1.
- */
-#define	GPIO_BASE	0x20200000
-#define	GPIO_FSEL1	0x4
-#define	GPIO_PUD	0x94
-#define	GPIO_PUDCLK0	0x98
-
-#define	GPIO_SEL_ALT5	0x2
-#define	GPIO_UART_MASK	0xfffc0fff
-#define	GPIO_UART_TX_SHIFT	12
-#define	GPIO_UART_RX_SHIFT	15
-
-#define	GPIO_PUD_DISABLE	0x0
-#define	GPIO_PUDCLK_UART	0x0000c000
-
-/*
- * A simple nop
- */
-static void
-bcm2835_miniuart_nop(void)
-{
-	__asm__ volatile("mov r0, r0\n" : : :);
-}
-
-void
-bcm2835_miniuart_init(void)
-{
-	uint32_t v;
-	int i;
-
-	/* Enable the mini UAT */
-	arm_reg_write(AUX_BASE + AUX_ENABLES, 0x1);
-
-	/* Disable interrupts */
-	arm_reg_write(AUX_BASE + AUX_MU_IER_REG, 0x0);
-
-	/* Disable the RX and TX */
-	arm_reg_write(AUX_BASE + AUX_MU_CNTL_REG, 0x0);
-
-	/*
-	 * Enable 8-bit word length. External sources tell us the PRM is buggy
-	 * here and that even though bit 1 is reserved, we need to actually set
-	 * it to get 8-bit words.
-	 */
-	arm_reg_write(AUX_BASE + AUX_MU_LCR_REG, 0x3);
-
-	/* Set RTS high */
-	arm_reg_write(AUX_BASE + AUX_MU_MCR_REG, 0x0);
-
-	/* Disable interrupts */
-	arm_reg_write(AUX_BASE + AUX_MU_IER_REG, 0x0);
-
-	/* Set baud rate */
-	arm_reg_write(AUX_BASE + AUX_MU_IIR_REG, 0xc6);
-	arm_reg_write(AUX_BASE + AUX_MU_BAUD, 0x10e);
-
-	/* TODO: Factor out the gpio bits */
-	v = arm_reg_read(GPIO_BASE + GPIO_FSEL1);
-	v &= GPIO_UART_MASK;
-	v |= GPIO_SEL_ALT5 << GPIO_UART_RX_SHIFT;
-	v |= GPIO_SEL_ALT5 << GPIO_UART_TX_SHIFT;
-	arm_reg_write(GPIO_BASE + GPIO_FSEL1, v);
-
-	arm_reg_write(GPIO_BASE + GPIO_PUD, GPIO_PUD_DISABLE);
-	for (i = 0; i < 150; i++)
-		bcm2835_miniuart_nop();
-	arm_reg_write(GPIO_BASE + GPIO_PUDCLK0, GPIO_PUDCLK_UART);
-	for (i = 0; i < 150; i++)
-		bcm2835_miniuart_nop();
-	arm_reg_write(GPIO_BASE + GPIO_PUDCLK0, 0);
-
-	/* Finally, go back and enable RX and TX */
-	arm_reg_write(AUX_BASE + AUX_MU_CNTL_REG, 0x3);
-}
-
-void
-bcm2835_miniuart_putc(uint8_t c)
-{
-	for (;;) {
-		if (arm_reg_read(AUX_BASE + AUX_MU_LSR_REG) & AUX_MU_TX_READY)
-			break;
-	}
-	arm_reg_write(AUX_BASE + AUX_MU_IO_REG, c & 0x7f);
-	if (c == '\n')
-		bcm2835_miniuart_putc('\r');
-}
-
-uint8_t
-bcm2835_miniuart_getc(void)
-{
-	for (;;) {
-		if (arm_reg_read(AUX_BASE + AUX_MU_LSR_REG) & AUX_MU_RX_READY)
-			break;
-	}
-	return (arm_reg_read(AUX_BASE + AUX_MU_IO_REG) & 0x7f);
-}
-
-int
-bcm2835_miniuart_isc(void)
-{
-	return (arm_reg_read(AUX_BASE + AUX_MU_LSR_REG) & AUX_MU_RX_READY);
-}
--- old/usr/src/uts/armv6/bcm2835/os/miniuart.h	2015-02-07 19:01:08.963865370 -0500
+++ /dev/null	2015-02-07 19:01:08.000000000 -0500
@@ -1,38 +0,0 @@
-/*
- * This file and its contents are supplied under the terms of the
- * Common Development and Distribution License ("CDDL"), version 1.0.
- * You may only use this file in accordance with the terms of version
- * 1.0 of the CDDL.
- *
- * A full copy of the text of the CDDL should have accompanied this
- * source.  A copy of the CDDL is also available via the Internet at
- * http://www.illumos.org/license/CDDL.
- */
-
-/*
- * Copyright 2013 (c) Joyent, Inc.  All rights reserved.
- */
-
-#ifndef _BCM2835_MINIUART_H
-#define	_BCM2835_MINIUART_H
-
-/*
- * Interface to the BCM2835's miniuart.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/types.h>
-
-void bcm2835_miniuart_init(void);
-void bcm2835_miniuart_putc(uint8_t);
-uint8_t bcm2835_miniuart_getc(void);
-int bcm2835_miniuart_isc(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _BCM2835_MINIUART_H */
--- old/usr/src/uts/armv6/ml/cache.s	2015-02-07 19:01:09.039852594 -0500
+++ new/usr/src/uts/armv6/ml/cache.s	2015-02-07 19:01:09.046999117 -0500
@@ -172,7 +172,7 @@
 
 	ENTRY(armv6_dcache_enable)
 	mrc	p15, 0, r0, c1, c0, 0
-	orr	r0, #0x2
+	orr	r0, #0x4
 	mcr	p15, 0, r0, c1, c0, 0
 	SET_SIZE(armv6_dcache_enable)
 
@@ -184,7 +184,7 @@
 
 	ENTRY(armv6_dcache_disable)
 	mrc	p15, 0, r0, c1, c0, 0
-	bic	r0, #0x2
+	bic	r0, #0x4
 	mcr	p15, 0, r0, c1, c0, 0
 	SET_SIZE(armv6_dcache_disable)
 
--- old/usr/src/uts/armv6/ml/glocore.s	2015-02-07 19:01:09.248682926 -0500
+++ new/usr/src/uts/armv6/ml/glocore.s	2015-02-07 19:01:09.255934240 -0500
@@ -20,14 +20,29 @@
 
 #include "assym.h"
 
-#if defined(__lint)
-
-#endif
+/*
+ * Every story needs a beginning. This is ours.
+ */
 
 /*
  * Each of the different machines has its own locore.s to take care of getting
- * us into fakebop for the first time. After that, they all return here to a
- * generic locore to take us into mlsetup and then to main forever more.
+ * the machine specific setup done.  Just before jumping into fakebop the
+ * first time, we call this machine specific code.
+ */
+
+/*
+ * We are in a primordial world here. The loader is going to come along and
+ * boot us at _start. As we've started the world, we also need to set up a
+ * few things about us, for example our stack pointer. To help us out, it's
+ * useful to remember what the loader set up for us:
+ *
+ * - unaligned access are allowed (A = 0, U = 1)
+ * - virtual memory is enabled
+ *   - we (unix) are mapped right were we want to be
+ *   - a UART has been enabled & any memory mapped registers have been 1:1
+ *     mapped
+ *   - ATAGs have been updated to tell us what the mappings are
+ * - I/D L1 caches have been enabled
  */
 
 	/*
@@ -44,6 +59,43 @@
 	.comm	t0stack, DEFAULTSTKSZ, 32
 	.comm	t0, 4094, 32
 
+
+/*
+ * Recall that _start is the traditional entry point for an ELF binary.
+ */
+	ENTRY(_start)
+	ldr	sp, =t0stack
+	ldr	r4, =DEFAULTSTKSZ
+	add	sp, r4
+	bic	sp, sp, #0xff
+
+	/*
+	 * establish bogus stacks for exceptional CPU states, our exception
+	 * code should never make use of these, and we want loud and violent
+	 * failure should we accidentally try.
+	 */
+	cps	#(CPU_MODE_UND)
+	mov	sp, #-1
+	cps	#(CPU_MODE_ABT)
+	mov	sp, #-1
+	cps	#(CPU_MODE_FIQ)
+	mov	sp, #-1
+	cps	#(CPU_MODE_IRQ)
+	mov	sp, #-1
+	cps	#(CPU_MODE_SVC)
+
+	/* Enable highvecs (moves the base of the exception vector) */
+	mrc	p15, 0, r3, c1, c0, 0
+	orr	r3, r3, #(1 << 13)
+	mcr	p15, 0, r3, c1, c0, 0
+
+	/* invoke machine specific setup */
+	bl	_mach_start
+
+	bl	_fakebop_start
+	SET_SIZE(_start)
+
+
 #if defined(__lint)
 
 /* ARGSUSED */
@@ -59,7 +111,6 @@
 	 * then main. We're never going back so we shouldn't feel compelled to
 	 * preserve any registers.
 	 *
-	 *  o Enable unaligned access
 	 *  o Enable our I/D-caches
 	 *  o Save the boot syscalls and bootops for later
 	 *  o Set up our stack to be the real stack of t0stack.
@@ -111,16 +162,11 @@
 	mcr	p15, 0, r0, c13, c0, 4
 
 	/*
-	 * Go ahead now and enable unaligned access, the L1 I/D caches.
-	 *
-	 * Bit 2 is for the D cache
-	 * Bit 12 is for the I cache
-	 * Bit 22 is for unaligned access
+	 * Go ahead now and enable the L1 I/D caches.  
 	 */
 	mrc	p15, 0, r0, c1, c0, 0
-	orr	r0, #0x02
-	orr	r0, #0x1000
-	orr	r0, #0x400000
+	orr	r0, #0x04	/* D-cache */
+	orr	r0, #0x1000	/* I-cache */
 	mcr	p15, 0, r0, c1, c0, 0
 
 	/*
@@ -148,3 +194,13 @@
 __return_from_main:
 	.string "main() returned"
 #endif	/* __lint */
+
+	ENTRY(arm_reg_read)
+	ldr r0, [r0]
+	bx lr
+	SET_SIZE(arm_reg_read)
+
+	ENTRY(arm_reg_write)
+	str r1, [r0]
+	bx lr
+	SET_SIZE(arm_reg_write)
--- old/usr/src/uts/armv6/os/fakebop.c	2015-02-07 19:01:09.454509470 -0500
+++ new/usr/src/uts/armv6/os/fakebop.c	2015-02-07 19:01:09.462000339 -0500
@@ -34,6 +34,7 @@
 #include <sys/cpu_asm.h>
 #include <sys/boot_mmu.h>
 #include <sys/elf.h>
+#include <sys/archsystm.h>
 
 static bootops_t bootop;
 
@@ -113,10 +114,41 @@
 
 static bootprop_t *bprops = NULL;
 
+static void
+hexdump_stack()
+{
+	extern char t0stack[];
+
+	uint8_t *start = (uint8_t *)t0stack;
+	uint8_t *end = start + DEFAULTSTKSZ;
+	uint8_t *ptr;
+	int i;
+
+	bop_printf(NULL, "stack (fp = %x):\n", getfp());
+
+	ptr = (uint8_t *)(getfp() & ~0xf);
+	if (ptr <= start || ptr >= end)
+		ptr = start;
+
+	while (ptr < end) {
+		uint32_t *tmp = (uint32_t *)ptr;
+
+		bop_printf(NULL, "%p: %08x %08x %08x %08x\n", ptr,
+		    tmp[0], tmp[1], tmp[2], tmp[3]);
+
+		ptr += 16;
+	}
+
+}
+
 void
 bop_panic(const char *msg)
 {
-	bop_printf(NULL, "ARM bop_panic:\n%s\nSpinning Forever...", msg);
+	bop_printf(NULL, "ARM bop_panic:\n%s\n", msg);
+
+	hexdump_stack();
+
+	bop_printf(NULL, "Spinning Forever...", msg);
 	for (;;)
 		;
 }
--- old/usr/src/uts/armv6/qvpb/ml/locore.s	2015-02-07 19:01:09.684717916 -0500
+++ new/usr/src/uts/armv6/qvpb/ml/locore.s	2015-02-07 19:01:09.691887105 -0500
@@ -11,100 +11,14 @@
 
 /*
  * Copyright 2013 (c) Joyent, Inc. All rights reserved.
+ * Copyright 2015 (c) Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
  */
 
 #include <sys/asm_linkage.h>
 #include <sys/machparam.h>
 #include <sys/cpu_asm.h>
 
-/*
- * Every story needs a beginning. This is ours.
- */
-
-/*
- * We are in a primordial world here. The BMC2835 is going to come along and
- * boot us at _start. Normally we would go ahead and use a main() function, but
- * for now, we'll do that ourselves. As we've started the world, we also need to
- * set up a few things about us, for example our stack pointer. To help us out,
- * it's useful to remember the rough memory map. Remember, this is for physcial
- * addresses. There is no virtual memory here. These sizes are often manipulated
- * by the 'configuration' in the bootloader.
- *
- * +----------------+ <---- Max physical memory
- * |                |
- * |                |
- * |                |
- * +----------------+
- * |                |
- * |      I/O       |
- * |  Peripherals   |
- * |                |
- * +----------------+ <---- I/O base 0x20000000 (corresponds to 0x7E000000)
- * |                |
- * |     Main       |
- * |    Memory      |
- * |                |
- * +----------------+ <---- Top of SDRAM
- * |                |
- * |       VC       |
- * |     SDRAM      |
- * |                |
- * +----------------+ <---- Split determined by bootloader config
- * |                |
- * |      ARM       |
- * |     SDRAM      |
- * |                |
- * +----------------+ <---- Bottom of physical memory 0x00000000
- *
- * With the Raspberry Pi Model B, we have 512 MB of SDRAM. That means we have a
- * range of addresses from [0, 0x20000000). If we assume that the minimum amount
- * of DRAM is given to the GPU - 32 MB, that means we really have the following
- * range: [0, 0x1e000000).
- *
- * By default, this binary will be loaded into 0x8000. For now, that means we
- * will set our initial stack to 0x10000000.
- */
-
-/*
- * Recall that _start is the traditional entry point for an ELF binary.
- */
-	ENTRY(_start)
-	ldr sp, =t0stack
-	ldr r4, =DEFAULTSTKSZ
-	add sp, r4
-	bic sp, sp, #0xff
-
-	/*
-	 * establish bogus stacks for exceptional CPU states, our exception
-	 * code should never make use of these, and we want loud and violent
-	 * failure should we accidentally try.
-	 */
-	cps #(CPU_MODE_UND)
-	mov sp, #-1
-	cps #(CPU_MODE_ABT)
-	mov sp, #-1
-	cps #(CPU_MODE_FIQ)
-	mov sp, #-1
-	cps #(CPU_MODE_IRQ)
-	mov sp, #-1
-	cps #(CPU_MODE_SVC)
-
-	/* Enable highvecs (moves the base of the exception vector) */
-	mrc	p15, 0, r3, c1, c0, 0
-	mov	r4, #1
-	lsl	r4, r4, #13
-	orr	r3, r3, r4
-	mcr	p15, 0, r3, c1, c0, 0
-
-	bl _fakebop_start
-	SET_SIZE(_start)
-
-	ENTRY(arm_reg_read)
-	ldr r0, [r0]
-	bx lr
-	SET_SIZE(arm_reg_read)
-
-	ENTRY(arm_reg_write)
-	str r1, [r0]
-	bx lr
-	SET_SIZE(arm_reg_write)
+	ENTRY(_mach_start)
+	/* nothing to do */
+	bx	r14
+	SET_SIZE(_mach_start)
