diff --git a/sys/arch/arm/arm32/kobj_machdep.c b/sys/arch/arm/arm32/kobj_machdep.c
index 901d01f..6ff9326 100644
--- a/sys/arch/arm/arm32/kobj_machdep.c
+++ b/sys/arch/arm/arm32/kobj_machdep.c
@@ -93,6 +93,31 @@ kobj_reloc(kobj_t ko, uintptr_t relocbase, const void *data,
 	case R_ARM_NONE:	/* none */
 		break;
 
+	case R_ARM_PC24: {	/* S - PC + (SignExt(A & 0xffffff)) << 2  */
+		Elf_Addr tmp;
+
+		/* Truncate (and sign-extend if needed) 24-bit addend */
+		addend &= 0x00ffffff;
+		if (addend & 0x00800000)
+			addend |= 0xff000000;
+
+		addr = kobj_sym_lookup(ko, symidx);
+		if (addr == 0)
+			return -1;
+		tmp = addr - (Elf_Addr)where + (addend << 2);
+		printf("kobj_reloc: R_PC24 relocation @ %p -- base = %#lx, addr = %#lx, addend = %#lx, out = %#lx\n", where, (long)relocbase, (long)addr, (long)addend, (long)tmp);
+		if ((tmp & 0xfe000000) != 0xfe000000 &&
+		    (tmp & 0xfe000000) != 0) {
+			printf("kobj_reloc: failed R_PC24 relocation @ %p (disp %ld (%#lx) out of range)\n", where, (long)tmp, (long)tmp);
+			return -1;
+		}
+
+		tmp >>= 2;
+		if ((*where & 0x00ffffff) != (tmp & 0x00ffffff))
+			*where = (*where & 0xff000000) | (tmp & 0x00ffffff);
+		break;
+	}
+
 	case R_ARM_ABS32:
 		addr = kobj_sym_lookup(ko, symidx);
 		if (addr == 0)
@@ -125,7 +150,7 @@ kobj_reloc(kobj_t ko, uintptr_t relocbase, const void *data,
 		break;
 
 	default:
-		printf("kobj_reloc: unexpected relocation type %d\n", rtype);
+		printf("kobj_reloc: unexpected relocation type %d @ %p\n", rtype, where);
 		return -1;
 	}
 	return 0;
diff --git a/sys/arch/evbarm/conf/IPAQ3900 b/sys/arch/evbarm/conf/IPAQ3900
new file mode 100644
index 0000000..de34b38
--- /dev/null
+++ b/sys/arch/evbarm/conf/IPAQ3900
@@ -0,0 +1,244 @@
+#
+#	IPAQ3900 -- evbarm kernel for Compaq iPAQ 3900 handheld.
+#
+
+include	"arch/evbarm/conf/std.ipaq3900"
+
+# estimated number of users
+
+maxusers	32
+
+# Standard system options
+
+options 	RTC_OFFSET=0	# hardware clock is this many mins. west of GMT
+#options 	NTP		# NTP phase/frequency locked loop
+
+# CPU options
+
+options 	CPU_XSCALE_PXA250	# Support the XScale core
+#options 	XSCALE_CACHE_WRITE_THROUGH
+#options 	XSCALE_CACHE_WRITE_BACK
+makeoptions	CPUFLAGS="-mcpu=xscale"
+
+# Architecture options
+
+# File systems
+
+file-system	FFS		# UFS
+#file-system	LFS		# log-structured file system
+file-system	MFS		# memory file system
+file-system	NFS		# Network file system
+#file-system 	ADOSFS		# AmigaDOS-compatible file system
+#file-system 	EXT2FS		# second extended file system (linux)
+#file-system	CD9660		# ISO 9660 + Rock Ridge file system
+file-system	MSDOSFS		# MS-DOS file system
+#file-system	FDESC		# /dev/fd
+file-system	KERNFS		# /kern
+#file-system	NULLFS		# loopback file system
+#file-system	PORTAL		# portal filesystem (still experimental)
+#file-system	PROCFS		# /proc
+#file-system	UMAPFS		# NULLFS + uid and gid remapping
+#file-system	UNION		# union file system
+file-system	PTYFS		# /dev/pts/N support
+
+# File system options
+#options 	QUOTA		# UFS quotas
+#options 	FFS_EI		# FFS Endian Independant support
+#options 	NFSSERVER
+#options 	SOFTDEP
+#options 	FFS_NO_SNAPSHOT	# No FFS snapshot support
+
+# Networking options
+
+#options 	GATEWAY		# packet forwarding
+options 	INET		# IP + ICMP + TCP + UDP
+#options 	INET6		# IPV6
+#options 	IPSEC		# IP security
+#options 	IPSEC_ESP	# IP security (encryption part; define w/ IPSEC)
+#options 	IPSEC_NAT_T	# IPsec NAT traversal (NAT-T)
+#options 	IPSEC_DEBUG	# debug for IP security
+#options 	MROUTING	# IP multicast routing
+#options 	PIM		# Protocol Independent Multicast
+#options 	ISO,TPIP	# OSI
+#options 	EON		# OSI tunneling over IP
+#options 	NETATALK	# AppleTalk networking
+#options 	PFIL_HOOKS	# pfil(9) packet filter hooks
+#options 	PPP_BSDCOMP	# BSD-Compress compression support for PPP
+#options 	PPP_DEFLATE	# Deflate compression support for PPP
+#options 	PPP_FILTER	# Active filter support for PPP (requires bpf)
+#options 	TCP_DEBUG	# Record last TCP_NDEBUG packets with SO_DEBUG
+
+#options 	NFS_BOOT_BOOTP
+options 	NFS_BOOT_DHCP
+#options 	NFS_BOOT_BOOTPARAM
+
+# Compatibility options
+
+#options 	COMPAT_43	# 4.3BSD compatibility.
+options 	COMPAT_30	# NetBSD 3.0 compatibility.
+#options 	COMPAT_20	# NetBSD 2.0 compatibility.
+#options 	COMPAT_16	# NetBSD 1.6 compatibility.
+#options 	COMPAT_15	# NetBSD 1.5 compatibility.
+#options 	COMPAT_14	# NetBSD 1.4 compatibility.
+#options 	COMPAT_13	# NetBSD 1.3 compatibility.
+#options 	COMPAT_12	# NetBSD 1.2 compatibility.
+#options 	COMPAT_11	# NetBSD 1.1 compatibility.
+#options 	COMPAT_10	# NetBSD 1.0 compatibility.
+#options 	COMPAT_09	# NetBSD 0.9 compatibility.
+#options 	TCP_COMPAT_42	# 4.2BSD TCP/IP bug compat. Not recommended.
+options		COMPAT_BSDPTY	# /dev/[pt]ty?? ptys.
+
+# Shared memory options
+
+#options 	SYSVMSG		# System V-like message queues
+#options 	SYSVSEM		# System V-like semaphores
+#options 	SEMMNI=10	# number of semaphore identifiers
+#options 	SEMMNS=60	# number of semaphores in system
+#options 	SEMUME=10	# max number of undo entries per process
+#options 	SEMMNU=30	# number of undo structures in system
+#options 	SYSVSHM		# System V-like memory sharing
+#options 	SHMMAXPGS=1024	# 1024 pages is the default
+
+# Device options
+
+# NB: MEMORYDISK stuff left for IPAQ3900_INSTALL kernel
+
+# Miscellaneous kernel options
+options 	KTRACE		# system call tracing, a la ktrace(1)
+options 	MODULAR		# NWO of loadable kernel modules
+#options 	KMEMSTATS	# kernel memory statistics
+options 	PCMCIAVERBOSE	# verbose PCMCIA configuration messages
+#options 	SCSIVERBOSE	# Verbose SCSI errors
+#options 	MIIVERBOSE	# Verbose MII autoconfuration messages
+#options 	DDB_KEYCODE=0x40
+#options 	USERCONF	# userconf(4) support
+
+# Development and Debugging options
+
+options 	DIAGNOSTIC	# internally consistency checks
+options 	EVBARM_SPL_NOINLINE
+options		INSECURE
+#options 	DEBUG
+#options 	PMAP_DEBUG	# Enable pmap_debug_level code
+options 	VERBOSE_INIT_ARM # verbose bootstraping messages
+options 	DDB		# in-kernel debugger
+#options 	DDB_HISTORY_SIZE=100	# Enable history editing in DDB
+#options 	KGDB
+#options  	DEBUG_KGDB
+#makeoptions	DEBUG="-g"	# compile full symbol table
+#options 	SYMTAB_SPACE=200000
+
+config		netbsd		root on ? type ?
+
+# The main bus device
+mainbus0	at root
+
+# The boot cpu
+cpu0		at mainbus?
+
+# integrated peripherals
+pxaip0	at mainbus?
+
+pxaintc0 at pxaip?	# interrupt controller
+pxagpio0 at pxaip?	# GPIO
+options PXAGPIO_HAS_GPION_INTRS
+
+pxartc0	at pxaip?	# RTC
+
+
+# cotulla integrated 16550 UARTs
+options COM_PXA2X0
+com0	at pxaip?  addr 0x40100000 intr 22      # Full Function UART
+com1	at pxaip?  addr 0x40200000 intr 21 	# BlueTootth UART
+com2	at pxaip?  addr 0x40700000 intr 20	# Standard UART (for IrDA)
+#com3	at pxaip?  addr 0x41600000 intr 7	# Hardware UART(console-hw, -bt)
+options FFUARTCONSOLE
+options BTUARTCONSOLE
+options KGDB_DEVNAME="\"btuart\""   # ffuart or btuart
+options KGDB_DEVRATE=115200
+
+# DMAC support
+pxadmac0 	at pxaip? addr 0x40000000 intr 25
+options 	PXA2X0_DMAC_DMOVER_CONCURRENCY=4 # Enable dmover(9) backend
+#options 	PXA2X0_DMAC_FIXED_PRIORITY	 # Don't want multiple priority
+
+# AC97 Audio support
+pxaacu0 	at pxaip? addr 0x40500000 intr 14
+audio*		at audiobus?
+
+# LCD
+lcd0	   at pxaip?
+wsdisplay* at lcd? console ?
+options 	WSEMUL_VT100		# VT100 / VT220 emulation
+options 	FONT_VT220L8x8
+options 	FONT_VT220L8x10
+
+# integrated PCMCIA/CF controller
+pxapcic0 at pxaip?
+
+# PCMCIA bus support
+pcmcia*	at pxapcic?
+
+# PCMCIA serial interfaces
+com*	at pcmcia? function ?		# Modems and serial cards
+
+##pcmcom*	at pcmcia? function ?		# PCMCIA multi-port serial cards
+##com*	at pcmcom? slave ?		# ...and the slave devices
+
+# PCMCIA SCSI controllers
+##aic*	at pcmcia? function ?		# Adaptec APA-1460 SCSI
+##esp*	at pcmcia? function ?		# Qlogic ESP406/FAS408 SCSI
+
+# SCSI devices
+##st*	at scsibus? target ? lun ?	# SCSI tape drives
+##cd*	at scsibus? target ? lun ?	# SCSI CD-ROM drives
+##ch*	at scsibus? target ? lun ?	# SCSI autochangers
+##ses*	at scsibus? target ? lun ?	# SCSI Enclosure Services devices
+##ss*	at scsibus? target ? lun ?	# SCSI scanners
+
+# PCMCIA IDE controllers and disks
+##wdc*	at pcmcia? function ?
+##atabus* 	at wdc? channel ?
+##wd*		at atabus? drive ? flags 0x0000
+
+#
+# Networking devices
+#
+##an*	at pcmcia? function ?		# Aironet PC4500/PC4800 (802.11)
+##awi*	at pcmcia? function ?		# BayStack 650/660 (802.11FH/DS)
+##cnw*	at pcmcia? function ?		# Xircom/Netwave AirSurfer
+##ep*	at pcmcia? function ?		# 3Com 3c589 and 3c562 Ethernet
+##mbe*	at pcmcia? function ?		# MB8696x based Ethernet
+ne*	at pcmcia? function ?		# NE2000-compatible Ethernet
+##ray*	at pcmcia? function ?		# Raytheon Raylink (802.11)
+##sm*	at pcmcia? function ?		# Megahertz Ethernet
+##tr*	at pcmcia? function ?		# TROPIC based Token-Ring
+wi*	at pcmcia? function ?		# Lucent/Intersil WaveLan IEEE (802.11)
+##xirc*	at pcmcia? function ?		# Xircom CreditCard Ethernet
+##com*	at xirc?
+##xi*	at xirc?
+
+##mhzc*	at pcmcia? function ?		# Megahertz Ethernet/Modem combo cards
+##com*	at mhzc?
+##sm*	at mhzc?
+
+# PCMCIA audio devices
+###esl*	at pcmcia? function ?			# ESS 1688 AudioDrive
+
+# Pseudo-Devices
+
+# disk/mass storage pseudo-devices
+#pseudo-device	vnd			# disk-like interface to files
+#pseudo-device	fss		4	# file system snapshot device
+
+# network pseudo-devices
+pseudo-device	bpfilter		# Berkeley packet filter
+pseudo-device	loop			# network loopback
+
+# miscellaneous pseudo-devices
+pseudo-device	pty			# pseudo-terminals
+pseudo-device	rnd			# /dev/random and in-kernel generator
+#options	RND_COM			# XXXrkb: can deadlock due to use of
+					# timer, etc. locks at IPL > IPL_SCHED
+pseudo-device	ksyms			# /dev/ksyms
+
diff --git a/sys/arch/evbarm/conf/IPAQ3900_INSTALL b/sys/arch/evbarm/conf/IPAQ3900_INSTALL
new file mode 100644
index 0000000..7328a96
--- /dev/null
+++ b/sys/arch/evbarm/conf/IPAQ3900_INSTALL
@@ -0,0 +1,8 @@
+#	$NetBSD$
+#
+#	IPAQ3900_INSTALL -- IPAQ3900 kernel with installation-sized
+#	ramdisk
+#
+
+include "arch/evbarm/conf/IPAQ3900"
+include "arch/evbarm/conf/INSTALL"
diff --git a/sys/arch/evbarm/conf/files.ipaq3900 b/sys/arch/evbarm/conf/files.ipaq3900
new file mode 100644
index 0000000..2a76bb4
--- /dev/null
+++ b/sys/arch/evbarm/conf/files.ipaq3900
@@ -0,0 +1,23 @@
+#	$NetBSD: files.ipaq3900,v 1.6 2005/12/11 12:17:07 christos Exp $
+#
+# Compaq iPAQ 3900 system configuration info
+#
+
+file	arch/evbarm/ipaq3900/ipaq3900_machdep.c
+
+# CPU support and integrated peripherals
+include "arch/arm/xscale/files.pxa2x0"
+
+#include "dev/sdmmc/files.sdmmc"
+
+# PCMCIA/CF socket
+attach  pxapcic at pxaip with pxapcic_ipaq3900_pcic
+file    arch/evbarm/ipaq3900/ipaq3900_pcic.c		pxapcic_ipaq3900_pcic
+
+# PXA2x0 MMC/SD controller
+#attach	pxamci at pxaip with ipaq3900_mci
+#file	arch/evbarm/ipaq3900/ipaq3900_mci.c		ipaq3900_mci
+
+# LCD frame buffer
+attach lcd at pxaip with ipaq3900_lcd
+file arch/evbarm/ipaq3900/ipaq3900_lcd.c		ipaq3900_lcd
diff --git a/sys/arch/evbarm/conf/mk.ipaq3900 b/sys/arch/evbarm/conf/mk.ipaq3900
new file mode 100644
index 0000000..287e343
--- /dev/null
+++ b/sys/arch/evbarm/conf/mk.ipaq3900
@@ -0,0 +1,8 @@
+#	$NetBSD: mk.ipaq3900,v 1.1 2003/01/03 02:16:28 thorpej Exp $
+
+SYSTEM_FIRST_OBJ=	ipaq3900_start.o
+SYSTEM_FIRST_SFILE=	${THISARM}/ipaq3900/ipaq3900_start.S
+
+KERNEL_BASE_PHYS=0xa0200000
+KERNEL_BASE_VIRT=0xc0200000
+
diff --git a/sys/arch/evbarm/conf/std.ipaq3900 b/sys/arch/evbarm/conf/std.ipaq3900
new file mode 100644
index 0000000..04f6ecb
--- /dev/null
+++ b/sys/arch/evbarm/conf/std.ipaq3900
@@ -0,0 +1,30 @@
+#	$NetBSD: std.lubbock,v 1.6 2008/01/27 12:37:12 chris Exp $
+#
+# standard NetBSD/evbarm for IPAQ3900 options
+
+machine	evbarm arm
+include		"conf/std"	# MI standard options
+include		"arch/arm/conf/std.arm"	# arch standard options
+
+# Pull in IPAQ3900 config definitions.
+include "arch/evbarm/conf/files.ipaq3900"
+
+options 	COTULLA
+options 	IPAQ3900
+options 	EXEC_ELF32
+options 	EXEC_SCRIPT
+
+# To support easy transit to ../arch/arm/arm32
+options 	ARM32
+
+options 	KERNEL_BASE_EXT=0xc0000000
+makeoptions	LOADADDRESS="0xc0200000"
+makeoptions	BOARDTYPE="ipaq3900"
+makeoptions	BOARDMKFRAG="${THISARM}/conf/mk.ipaq3900"
+
+options 	ARM_INTR_IMPL="<arch/arm/xscale/pxa2x0_intr.h>"
+
+# OS Timer    This is compatible to SA1110's OS Timer.
+saost*	at pxaip? addr 0x40a00000 size 0x20
+
+
diff --git a/sys/arch/evbarm/ipaq3900/ipaq3900_lcd.c b/sys/arch/evbarm/ipaq3900/ipaq3900_lcd.c
new file mode 100644
index 0000000..689355b
--- /dev/null
+++ b/sys/arch/evbarm/ipaq3900/ipaq3900_lcd.c
@@ -0,0 +1,226 @@
+/* $NetBSD: ipaq3900_lcd.c,v 1.7 2007/03/04 05:59:45 christos Exp $ */
+
+/*
+ * Copyright (c) 2002, 2003  Genetec Corporation.  All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. The name of Genetec Corporation may not be used to endorse or 
+ *    promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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.
+ */
+
+/*
+ * LCD driver for Intel Lubbock.
+ *
+ * Controlling LCD is almost completely done through PXA2X0's
+ * integrated LCD controller.  Codes for it is arm/xscale/pxa2x0_lcd.c.
+ *
+ * Codes in this file provide platform specific things including:
+ *   LCD on/off switch in on-board PLD register.
+ *   LCD panel geometry
+ */
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: ipaq3900_lcd.c,v 1.7 2007/03/04 05:59:45 christos Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/uio.h>
+#include <sys/malloc.h>
+
+#include <dev/cons.h> 
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsdisplayvar.h> 
+#include <dev/wscons/wscons_callbacks.h>
+
+#include <machine/bus.h>
+#include <arm/xscale/pxa2x0var.h>
+#include <arm/xscale/pxa2x0reg.h>
+#include <arm/xscale/pxa2x0_lcd.h>
+
+#include <hpc/include/bootinfo.h>
+#include <evbarm/ipaq3900/ipaq3900_reg.h>
+
+int	lcd_match( struct device *, struct cfdata *, void *);
+void	lcd_attach( struct device *, struct device *, void *);
+int	lcdintr(void *);
+
+static void 	lcd_power_control(int);
+
+/*
+ * wsdisplay glue
+ */
+static struct pxa2x0_wsscreen_descr lcd_std_screen = {
+	.c = {
+		.name = "std",
+		.textops = &pxa2x0_lcd_emulops,
+		.fontwidth = 8,
+		.fontheight = 8,
+		.capabilities = WSSCREEN_WSCOLORS,
+	},
+	.depth = 16,			/* bits per pixel */
+};
+
+static const struct wsscreen_descr *lcd_scr_descr[] = {
+	&lcd_std_screen.c
+};
+
+static const struct wsscreen_list lcd_screen_list = {
+	.nscreens = __arraycount(lcd_scr_descr),
+	.screens = lcd_scr_descr,
+};
+
+int	lcd_ioctl(void *, void *, u_long, void *, int, struct lwp *);
+
+int	lcd_show_screen(void *, void *, int,
+	    void (*)(void *, int, int), void *);
+
+const struct wsdisplay_accessops lcd_accessops = {
+	lcd_ioctl,
+	pxa2x0_lcd_mmap,
+	pxa2x0_lcd_alloc_screen,
+	pxa2x0_lcd_free_screen,
+	lcd_show_screen,
+	NULL, /* load_font */
+};
+
+CFATTACH_DECL(ipaq3900_lcd, sizeof (struct pxa2x0_lcd_softc),  lcd_match,
+    lcd_attach, NULL, NULL);
+
+int
+lcd_match( struct device *parent, struct cfdata *cf, void *aux )
+{
+	return 1;
+}
+
+static const struct lcd_panel_geometry ipaq_3900 =
+{
+    320,			/* Width */
+    240,			/* Height */
+    0,				/* No extra lines */
+
+    LCDPANEL_ACTIVE|LCDPANEL_HSP|LCDPANEL_VSP,
+    10,				/* clock divider */
+    0,				/* AC bias pin freq */
+
+    3,				/* horizontal sync pulse width */
+    12,				/* BLW */
+    17,				/* ELW */
+
+    3,				/* vertical sync pulse width */
+    6,				/* BFW */
+    17,				/* EFW */
+
+};
+
+void lcd_attach( struct device *parent, struct device *self, void *aux )
+{
+	int is_console = !(bootinfo->bi_cnuse & BI_CNUSE_SERIAL);
+	struct pxa2x0_lcd_softc *sc = (struct pxa2x0_lcd_softc *)self;
+	struct wsemuldisplaydev_attach_args aa;
+
+	if (is_console)
+		pxa2x0_lcd_cnattach(&lcd_std_screen, &ipaq_3900);
+
+	pxa2x0_lcd_attach_sub(sc, aux, &ipaq_3900);
+
+	/* make wsdisplay screen list */
+	pxa2x0_lcd_setup_wsscreen(&lcd_std_screen, &ipaq_3900, NULL);
+	lcd_power_control(1);
+
+	aa.console = is_console;
+	aa.scrdata = &lcd_screen_list;
+	aa.accessops = &lcd_accessops;
+	aa.accesscookie = sc;
+
+	printf( "\n" );
+
+	(void) config_found(self, &aa, wsemuldisplaydevprint);
+}
+
+int
+lcd_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
+{
+	switch (cmd) {
+	case WSDISPLAYIO_SVIDEO:
+		if (*(int *)data == WSDISPLAYIO_VIDEO_ON)
+			lcd_power_control(1);
+		else
+			lcd_power_control(0);
+		break;			/* turn on/off LCD controller */
+	}
+	return pxa2x0_lcd_ioctl( v, vs, cmd, data, flag, l );
+}
+
+int
+lcd_show_screen(void *v, void *cookie, int waitok,
+    void (*cb)(void *, int, int), void *cbarg)
+{
+	pxa2x0_lcd_show_screen(v,cookie,waitok,cb,cbarg);
+	lcd_power_control(1);
+
+	return (0);
+}
+
+static void
+lcd_power_control(int on)
+{
+	if (on) {
+		/*
+		 * Set up backlight params:
+		 *	H3800_ASIC2_CLOCK_Enable    |= ASIC2_CLOCK_PWM;
+		 *	if ( level < 21 ) level = 21; 
+		 *	if ( level > 64 ) level = 64;
+		 *	H3800_ASIC2_PWM_0_DutyTime = level;
+		 *	H3800_ASIC2_PWM_0_TimeBase |= 
+		 *				PWM_TIMEBASE_ENABLE;
+		 *
+		 * Backlight on:
+		 * 	H3900_ASIC3_GPIO_B_OUT |= GPIO3_FL_PWR_ON;
+		 */
+		ioreg16_write(IPAQ3900_ASIC3_VBASE + 0x108,
+		    ioreg16_read(IPAQ3900_ASIC3_VBASE + 0x108) |
+			(1 << 5) |	/* GPIO3_LCD_5V_ON */
+			(1 << 6) |	/* GPIO3_LCD_ON */
+			(1 << 7) |	/* GPIO3_LCD_PCI */
+			(1 << 1) |	/* GPIO3_LCD_9V_ON */
+			(1 << 3));	/* GPIO3_LCD_NV_ON */
+	} else {
+		/*
+		 * Backlight off:
+		 * 	H3900_ASIC3_GPIO_B_OUT &= ~GPIO3_FL_PWR_ON;
+		 *
+		 * Clean up backlight params:
+		 *	H3800_ASIC2_PWM_0_TimeBase &= 
+		 *			~PWM_TIMEBASE_ENABLE;
+		 *	H3800_ASIC2_CLOCK_Enable &= ~ASIC2_CLOCK_PWM;
+		 */
+		ioreg16_write(IPAQ3900_ASIC3_VBASE + 0x108,
+		    ioreg16_read(IPAQ3900_ASIC3_VBASE + 0x108) &
+			~((1 << 5) |	/* GPIO3_LCD_5V_ON */
+			  (1 << 6) |	/* GPIO3_LCD_ON */
+			  (1 << 7) |	/* GPIO3_LCD_PCI */
+			  (1 << 1) |	/* GPIO3_LCD_9V_ON */
+			  (1 << 3)));	/* GPIO3_LCD_NV_ON */
+	}
+}
diff --git a/sys/arch/evbarm/ipaq3900/ipaq3900_machdep.c b/sys/arch/evbarm/ipaq3900/ipaq3900_machdep.c
new file mode 100644
index 0000000..c920096
--- /dev/null
+++ b/sys/arch/evbarm/ipaq3900/ipaq3900_machdep.c
@@ -0,0 +1,1254 @@
+/*	$NetBSD: ipaq3900_machdep.c,v 1.17 2008/01/19 13:11:16 chris Exp $ */
+
+/*
+ * Copyright (c) 2002, 2003, 2005  Genetec Corporation.  All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. The name of Genetec Corporation may not be used to endorse or 
+ *    promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * 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.
+ *
+ * Machine dependant functions for kernel setup for 
+ * Intel DBPXA250 evaluation board (a.k.a. Lubbock).
+ * Based on iq80310_machhdep.c
+ */
+/*
+ * Copyright (c) 2001 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+
+/*
+ * Copyright (c) 1997,1998 Mark Brinicombe.
+ * Copyright (c) 1997,1998 Causality Limited.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Mark Brinicombe
+ *	for the NetBSD Project.
+ * 4. The name of the company nor the name of the author may 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 OR CONTRIBUTORS 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.
+ *
+ * Machine dependant functions for kernel setup for Intel IQ80310 evaluation
+ * boards using RedBoot firmware.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: ipaq3900_machdep.c,v 1.17 2008/01/19 13:11:16 chris Exp $");
+
+#include "opt_ddb.h"
+#include "opt_kgdb.h"
+#include "opt_pmap_debug.h"
+#include "opt_md.h"
+#include "opt_com.h"
+#include "md.h"
+#include "lcd.h"
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/exec.h>
+#include <sys/proc.h>
+#include <sys/msgbuf.h>
+#include <sys/reboot.h>
+#include <sys/boot_flag.h>
+#include <sys/termios.h>
+#include <sys/ksyms.h>
+#include <sys/module.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <sys/conf.h>
+#include <dev/cons.h>
+#include <dev/md.h>
+
+#include <machine/db_machdep.h>
+#include <ddb/db_sym.h>
+#include <ddb/db_extern.h>
+#ifdef KGDB
+#include <sys/kgdb.h>
+#endif
+
+#ifndef DB_ELFSIZE
+#error Must define DB_ELFSIZE!
+#endif
+#define ELFSIZE		DB_ELFSIZE
+#include <sys/exec_elf.h>
+
+#include <machine/bootconfig.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/frame.h>
+#include <arm/undefined.h>
+
+#include <arm/arm32/machdep.h>
+#include <hpc/include/bootinfo.h>
+
+#include <arm/xscale/pxa2x0reg.h>
+#include <arm/xscale/pxa2x0var.h>
+#include <arm/xscale/pxa2x0_gpio.h>
+#include <arm/sa11x0/sa11x0_ostreg.h>
+#include <evbarm/ipaq3900/ipaq3900_reg.h>
+
+/* Kernel text starts 2MB in from the bottom of the kernel address space. */
+#define	KERNEL_TEXT_BASE	(KERNEL_BASE + 0x00200000)
+#define	KERNEL_VM_BASE		(KERNEL_BASE + 0x01000000)
+
+/*
+ * The range 0xc1000000 - 0xccffffff is available for kernel VM space
+ * Core-logic registers and I/O mappings occupy 0xfd000000 - 0xffffffff
+ */
+#define KERNEL_VM_SIZE		0x0C000000
+
+
+/*
+ * Address to call from cpu_reset() to reset the machine.
+ * This is machine architecture dependant as it varies depending
+ * on where the ROM appears when you turn the MMU off.
+ */
+
+u_int cpu_reset_address = 0;
+
+/* Define various stack sizes in pages */
+#define IRQ_STACK_SIZE	1
+#define ABT_STACK_SIZE	1
+#define UND_STACK_SIZE	1
+
+vm_offset_t physical_start;
+vm_offset_t physical_freestart;
+vm_offset_t physical_freeend;
+vm_offset_t physical_end;
+u_int free_pages;
+vm_offset_t pagetables_start;
+int physmem = 0;
+
+/*int debug_flags;*/
+#ifndef PMAP_STATIC_L1S
+int max_processes = 64;			/* Default number */
+#endif	/* !PMAP_STATIC_L1S */
+
+/* Physical and virtual addresses for some global pages */
+pv_addr_t systempage;
+pv_addr_t irqstack;
+pv_addr_t undstack;
+pv_addr_t abtstack;
+pv_addr_t kernelstack;
+pv_addr_t minidataclean;
+
+vm_offset_t msgbufphys;
+
+extern char etext[], _end[];
+extern u_int data_abort_handler_address;
+extern u_int prefetch_abort_handler_address;
+extern u_int undefined_handler_address;
+
+#ifdef PMAP_DEBUG
+extern int pmap_debug_level;
+#endif
+
+#define KERNEL_PT_SYS		0	/* Page table for mapping proc0 zero page */
+#define KERNEL_PT_KERNEL	1	/* Page table for mapping kernel */
+#define	KERNEL_PT_KERNEL_NUM	4
+#define KERNEL_PT_VMDATA	(KERNEL_PT_KERNEL+KERNEL_PT_KERNEL_NUM)
+				        /* Page tables for mapping kernel VM */
+#define	KERNEL_PT_VMDATA_NUM	4	/* start with 16MB of KVM */
+#define NUM_KERNEL_PTS		(KERNEL_PT_VMDATA + KERNEL_PT_VMDATA_NUM)
+
+pv_addr_t kernel_pt_table[NUM_KERNEL_PTS];
+
+struct user *proc0paddr;
+
+struct hpcboot_args {
+	int			argc;
+	char**			argv;
+	struct bootinfo*	bi;
+};
+
+
+char boot_file[16];
+BootConfig bootconfig;		/* Boot config storage */
+char *boot_args = NULL;
+static char booted_kernel_storage[80];
+struct bootinfo *bootinfo, bootinfo_storage;
+char *booted_kernel = booted_kernel_storage;
+
+/* Prototypes */
+
+void	consinit(void);
+void	kgdb_port_init(void);
+void	change_clock(uint32_t v);
+
+#ifdef BOOT_DUMP
+void	dumppages(char *, int);
+#endif
+
+bs_protos(bs_notimpl);
+
+#include "com.h"
+#if NCOM > 0
+#include <dev/ic/comreg.h>
+#include <dev/ic/comvar.h>
+#endif
+
+#ifndef CONSPEED
+#define CONSPEED B115200	/* What RedBoot uses */
+#endif
+#ifndef CONMODE
+#define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
+#endif
+
+int comcnspeed = CONSPEED;
+int comcnmode = CONMODE;
+
+static struct pxa2x0_gpioconf boarddep_gpioconf[] = {
+	{ 44, GPIO_ALT_FN_1_IN },	/* BTCST */
+	{ 45, GPIO_ALT_FN_2_OUT },	/* BTRST */
+
+	{ 29, GPIO_ALT_FN_1_IN },	/* SDATA_IN0 */
+
+	{ -1 }
+};
+
+static struct pxa2x0_gpioconf *ipaq3900_gpioconf[] = {
+	pxa25x_com_btuart_gpioconf,
+	pxa25x_com_ffuart_gpioconf,
+	pxa25x_com_stuart_gpioconf,
+	pxa25x_pcic_gpioconf,
+	pxa25x_pxaacu_gpioconf,
+	boarddep_gpioconf,
+	NULL
+};
+
+/*
+ * void cpu_reboot(int howto, char *bootstr)
+ *
+ * Reboots the system
+ *
+ * Deal with any syncing, unmounting, dumping and shutdown hooks,
+ * then reset the CPU.
+ */
+void
+cpu_reboot(int howto, char *bootstr)
+{
+#ifdef DIAGNOSTIC
+	/* info */
+	printf("boot: howto=%08x curproc=%p\n", howto, curproc);
+#endif
+
+	/*
+	 * If we are still cold then hit the air brakes
+	 * and crash to earth fast
+	 */
+	if (cold) {
+		doshutdownhooks();
+		printf("The operating system has halted.\n");
+		printf("Please press any key to reboot.\n\n");
+		cngetc();
+		printf("rebooting...\n");
+		cpu_reset();
+		/*NOTREACHED*/
+	}
+
+	/* Disable console buffering */
+/*	cnpollc(1);*/
+
+	/*
+	 * If RB_NOSYNC was not specified sync the discs.
+	 * Note: Unless cold is set to 1 here, syslogd will die during the
+	 * unmount.  It looks like syslogd is getting woken up only to find
+	 * that it cannot page part of the binary in as the filesystem has
+	 * been unmounted.
+	 */
+	if (!(howto & RB_NOSYNC))
+		bootsync();
+
+	/* Say NO to interrupts */
+	splhigh();
+
+	/* Do a dump if requested. */
+	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
+		dumpsys();
+	
+	/* Run any shutdown hooks */
+	doshutdownhooks();
+
+	/* Make sure IRQ's are disabled */
+	IRQdisable;
+
+	if (howto & RB_HALT) {
+		printf("The operating system has halted.\n");
+		printf("Please press any key to reboot.\n\n");
+		cngetc();
+	}
+
+	printf("rebooting...\n");
+	cpu_reset();
+	/*NOTREACHED*/
+}
+
+/*
+ * Static device mappings. These peripheral registers are mapped at
+ * fixed virtual addresses very early in initarm() so that we can use
+ * them while booting the kernel, and stay at the same address
+ * throughout whole kernel's life time.
+ *
+ * We use this table twice; once with bootstrap page table, and once
+ * with kernel's page table which we build up in initarm().
+ *
+ * Since we map these registers into the bootstrap page table using
+ * pmap_devmap_bootstrap() which calls pmap_map_chunk(), we map
+ * registers segment-aligned and segment-rounded in order to avoid
+ * using the 2nd page tables.
+ */
+
+#define	_A(a)	((a) & ~L1_S_OFFSET)
+#define	_S(s)	(((s) + L1_S_SIZE - 1) & ~(L1_S_SIZE-1))
+
+static const struct pmap_devmap ipaq3900_devmap[] = {
+    {
+	    IPAQ3900_GPIO_VBASE,
+	    _A(PXA2X0_GPIO_BASE),
+	    _S(PXA250_GPIO_SIZE),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE,
+    },
+    {
+	    IPAQ3900_CLKMAN_VBASE,
+	    _A(PXA2X0_CLKMAN_BASE),
+	    _S(PXA2X0_CLKMAN_SIZE),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE,
+    },
+    {
+	    IPAQ3900_INTCTL_VBASE,
+	    _A(PXA2X0_INTCTL_BASE),
+	    _S(PXA2X0_INTCTL_SIZE),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE,
+    },
+    {
+	    IPAQ3900_FFUART_VBASE,
+	    _A(PXA2X0_FFUART_BASE),
+	    _S(4 * COM_NPORTS),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE,
+    },
+    {
+	    IPAQ3900_BTUART_VBASE,
+	    _A(PXA2X0_BTUART_BASE),
+	    _S(4 * COM_NPORTS),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE,
+    },
+    {
+	    IPAQ3900_STUART_VBASE,
+	    _A(PXA2X0_STUART_BASE),
+	    _S(4 * COM_NPORTS),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE,
+    },
+    {
+	    IPAQ3900_ASIC2_VBASE,
+	    _A(0x15000000),
+	    _S(0x1000),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE,
+    },
+    {
+	    IPAQ3900_ASIC3_VBASE,
+	    _A(0x14800000),
+	    _S(0x2000),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE,
+    },
+    {
+	    IPAQ3900_ASIC3_SD_VBASE,
+	    _A(0x14000000),
+	    _S(0x2000),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE,
+    },
+    {0, 0, 0, 0,}
+};
+
+#undef	_A
+#undef	_S
+
+/*
+ * u_int initarm(...)
+ *
+ * Initial entry point on startup. This gets called before main() is
+ * entered.
+ * It should be responsible for setting up everything that must be
+ * in place when main is called.
+ * This includes
+ *   Taking a copy of the boot configuration structure.
+ *   Initialising the physical console so characters can be printed.
+ *   Setting up page tables for the kernel
+ *   Relocating the kernel to the bottom of physical memory
+ */
+u_int
+initarm(void *arg)
+{
+	extern vaddr_t xscale_cache_clean_addr;
+	int loop;
+	int loop1;
+	u_int l1pagetable;
+	paddr_t memstart;
+	psize_t memsize;
+	size_t symbolsize = 0;
+	int dbg_value = '0';
+#ifdef BOOT_DUMP
+	vm_offset_t setup_pages_start;
+	vm_offset_t setup_pages_end;
+#endif
+#ifdef DIAGNOSTIC
+	extern vsize_t xscale_minidata_clean_size; /* used in KASSERT */
+#endif
+	struct hpcboot_args* hpc_boot_args = arg; 
+
+#define LEDSTEP_P()							 \
+	do {								 \
+		while (!(ioreg8_read(PXA2X0_FFUART_BASE + 0x14) & 0x20)) \
+			/* EMPTY */;					 \
+		ioreg8_write(PXA2X0_FFUART_BASE + 0x00, dbg_value++);	 \
+		while (!(ioreg8_read(PXA2X0_FFUART_BASE + 0x14) & 0x20)) \
+			/* EMPTY */;					 \
+		ioreg8_read(PXA2X0_FFUART_BASE + 0x08);			 \
+	} while (0)
+	
+#define LEDSTEP()							    \
+	do {								    \
+		while (!(ioreg8_read(IPAQ3900_FFUART_VBASE + 0x14) & 0x20)) \
+			/* EMPTY */;					    \
+		ioreg8_write(IPAQ3900_FFUART_VBASE + 0x00, dbg_value++);    \
+		while (!(ioreg8_read(IPAQ3900_FFUART_VBASE + 0x14) & 0x20)) \
+			; /* EMPTY */					    \
+		ioreg8_read(IPAQ3900_FFUART_VBASE + 0x08);     		    \
+	} while (0)
+
+	/*
+	 * XXXrkb: grotty stuff to keep interrupts from blowing us out of
+	 * the water before we're ready.  Should probably be pushed into
+	 * the drivers, though it's good to get the HW in a sane state
+	 * regardless of which drivers are/aren't configured in.
+	 */
+
+	/* Init ASIC3 GPIO mask / output / direction registers */
+	ioreg16_write(IPAQ3900_ASIC3_VBASE + 0x100, 0xffff);
+	ioreg16_write(IPAQ3900_ASIC3_VBASE + 0x108, 0x0004);
+	ioreg16_write(IPAQ3900_ASIC3_VBASE + 0x104, 0xffff);
+
+	/* Disable RTC HZ/alarm interrupts, clear status */
+	ioreg_write(PXA2X0_RTC_BASE + RTC_RTSR, 0x03);
+
+	/* Disable OS timer match interrupts, clear status */
+	ioreg_write(PXA2X0_OST_BASE + SAOST_IR, 0);
+	ioreg_write(PXA2X0_OST_BASE + SAOST_SR, 
+	    ioreg_read(PXA2X0_OST_BASE + SAOST_SR));
+
+	/* Disable LCD 'disable done' interrupt, disable LCD controller */
+	ioreg_write(PXA2X0_LCDC_BASE + LCDC_LCCR0, 
+	    ioreg_read(PXA2X0_LCDC_BASE + LCDC_LCCR0) | LCCR0_LDM);
+	ioreg_write(PXA2X0_LCDC_BASE + LCDC_LCCR0, 
+	    ioreg_read(PXA2X0_LCDC_BASE + LCDC_LCCR0) | LCCR0_DIS);
+
+	/* ACK any outstanding LCD controller interrupts */
+	ioreg_write(PXA2X0_LCDC_BASE + LCDC_LCSR, 
+	    ioreg_read(PXA2X0_LCDC_BASE + LCDC_LCSR));
+
+	/* use physical address until at least bootstrap devmap is set up */
+	LEDSTEP_P();
+
+	/* register the static device map (mapped by startup asm code) */
+	pmap_devmap_register(ipaq3900_devmap);
+
+	LEDSTEP_P();
+
+	/* start 32.768 kHz OSC */
+	ioreg_write(IPAQ3900_CLKMAN_VBASE + 0x08, 2);
+	/* Get ready for splfoo() */
+	pxa2x0_intr_bootstrap(IPAQ3900_INTCTL_VBASE);
+
+	LEDSTEP();
+
+	/*
+	 * Heads up ... Setup the CPU / MMU / TLB functions
+	 */
+	if (set_cpufuncs())
+		panic("cpu not recognized!");
+
+	LEDSTEP();
+
+
+#if 0
+	/* Calibrate the delay loop. */
+#endif
+
+	/*
+	 * Okay, RedBoot has provided us with the following memory map:
+	 *
+	 * XXXrkb: no RedBoot, but it might be useful to document the
+	 * machine's address map here anyway (and any specifics of how
+	 * Windows / hpcboot or the CRL bootloader sets up the machine).
+	 *
+	 * Physical Address Range     Description 
+	 * -----------------------    ---------------------------------- 
+	 * 0x00000000 - 0x01ffffff    flash Memory   (32MB)
+	 * 0x04000000 - 0x05ffffff    Application flash Memory  (32MB)
+	 * 0x08000000 - 0x080000ff    I/O baseboard registers
+	 * 0x0a000000 - 0x0a0fffff    SRAM (1MB)
+	 * 0x0c000000 - 0x0c0fffff    Ethernet Controller
+	 * 0x0e000000 - 0x0e0fffff    Ethernet Controller (Attribute)
+	 * 0x10000000 - 0x103fffff    SA-1111 Companion Chip
+	 * 0x14000000 - 0x17ffffff    Expansion Card (64MB)
+	 * 0x40000000 - 0x480fffff    Processor Registers
+	 * 0xa0000000 - 0xa3ffffff    SDRAM Bank 0 (64MB)
+	 *
+	 *
+	 * Virtual Address Range    X C B  Description 
+	 * -----------------------  - - -  ---------------------------------- 
+	 * 0x00000000 - 0x00003fff  N Y Y  SDRAM 
+	 * 0x00004000 - 0x000fffff  N Y N  Boot ROM
+	 * 0x00100000 - 0x01ffffff  N N N  Application Flash
+	 * 0x04000000 - 0x05ffffff  N N N  Exp Application Flash
+	 * 0x08000000 - 0x080fffff  N N N  I/O baseboard registers
+	 * 0x0a000000 - 0x0a0fffff  N N N  SRAM
+	 * 0x40000000 - 0x480fffff  N N N  Processor Registers
+	 * 0xa0000000 - 0xa000ffff  N Y N  RedBoot SDRAM 
+	 * 0xa0017000 - 0xa3ffffff  Y Y Y  SDRAM
+	 * 0xc0000000 - 0xcfffffff  Y Y Y  Cache Flush Region 
+	 * (done by this routine)
+	 * 0xfd000000 - 0xfd0000ff  N N N  I/O baseboard registers
+	 * 0xfd100000 - 0xfd3fffff  N N N  Processor Registers.
+	 * 0xfd400000 - 0xfd4fffff  N N N  FF-UART
+	 * 0xfd500000 - 0xfd5fffff  N N N  BT-UART
+	 *
+	 * RedBoot's first level page table is at 0xa0004000.  There
+	 * are also 2 second-level tables at 0xa0008000 and
+	 * 0xa0008400.  We will continue to use them until we switch to
+	 * our pagetable by setttb().
+	 *
+	 */
+
+	/* setup GPIO for BTUART, in case bootloader doesn't take care of it */
+	pxa2x0_gpio_bootstrap(IPAQ3900_GPIO_VBASE);
+	pxa2x0_gpio_config(ipaq3900_gpioconf);
+
+	/* turn on clock to UART block.
+	   XXX: this should not be done here. */
+	ioreg_write(IPAQ3900_CLKMAN_VBASE+CLKMAN_CKEN, CKEN_FFUART|CKEN_BTUART |
+	    ioreg_read(IPAQ3900_CLKMAN_VBASE+CLKMAN_CKEN));
+
+	LEDSTEP();
+
+	if (hpc_boot_args != NULL && hpc_boot_args->bi != NULL) {
+		/* copy bootinfo into known kernel space */
+		bootinfo_storage = *hpc_boot_args->bi;
+		bootinfo = &bootinfo_storage;
+	} else {
+		memset(&bootinfo_storage, 0, sizeof(bootinfo_storage));
+		bootinfo = &bootinfo_storage;
+	}
+
+	consinit();
+	LEDSTEP();
+#ifdef KGDB
+	kgdb_port_init();
+	LEDSTEP();
+#endif
+
+	/* Talk to the user */
+	printf("\nNetBSD/evbarm (ipaq3900) booting ...\n");
+
+	/* parse kernel args */
+	boothowto = 0;
+	boot_file[0] = '\0';
+	if (hpc_boot_args != NULL && hpc_boot_args->argv != NULL) {
+		strncpy(booted_kernel_storage, hpc_boot_args->argv[0], 
+					       sizeof(booted_kernel_storage));
+
+#ifdef VERBOSE_INIT_ARM
+		printf("booted kernel = %s\n", booted_kernel_storage);
+#endif
+		for (loop = 1; loop < hpc_boot_args->argc; loop++) {
+			int howto;
+			char *cp = hpc_boot_args->argv[loop];
+
+#ifdef VERBOSE_INIT_ARM
+			printf("\targv[%d] = %s\n", loop, cp);
+#endif
+			switch (*cp) {
+			case '-':
+				/* Ignore extra '-' */
+				break;
+
+			case 'h':	/* serial console */
+				/* 
+				 * serial console: ignore this switch, we
+				 * use the console setting from bootinfo
+				 * instead.
+				 */
+				break;
+
+			case 'b':
+				/* boot device: -b=sd0 etc. */
+				cp = cp + 2;
+#ifdef NFS
+				if (strcmp(cp, "nfs") == 0)
+					mountroot = nfs_mountroot;
+				else
+					strncpy(boot_file, cp, sizeof(boot_file));
+#else /* !NFS */
+				strncpy(boot_file, cp, sizeof(boot_file));
+#endif /* !NFS */
+				break;
+			default:
+				howto = 0;
+				BOOT_FLAG(*cp, howto);
+				if (! howto)
+					printf("bootflag '%c' not recognised\n", *cp);
+				else
+					boothowto |= howto;
+				break;
+			}
+		}
+	}
+
+	{
+		/* Cotulla */
+		memstart = 0xa0000000;
+		memsize =  0x04000000; /* 64MB */
+	}
+
+	printf("initarm: Configuring system ...\n");
+
+	/* Fake bootconfig structure for the benefit of pmap.c */
+	/* XXX must make the memory description h/w independent */
+	bootconfig.dramblocks = 1;
+	bootconfig.dram[0].address = memstart;
+	bootconfig.dram[0].pages = memsize / PAGE_SIZE;
+
+	/*
+	 * Set up the variables that define the availablilty of
+	 * physical memory.  For now, we're going to set
+	 * physical_freestart to 0xa0200000 (where the kernel
+	 * was loaded), and allocate the memory we need downwards.
+	 * If we get too close to the page tables that RedBoot
+	 * set up, we will panic.  We will update physical_freestart
+	 * and physical_freeend later to reflect what pmap_bootstrap()
+	 * wants to see.
+	 *
+	 * XXX pmap_bootstrap() needs an enema.
+	 */
+	physical_start = bootconfig.dram[0].address;
+	physical_end = physical_start + (bootconfig.dram[0].pages * PAGE_SIZE);
+
+	physical_freestart = 0xa0009000UL;
+	physical_freeend = 0xa0200000UL;
+#ifdef BOOT_DUMP
+	setup_pages_end = KERNEL_BASE + physical_freeend - physical_start;
+#endif
+
+	physmem = (physical_end - physical_start) / PAGE_SIZE;
+
+#ifdef VERBOSE_INIT_ARM
+	/* Tell the user about the memory */
+	printf("physmemory: %d pages at 0x%08lx -> 0x%08lx\n", physmem,
+	    physical_start, physical_end - 1);
+#endif
+
+	/*
+	 * Okay, the kernel starts 2MB in from the bottom of physical
+	 * memory.  We are going to allocate our bootstrap pages downwards
+	 * from there.
+	 *
+	 * We need to allocate some fixed page tables to get the kernel
+	 * going.  We allocate one page directory and a number of page
+	 * tables and store the physical addresses in the kernel_pt_table
+	 * array.
+	 *
+	 * The kernel page directory must be on a 16K boundary.  The page
+	 * tables must be on 4K boundaries.  What we do is allocate the
+	 * page directory on the first 16K boundary that we encounter, and
+	 * the page tables on 4K boundaries otherwise.  Since we allocate
+	 * at least 3 L2 page tables, we are guaranteed to encounter at
+	 * least one 16K aligned region.
+	 */
+
+#ifdef VERBOSE_INIT_ARM
+	printf("Allocating page tables\n");
+#endif
+
+	free_pages = (physical_freeend - physical_freestart) / PAGE_SIZE;
+
+#ifdef VERBOSE_INIT_ARM
+	printf("freestart = 0x%08lx, free_pages = %d (0x%08x)\n",
+	       physical_freestart, free_pages, free_pages);
+#endif
+
+	/* Define a macro to simplify memory allocation */
+#define	valloc_pages(var, np)				\
+	alloc_pages((var).pv_pa, (np));			\
+	(var).pv_va = KERNEL_BASE + (var).pv_pa - physical_start;
+
+#define alloc_pages(var, np)				\
+	physical_freeend -= ((np) * PAGE_SIZE);		\
+	if (physical_freeend < physical_freestart)	\
+		panic("initarm: out of memory");	\
+	(var) = physical_freeend;			\
+	free_pages -= (np);				\
+	memset((char *)(var), 0, ((np) * PAGE_SIZE));
+
+	loop1 = 0;
+	kernel_l1pt.pv_pa = 0;
+	kernel_l1pt.pv_va = 0;
+	for (loop = 0; loop <= NUM_KERNEL_PTS; ++loop) {
+		/* Are we 16KB aligned for an L1 ? */
+		if (((physical_freeend - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) == 0
+		    && kernel_l1pt.pv_pa == 0) {
+			valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
+		} else {
+			valloc_pages(kernel_pt_table[loop1],
+			    L2_TABLE_SIZE / PAGE_SIZE);
+			++loop1;
+		}
+	}
+
+	/* This should never be able to happen but better confirm that. */
+	if (!kernel_l1pt.pv_pa || (kernel_l1pt.pv_pa & (L1_TABLE_SIZE-1)) != 0)
+		panic("initarm: Failed to align the kernel page directory");
+
+	LEDSTEP();
+
+	/*
+	 * Allocate a page for the system page mapped to V0xFFFF0000
+	 * This page will just contain the system vectors and can be
+	 * shared by all processes.
+	 */
+	vector_page = ARM_VECTORS_HIGH;
+	alloc_pages(systempage.pv_pa, 1);
+
+	/* Allocate stacks for all modes */
+	valloc_pages(irqstack, IRQ_STACK_SIZE);
+	valloc_pages(abtstack, ABT_STACK_SIZE);
+	valloc_pages(undstack, UND_STACK_SIZE);
+	valloc_pages(kernelstack, UPAGES);
+
+	/* Allocate enough pages for cleaning the Mini-Data cache. */
+	KASSERT(xscale_minidata_clean_size <= PAGE_SIZE);
+	valloc_pages(minidataclean, 1);
+
+#ifdef VERBOSE_INIT_ARM
+	for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
+		printf("kernel pt table[%d]: p0x%08lx v0x%08lx\n", 
+		    loop,
+		    kernel_pt_table[loop].pv_pa, 
+		    kernel_pt_table[loop].pv_va);
+	}
+
+	printf("System page: p0x%08lx v0x%08lx\n", systempage.pv_pa,
+	    systempage.pv_va); 
+	printf("IRQ stack: p0x%08lx v0x%08lx\n", irqstack.pv_pa,
+	    irqstack.pv_va); 
+	printf("ABT stack: p0x%08lx v0x%08lx\n", abtstack.pv_pa,
+	    abtstack.pv_va); 
+	printf("UND stack: p0x%08lx v0x%08lx\n", undstack.pv_pa,
+	    undstack.pv_va); 
+	printf("SVC stack: p0x%08lx v0x%08lx\n", kernelstack.pv_pa,
+	    kernelstack.pv_va); 
+	printf("Minidata clean: p0x%08lx v0x%08lx (size %ld)\n", 
+	    minidataclean.pv_pa, minidataclean.pv_va, 
+	    xscale_minidata_clean_size); 
+#endif
+
+	/*
+	 * XXX Defer this to later so that we can reclaim the memory
+	 * XXX used by the initial page tables.
+	 */
+	alloc_pages(msgbufphys, round_page(MSGBUFSIZE) / PAGE_SIZE);
+
+	/*
+	 * Ok we have allocated physical pages for the primary kernel
+	 * page tables
+	 */
+
+#ifdef VERBOSE_INIT_ARM
+	printf("Creating L1 page table at 0x%08lx\n", kernel_l1pt.pv_pa);
+#endif
+
+	/*
+	 * Now we start construction of the L1 page table
+	 * We start by mapping the L2 page tables into the L1.
+	 * This means that we can replace L1 mappings later on if necessary
+	 */
+	l1pagetable = kernel_l1pt.pv_pa;
+
+	/* Map the L2 pages tables in the L1 page table */
+	pmap_link_l2pt(l1pagetable, vector_page & ~(0x00400000 - 1),
+	    &kernel_pt_table[KERNEL_PT_SYS]);
+
+	for (loop = 0; loop < KERNEL_PT_KERNEL_NUM; loop++)
+		pmap_link_l2pt(l1pagetable, KERNEL_BASE + loop * 0x00400000,
+		    &kernel_pt_table[KERNEL_PT_KERNEL + loop]);
+
+	for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; loop++)
+		pmap_link_l2pt(l1pagetable, KERNEL_VM_BASE + loop * 0x00400000,
+		    &kernel_pt_table[KERNEL_PT_VMDATA + loop]);
+
+	/* update the top of the kernel VM */
+	pmap_curmaxkvaddr =
+	    KERNEL_VM_BASE + (KERNEL_PT_VMDATA_NUM * 0x00400000);
+
+#ifdef VERBOSE_INIT_ARM
+	printf("Mapping kernel\n");
+#endif
+
+	/* Now we fill in the L2 pagetable for the kernel static code/data */
+	{
+		size_t textsize = (uintptr_t) etext - KERNEL_TEXT_BASE;
+		size_t totalsize = (uintptr_t) _end - KERNEL_TEXT_BASE;
+		u_int logical;
+
+#if NKSYMS || defined(DDB) || defined(MODULAR)
+		if (!memcmp(&_end, "\177ELF", 4)) {
+			Elf_Shdr *sh = (Elf_Shdr *)
+			    ((char *)&_end + ((Elf_Ehdr *)&_end)->e_shoff);
+
+			loop = ((Elf_Ehdr *)&_end)->e_shnum;
+			for (; loop; loop--, sh++)
+				if (sh->sh_offset > 0 &&
+				    (sh->sh_offset + sh->sh_size) > symbolsize)
+					symbolsize = sh->sh_offset + sh->sh_size;
+		}
+
+		totalsize += symbolsize;
+#endif
+
+		textsize = (textsize + PGOFSET) & ~PGOFSET;
+		totalsize = (totalsize + PGOFSET) & ~PGOFSET;
+		
+		logical = 0x00200000;	/* offset of kernel in RAM */
+
+		logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical,
+		    physical_start + logical, textsize,
+		    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+		logical += pmap_map_chunk(l1pagetable, KERNEL_BASE + logical,
+		    physical_start + logical, totalsize - textsize,
+		    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	}
+
+#ifdef VERBOSE_INIT_ARM
+	printf("Constructing L2 page tables\n");
+#endif
+
+	/* Map the stack pages */
+	pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa,
+	    IRQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa,
+	    ABT_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa,
+	    UND_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa,
+	    UPAGES * PAGE_SIZE, VM_PROT_READ | VM_PROT_WRITE, PTE_CACHE);
+
+	pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,
+	    L1_TABLE_SIZE, VM_PROT_READ | VM_PROT_WRITE, PTE_PAGETABLE);
+
+	for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
+		pmap_map_chunk(l1pagetable, kernel_pt_table[loop].pv_va,
+		    kernel_pt_table[loop].pv_pa, L2_TABLE_SIZE,
+		    VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
+	}
+
+	/* Map the vector page. */
+	pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+
+	printf("vector_page: v0x%08lx\n", vector_page);
+
+	/*
+	 * map integrated peripherals at same address in l1pagetable
+	 * so that we can continue to use console.
+	 */
+	pmap_devmap_bootstrap(l1pagetable, ipaq3900_devmap);
+
+	/* Map the Mini-Data cache clean area. */
+	xscale_setup_minidata(l1pagetable, minidataclean.pv_va,
+	    minidataclean.pv_pa);
+
+	/*
+	 * Give the XScale global cache clean code an appropriately
+	 * sized chunk of unmapped VA space starting at 0xff000000
+	 * (our device mappings end before this address).
+	 */
+	xscale_cache_clean_addr = 0xff000000U;
+
+	/*
+	 * Now we have the real page tables in place so we can switch to them.
+	 * Once this is done we will be running with the REAL kernel page
+	 * tables.
+	 */
+
+	/*
+	 * Update the physical_freestart/physical_freeend/free_pages
+	 * variables.  Make sure to account for symbol table if we
+	 * need to.
+	 */
+	{
+#ifdef BOOT_DUMP
+		/* physical_freend points to next free page, save off last-used */
+		setup_pages_start = KERNEL_BASE + physical_freeend - physical_start + PAGE_SIZE;
+#endif
+		physical_freestart = physical_start +
+		    (((((uintptr_t) _end + symbolsize) + PGOFSET) & ~PGOFSET) -
+		     KERNEL_BASE);
+		physical_freeend = physical_end;
+		free_pages =
+		    (physical_freeend - physical_freestart) / PAGE_SIZE;
+	}
+
+	/* Switch tables */
+#ifdef VERBOSE_INIT_ARM
+	printf("freestart = 0x%08lx, free_pages = %d (0x%x)\n",
+	       physical_freestart, free_pages, free_pages);
+	printf("switching to new L1 page table  @%#lx...", kernel_l1pt.pv_pa);
+#endif
+
+	LEDSTEP();
+
+	cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
+	setttb(kernel_l1pt.pv_pa);
+	cpu_tlb_flushID();
+	cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
+	LEDSTEP();
+
+	/*
+	 * Moved from cpu_startup() as data_abort_handler() references
+	 * this during uvm init
+	 */
+	proc0paddr = (struct user *)kernelstack.pv_va;
+	lwp0.l_addr = proc0paddr;
+
+#ifdef VERBOSE_INIT_ARM
+	printf("bootstrap done.\n");
+#endif
+
+	/* 
+	 * Enable I-cache, D-cache, BTB.  Set SYSTEM protection, turn
+	 * off ROM protection to avoid UNDEFINED access modes (if we
+	 * turn both off, OTOH, we'll get DENIED access, so we need to
+	 * make sure both of them have the right value).
+	 *
+	 * NB: Be careful this doesn't mess with the CPU_CONTROL_VECRELOC
+	 * bit if you call arm32_vector_init() before this!
+	 *
+	 * Also, not sure that it matters, but force all the bits the PXA
+	 * docs claim should always be written as ones to ones.
+	 */
+	cpu_control(0xffffdf7c, 0x0000197c);
+	LEDSTEP();
+
+	arm32_vector_init(vector_page, ARM_VEC_ALL);
+	LEDSTEP();
+
+	/*
+	 * Pages were allocated during the secondary bootstrap for the
+	 * stacks for different CPU modes.
+	 * We must now set the r13 registers in the different CPU modes to
+	 * point to these stacks.
+	 * Since the ARM stacks use STMFD etc. we must set r13 to the top end
+	 * of the stack memory.
+	 */
+	printf("init subsystems: stacks ");
+
+	set_stackptr(PSR_IRQ32_MODE, irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE);
+	set_stackptr(PSR_ABT32_MODE, abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE);
+	set_stackptr(PSR_UND32_MODE, undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE);
+
+	/*
+	 * Well we should set a data abort handler.
+	 * Once things get going this will change as we will need a proper
+	 * handler.
+	 * Until then we will use a handler that just panics but tells us
+	 * why.
+	 * Initialisation of the vectors will just panic on a data abort.
+	 * This just fills in a slightly better one.
+	 */
+	printf("vectors ");
+	data_abort_handler_address = (u_int)data_abort_handler;
+	prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
+	undefined_handler_address = (u_int)undefinedinstruction_bounce;
+
+	/* Initialise the undefined instruction handlers */
+	printf("undefined ");
+	undefined_init();
+
+	/* Load memory into UVM. */
+	printf("page ");
+	uvm_setpagesize();        /* initialize PAGE_SIZE-dependent variables */
+	uvm_page_physload(atop(physical_freestart), atop(physical_freeend),
+	    atop(physical_freestart), atop(physical_freeend),
+	    VM_FREELIST_DEFAULT);
+
+	/* Boot strap pmap telling it where the kernel page table is */
+	printf("pmap ");
+	LEDSTEP();
+	pmap_bootstrap(KERNEL_VM_BASE, KERNEL_VM_BASE + KERNEL_VM_SIZE);
+	LEDSTEP();
+
+#ifdef __HAVE_MEMORY_DISK__
+	md_root_setconf(memory_disk, sizeof memory_disk);
+#endif
+
+	LEDSTEP();
+
+#ifdef KGDB
+	if (boothowto & RB_KDB) {
+		kgdb_debug_init = 1;
+		kgdb_connect(1);
+	}
+#endif
+
+#ifdef DDB
+	db_machine_init();
+#endif
+#if NKSYMS || defined(DDB) || defined(MODULAR)
+	if (symbolsize != 0) {
+		printf("Loading 0x%zx bytes of symbols...\n", symbolsize);
+		ksyms_addsyms_elf(symbolsize, ((int *)&_end), ((char *)&_end) + symbolsize);
+	}
+#endif
+
+#ifdef DDB
+	if (boothowto & RB_KDB)
+		Debugger();
+#endif /* DDB */
+
+	/* Turn off BLUE & GREEN LED's, turn on YELLOW for now */
+	ioreg8_write(IPAQ3900_ASIC2_VBASE + ASIC_LED_BASE + 
+	    ASIC_LED_BLUE + LED_TIMEBASE_REG, 0);
+	ioreg16_write(IPAQ3900_ASIC2_VBASE + ASIC_LED_BASE + 
+	    ASIC_LED_BLUE + LED_PERIOD_REG, 0);
+	ioreg16_write(IPAQ3900_ASIC2_VBASE + ASIC_LED_BASE + 
+	    ASIC_LED_BLUE + LED_DUTYTIME_REG, 0);
+
+	ioreg8_write(IPAQ3900_ASIC2_VBASE + ASIC_LED_BASE + 
+	    ASIC_LED_GREEN + LED_TIMEBASE_REG, 0);
+	ioreg16_write(IPAQ3900_ASIC2_VBASE + ASIC_LED_BASE + 
+	    ASIC_LED_GREEN + LED_PERIOD_REG, 0);
+	ioreg16_write(IPAQ3900_ASIC2_VBASE + ASIC_LED_BASE + 
+	    ASIC_LED_GREEN + LED_DUTYTIME_REG, 0);
+
+	ioreg8_write(IPAQ3900_ASIC2_VBASE + ASIC_LED_BASE + 
+	    ASIC_LED_YELLOW + LED_TIMEBASE_REG, 0x70);
+	ioreg16_write(IPAQ3900_ASIC2_VBASE + ASIC_LED_BASE + 
+	    ASIC_LED_YELLOW + LED_PERIOD_REG, 4);
+	ioreg16_write(IPAQ3900_ASIC2_VBASE + ASIC_LED_BASE + 
+	    ASIC_LED_YELLOW + LED_DUTYTIME_REG, 4);
+
+	/* We return the new stack pointer address */
+	return(kernelstack.pv_va + USPACE_SVC_STACK_TOP);
+}
+
+#ifdef KGDB
+#ifndef KGDB_DEVNAME
+#define KGDB_DEVNAME "ffuart"
+#endif
+const char kgdb_devname[] = KGDB_DEVNAME;
+
+#if (NCOM > 0)
+#ifndef KGDB_DEVMODE
+#define KGDB_DEVMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
+#endif
+int comkgdbmode = KGDB_DEVMODE;
+#endif /* NCOM */
+
+#endif /* KGDB */
+
+
+void
+consinit(void)
+{
+	static int consinit_called = 0;
+
+	if (consinit_called != 0)
+		return;
+
+	consinit_called = 1;
+
+	/*
+	 * Nothing to do here.  Console initialization is done at
+	 * autoconf device attach time.
+	 */
+	if ((bootinfo->bi_cnuse & BI_CNUSE_SERIAL) == 0)
+		return;
+
+#if NCOM > 0
+
+#ifdef FFUARTCONSOLE
+#ifdef KGDB
+	if (0 == strcmp(kgdb_devname, "ffuart")) {
+		/* port is reserved for kgdb */
+	} else 
+#endif
+	if (0 == comcnattach(&pxa2x0_a4x_bs_tag, PXA2X0_FFUART_BASE, 
+		     comcnspeed, PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comcnmode)) {
+#if 0
+		/* XXX: can't call pxa2x0_clkman_config yet */
+		pxa2x0_clkman_config(CKEN_FFUART, 1);
+#else
+		uint32_t ckenreg = ioreg_read(IPAQ3900_CLKMAN_VBASE+CLKMAN_CKEN);
+
+		ioreg_write(IPAQ3900_CLKMAN_VBASE+CLKMAN_CKEN,
+		    ckenreg|CKEN_FFUART);
+#endif
+
+		return;
+	}
+#endif /* FFUARTCONSOLE */
+
+#ifdef BTUARTCONSOLE
+#ifdef KGDB
+	if (0 == strcmp(kgdb_devname, "btuart")) {
+		/* port is reserved for kgdb */
+	} else
+#endif
+	if (0 == comcnattach(&pxa2x0_a4x_bs_tag, PXA2X0_BTUART_BASE,
+		comcnspeed, PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comcnmode)) {
+		uint32_t ckenreg = ioreg_read(IPAQ3900_CLKMAN_VBASE+CLKMAN_CKEN);
+
+		ioreg_write(IPAQ3900_CLKMAN_VBASE+CLKMAN_CKEN,
+		    ckenreg|CKEN_BTUART);
+		return;
+	}
+#endif /* BTUARTCONSOLE */
+
+
+#endif /* NCOM */
+
+}
+
+#ifdef KGDB
+void
+kgdb_port_init(void)
+{
+#if (NCOM > 0) && defined(COM_PXA2X0)
+	paddr_t paddr = 0;
+	uint32_t ckenreg = ioreg_read(IPAQ3900_CLKMAN_VBASE+CLKMAN_CKEN);
+
+	if (0 == strcmp(kgdb_devname, "ffuart")) {
+		paddr = PXA2X0_FFUART_BASE;
+		ckenreg |= CKEN_FFUART;
+	}
+	else if (0 == strcmp(kgdb_devname, "btuart")) {
+		paddr = PXA2X0_BTUART_BASE;
+		ckenreg |= CKEN_BTUART;
+	}
+
+	if (paddr &&
+	    0 == com_kgdb_attach(&pxa2x0_a4x_bs_tag, paddr,
+		kgdb_rate, PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comkgdbmode)) {
+
+		ioreg_write(IPAQ3900_CLKMAN_VBASE+CLKMAN_CKEN, ckenreg);
+	}
+#endif
+}
+#endif
+
+#ifdef BOOT_DUMP
+void
+dumppages(char *start, int nbytes)
+{
+	char *p = start;
+	char *p1;
+	int i;
+
+	for (i = nbytes; i > 0; i -= 16, p += 16) {
+		for (p1 = p + 15; p != p1; p1--) {
+			if (*p1)
+				break;
+		}
+		if (!*p1)
+			continue;
+		printf("%08x %02x %02x %02x %02x %02x %02x %02x %02x"
+		    " %02x %02x %02x %02x %02x %02x %02x %02x\n",
+		    (unsigned int)p,
+		    p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
+		    p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
+	}
+}
+#endif
+
+#ifdef MODULAR
+/*
+ * Push any modules loaded by the boot loader.
+ */
+void
+module_init_md(void)
+{
+}
+#endif /* MODULAR */
diff --git a/sys/arch/evbarm/ipaq3900/ipaq3900_pcic.c b/sys/arch/evbarm/ipaq3900/ipaq3900_pcic.c
new file mode 100644
index 0000000..f042c51
--- /dev/null
+++ b/sys/arch/evbarm/ipaq3900/ipaq3900_pcic.c
@@ -0,0 +1,314 @@
+/*	$NetBSD: ipaq3900_pcic.c,v 1.7 2007/12/15 00:39:15 perry Exp $ */
+/*
+ * Copyright (C) 2005, 2006 WIDE Project and SOUM Corporation.
+ * All rights reserved.
+ *
+ * Written by Takashi Kiyohara and Susumu Miki for WIDE Project and SOUM
+ * Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the project nor the name of SOUM Corporation
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT and SOUM CORPORATION ``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 PROJECT AND SOUM CORPORATION
+ * 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.
+ */
+/*
+ * Copyright (c) 2002, 2003, 2005  Genetec corp.  All rights reserved.
+ *
+ * PCMCIA/CF support for TWINTAIL (G4255EB)
+ * Written by Hiroyuki Bessho for Genetec corp.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. The name of Genetec corp. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORP. ``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 GENETEC CORP.
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/callout.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+#include <sys/malloc.h>
+#include <uvm/uvm.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/pcmcia/pcmciareg.h>
+#include <dev/pcmcia/pcmciavar.h>
+#include <dev/pcmcia/pcmciachip.h>
+
+#include <arch/arm/xscale/pxa2x0cpu.h>
+#include <arch/arm/xscale/pxa2x0var.h>
+#include <arch/arm/xscale/pxa2x0reg.h>
+#include <arch/arm/xscale/pxa2x0_gpio.h>
+#include <arch/arm/xscale/pxa2x0_pcic.h>
+
+/* Debug code to dump out MC PCMCIA timing registers if they change value */
+#define REPORT_SETUP_TIMINGS
+
+#ifdef DEBUG
+#define DPRINTF(arg)	printf arg
+#else
+#define DPRINTF(arg)
+#endif
+
+#define HAVE_CARD(r)	(!((r) & GPIO_SET))
+
+#define IPAQ3900_PCMCIA_CD0	3
+#define IPAQ3900_PCMCIA_IRQ0	7
+#define IPAQ3900_PCMCIA_CD1	12
+#define IPAQ3900_PCMCIA_IRQ1	13
+
+static	int  	ipaq3900_pcic_match(struct device *, struct cfdata *, void *);
+static	void  	ipaq3900_pcic_attach(struct device *, struct device *, void *);
+static	void	ipaq3900_pcic_pcic_socket_setup(struct pxapcic_socket *);
+
+static	u_int	ipaq3900_pcic_read(struct pxapcic_socket *, int);
+static	void	ipaq3900_pcic_write(struct pxapcic_socket *, int, u_int);
+static	void	ipaq3900_pcic_set_power(struct pxapcic_socket *, int);
+static	void	ipaq3900_pcic_clear_intr(struct pxapcic_socket *);
+static	void	*ipaq3900_pcic_intr_establish(struct pxapcic_socket *, int,
+				       int (*)(void *), void *);
+static	void	ipaq3900_pcic_intr_disestablish(struct pxapcic_socket *, void *);
+
+CFATTACH_DECL(pxapcic_ipaq3900_pcic, sizeof(struct pxapcic_softc),
+    ipaq3900_pcic_match, ipaq3900_pcic_attach, NULL, NULL);
+
+static struct pxapcic_tag ipaq3900_pcic_pcic_functions = {
+	ipaq3900_pcic_read,
+	ipaq3900_pcic_write,
+	ipaq3900_pcic_set_power,
+	ipaq3900_pcic_clear_intr,
+	ipaq3900_pcic_intr_establish,
+	ipaq3900_pcic_intr_disestablish,
+};
+
+static struct {
+	int cd;
+	int prdy;
+} ipaq3900_pcic_slot_irqs[] = {
+	{ IPAQ3900_PCMCIA_CD0, 	IPAQ3900_PCMCIA_IRQ0 },
+	{ IPAQ3900_PCMCIA_CD1, 	IPAQ3900_PCMCIA_IRQ1 }
+};
+
+
+static int
+ipaq3900_pcic_match(struct device *parent, struct cfdata *cf, void *aux)
+{
+	struct pxa2x0_gpioconf *gpioconf;
+	u_int reg;
+	int i;
+
+	/*
+	 * Check GPIO configuration.  If you use these, it is sure already
+	 * to have been set by gxio.
+	 */
+	gpioconf = CPU_IS_PXA250 ? pxa25x_pcic_gpioconf :
+	    pxa27x_pcic_gpioconf;
+	for (i = 0; gpioconf[i].pin != -1; i++) {
+		reg = pxa2x0_gpio_get_function(gpioconf[i].pin);
+		if (GPIO_FN(reg) != GPIO_FN(gpioconf[i].value) ||
+		    GPIO_FN_IS_OUT(reg) != GPIO_FN_IS_OUT(gpioconf[i].value))
+			return (0);
+	}
+
+	return	1;	/* match */
+}
+
+static void
+ipaq3900_pcic_attach(struct device *parent, struct device *self, void *aux)
+{
+	struct pxapcic_softc *sc = (struct pxapcic_softc *)self;
+	struct pxaip_attach_args *pxa = (struct pxaip_attach_args *)aux;
+	int nslot, i;
+
+	sc->sc_iot = pxa->pxa_iot;
+
+	nslot = 1; 	/* XXXrkb: how do we find this out? */
+
+	for (i = 0; i < nslot; i++) {
+		sc->sc_irqpin[i] = ipaq3900_pcic_slot_irqs[i].prdy;
+		sc->sc_irqcfpin[i] = ipaq3900_pcic_slot_irqs[i].cd;
+	}
+	sc->sc_nslots = nslot;
+
+	pxapcic_attach_common(sc, &ipaq3900_pcic_pcic_socket_setup);
+}
+
+static void
+ipaq3900_pcic_pcic_socket_setup(struct pxapcic_socket *so)
+{
+#ifdef REPORT_SETUP_TIMINGS
+	uint32_t omcmem, omcatt, omcio;
+	uint32_t nmcmem, nmcatt, nmcio;
+#endif
+	struct pxapcic_softc *sc = so->sc;
+
+	/* 3.3V only? */
+	so->power_capability = PXAPCIC_POWER_3V;
+	so->pcictag_cookie = NULL;
+	so->pcictag = &ipaq3900_pcic_pcic_functions;
+
+
+#ifdef REPORT_SETUP_TIMINGS
+	omcmem = bus_space_read_4(sc->sc_iot, sc->sc_memctl_ioh, 
+	    MEMCTL_MCMEM(so->socket));
+	omcatt = bus_space_read_4(sc->sc_iot, sc->sc_memctl_ioh, 
+	    MEMCTL_MCATT(so->socket));
+	omcio = bus_space_read_4(sc->sc_iot, sc->sc_memctl_ioh, 
+	    MEMCTL_MCIO(so->socket));
+#endif
+
+	/*
+	 * These settings are based on residual settings left over by
+	 * WinCE.  NB: These are dependent on CPU/memory clock, so will
+	 * need to be adjusted if/when we get proper CPU clock control
+	 * implemented.
+	 *
+	 * The odd thing here is I expected timings for attribute and
+	 * common memory to be the same, and I/O to be different, but
+	 * the outlier is common memory instead (I/O and attribute
+	 * memory are the same).
+	 */
+	bus_space_write_4(sc->sc_iot, sc->sc_memctl_ioh,
+	    MEMCTL_MCMEM(so->socket), MC_TIMING_VAL(7, 8, 22));
+	bus_space_write_4(sc->sc_iot, sc->sc_memctl_ioh,
+	    MEMCTL_MCATT(so->socket), MC_TIMING_VAL(11, 14, 33));
+	bus_space_write_4(sc->sc_iot, sc->sc_memctl_ioh,
+	    MEMCTL_MCIO(so->socket), MC_TIMING_VAL(11, 14, 33));
+
+#ifdef REPORT_SETUP_TIMINGS
+	nmcmem = bus_space_read_4(sc->sc_iot, sc->sc_memctl_ioh, 
+	    MEMCTL_MCMEM(so->socket));
+	nmcatt = bus_space_read_4(sc->sc_iot, sc->sc_memctl_ioh, 
+	    MEMCTL_MCATT(so->socket));
+	nmcio = bus_space_read_4(sc->sc_iot, sc->sc_memctl_ioh, 
+	    MEMCTL_MCIO(so->socket));
+
+	if (omcmem != nmcmem)
+		printf("socket_setup: socket %d: mcmem changed from 0x%x -> 0x%x\n", so->socket, omcmem, nmcmem);
+	if (omcatt != nmcatt)
+		printf("socket_setup: socket %d: mcatt changed from 0x%x -> 0x%x\n", so->socket, omcatt, nmcatt);
+	if (omcio != nmcio)
+		printf("socket_setup: socket %d: mcio changed from 0x%x -> 0x%x\n", so->socket, omcio, nmcio);
+#endif
+}
+
+static u_int
+ipaq3900_pcic_read(struct pxapcic_socket *so, int which)
+{
+	int reg;
+
+	switch (which) {
+	case PXAPCIC_CARD_STATUS:
+		reg = pxa2x0_gpio_get_function(ipaq3900_pcic_slot_irqs[so->socket].cd);
+		return (HAVE_CARD(reg) ?
+		    PXAPCIC_CARD_VALID : PXAPCIC_CARD_INVALID);
+
+	case PXAPCIC_CARD_READY:
+	/* XXXrkb: steal VS1, VS2 from the iPAQ 3600 implementation? */
+		reg = pxa2x0_gpio_get_function(
+		    ipaq3900_pcic_slot_irqs[so->socket].prdy);
+		return (reg & GPIO_SET ? 1 : 0);
+
+	default:
+		panic("%s: bogus register", __func__);
+	}
+	/* NOTREACHED */
+}
+
+/* ARGSUSED */
+static void
+ipaq3900_pcic_write(struct pxapcic_socket *so, int which, u_int arg)
+{
+
+	/* XXXrkb: steal from the iPAQ 3600 implementation */
+	switch (which) {
+	case PXAPCIC_CARD_POWER:
+	case PXAPCIC_CARD_RESET:
+		/* We can't */
+		break;
+
+	default:
+		panic("%s: bogus register", __func__);
+	}
+	/* NOTREACHED */
+}
+
+static void
+ipaq3900_pcic_set_power(struct pxapcic_socket *__so, int arg)
+{
+
+	/* XXXrkb: steal from the iPAQ 3600 implementation? */
+	if(arg != PXAPCIC_POWER_OFF && arg != PXAPCIC_POWER_3V)
+		panic("%s: bogus arg\n", __func__);
+
+	/* 3.3V only? */
+}
+
+/* ARGSUSED */
+static void
+ipaq3900_pcic_clear_intr(struct pxapcic_socket *so)
+{
+
+	/* nothing to do */
+}
+
+static void *
+ipaq3900_pcic_intr_establish(struct pxapcic_socket *so, int level,
+    int (* ih_fun)(void *), void *ih_arg)
+{
+
+	return pxa2x0_gpio_intr_establish(so->irqpin, IST_EDGE_FALLING,
+	    level, ih_fun, ih_arg);
+}
+
+/* ARGSUSED */
+static void
+ipaq3900_pcic_intr_disestablish(struct pxapcic_socket *so, void *ih)
+{
+
+	pxa2x0_gpio_intr_disestablish(ih);
+}
+
diff --git a/sys/arch/evbarm/ipaq3900/ipaq3900_reg.h b/sys/arch/evbarm/ipaq3900/ipaq3900_reg.h
new file mode 100644
index 0000000..14b7eef
--- /dev/null
+++ b/sys/arch/evbarm/ipaq3900/ipaq3900_reg.h
@@ -0,0 +1,74 @@
+/*	$NetBSD: ipaq3900_reg.h,v 1.4 2005/12/11 12:17:09 christos Exp $ */
+
+/*
+ * Copyright (c) 2002, 2003, 2005  Genetec Corporation.  All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. The name of Genetec Corporation may not be used to endorse or 
+ *    promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef _EVBARM_IPAQ3900_REG_H
+#define _EVBARM_IPAQ3900_REG_H
+
+#include <arm/xscale/pxa2x0reg.h>
+
+/*
+ * Logical mapping for onboard/integrated peripherals
+ */
+#define	IPAQ3900_IO_AREA_VBASE	0xfd000000
+
+/* Nothing yet -- OBIO? 	0xfd000000	*/
+#define IPAQ3900_GPIO_VBASE	0xfd100000
+#define IPAQ3900_CLKMAN_VBASE 	0xfd200000
+#define IPAQ3900_INTCTL_VBASE 	0xfd300000
+#define IPAQ3900_FFUART_VBASE	0xfd400000
+#define IPAQ3900_BTUART_VBASE	0xfd500000
+#define IPAQ3900_STUART_VBASE	0xfd600000
+#define IPAQ3900_ASIC2_VBASE	0xfd700000
+#define IPAQ3900_ASIC3_VBASE	0xfd800000
+#define IPAQ3900_ASIC3_SD_VBASE	0xfd900000
+
+#define ASIC_LED_BASE		0x00000800
+
+#define ASIC_LED_BLUE		0x00000000
+#define ASIC_LED_GREEN		0x00000080
+#define ASIC_LED_YELLOW		0x00000100
+
+#define LED_TIMEBASE_REG	0x00
+#define LED_PERIOD_REG		0x04
+#define LED_DUTYTIME_REG	0x08
+#define LED_AUTOSTOP_REG	0x0c
+
+#define ioreg_read(a)  (*(volatile unsigned *)(a))
+#define ioreg_write(a,v)  (*(volatile unsigned *)(a)=(v))
+
+#define ioreg16_read(a)  (*(volatile uint16_t *)(a))
+#define ioreg16_write(a,v)  (*(volatile uint16_t *)(a)=(v))
+
+#define ioreg8_read(a)  (*(volatile uint8_t *)(a))
+#define ioreg8_write(a,v)  (*(volatile uint8_t *)(a)=(v))
+
+#endif /* _EVBARM_IPAQ3900_REG_H */
diff --git a/sys/arch/evbarm/ipaq3900/ipaq3900_start.S b/sys/arch/evbarm/ipaq3900/ipaq3900_start.S
new file mode 100644
index 0000000..b544626
--- /dev/null
+++ b/sys/arch/evbarm/ipaq3900/ipaq3900_start.S
@@ -0,0 +1,174 @@
+/*	$NetBSD: ipaq3900_start.S,v 1.1 2003/06/18 10:51:15 bsh Exp $ */
+
+/*
+ * Copyright (c) 2002, 2003  Genetec Corporation.  All rights reserved.
+ * Written by Hiroyuki Bessho for Genetec Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. The name of Genetec Corporation may not be used to endorse or 
+ *    promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``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 GENETEC CORPORATION
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+#include <arm/armreg.h>
+#include <arm/arm32/pte.h>
+#include <arm/arm32/pmap.h>		/* for PMAP_DOMAIN_KERNEL */
+
+#ifndef SDRAM_START
+#define SDRAM_START	0xa0000000
+#endif
+
+/*
+ * CPWAIT -- Canonical method to wait for CP15 update.
+ * NOTE: Clobbers the specified temp reg.
+ * copied from arm/arm/cpufunc_asm_xscale.S
+ * XXX: better be in a common header file.
+ */
+#define	CPWAIT(tmp)							 \
+	mrc	p15, 0, tmp, c2, c0, 0	/* arbitrary read of CP15 */	;\
+	mov	tmp, tmp		/* wait for it to complete */	;\
+	sub	pc, pc, #4		/* branch to next insn */
+	
+/*
+ * Kernel start routine for PXA-2x0-based iPAQ 39x0/54xx/...
+ *
+ * MMU is disabled when we enter here; note that we need to save 
+ * the args passed by hpcboot.exe (argc, argv, bootinfo*) some-
+ * where since the generic arm32 start code only passes r0 through
+ * to initarm().
+ */
+	.text
+
+	.global	_C_LABEL(ipaq3900_start)
+_C_LABEL(ipaq3900_start):
+	/* Put the processor in SVC32 mode, disable IRQs and FIQs */
+	mov	r5, sp
+	mrs	r4, cpsr_all
+	bic	r4, r4, #31
+	orr	r4, r4, #(I32_bit | F32_bit | PSR_SVC32_MODE)
+	msr	cpsr_all, r4
+	mov	sp, r5
+
+	/* Disable PID virtual address mapping */
+	mov	r4, #0
+	mcr	15, 0, r4, c13, c0, 0
+	CPWAIT(r4)
+
+	/*
+	 * Save args passed to us by hpcboot.exe and pass in the pointer
+	 * to the arg save area instead (in r0).
+	 */
+	adr	r4, Lhpcboot_args
+	stmia	r4, {r0,r1,r2}   /* argc, argc, bootinfo ptr */
+	mov	r0, r4
+
+	/*
+	 * Kernel is loaded in SDRAM (0xa0200000..), and is expected to run
+	 * in VA 0xc0200000; the CPU is currently running with MMU off.  To
+	 * make transition easier map the whole address space VA == PA first,
+	 * then create a (second) mapping for SDRAM at 0xc0000000.  Finally,
+	 * map on-board devices we might need while booting.
+	 */
+	ldr	r4, Lstartup_pagetable
+	adr	r5, mmu_init_table
+	b	2f
+
+1:
+	str	r8, [r4, r7]
+	add	r7, r7, #4
+	add	r8, r8, #(L1_S_SIZE)
+	adds	r6, r6, #-1
+	bhi	1b
+2:	
+	ldmia	r5!, {r6,r7,r8}   /* # of sections, PA|attr, VA */
+	cmp	r6, #0
+	bne	1b	
+
+	/* Now set up the TTB, flush TLB */
+	mcr	p15, 0, r4, c2, c0, 0	/* Set TTB */
+	mcr	p15, 0, r4, c8, c7, 0	/* Flush TLB */
+
+	/* Set the Domain Access register.  Very important! */
+        mov     r4, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT)
+	mcr	p15, 0, r4, c3, c0, 0
+
+	/* Enable the MMU, wait for it to complete */
+	mrc	p15, 0, r4, c1, c0, 0
+	orr	r4, r4, #CPU_CONTROL_MMU_ENABLE
+	mcr	p15, 0, r4, c1, c0, 0
+	CPWAIT(r4)
+
+	/* Jump to kernel code in TRUE VA */
+	adr	r4, Lstart
+	ldr	pc, [r4]
+
+Lhpcboot_args:
+	.word	0	/* r0 == argc */
+	.word	0	/* r1 == argv */
+	.word	0	/* r2 == bootinfo ptr */
+
+Lstart:
+	.word	start
+
+#ifndef STARTUP_PAGETABLE_ADDR
+#define STARTUP_PAGETABLE_ADDR 0xa0004000
+#endif
+Lstartup_pagetable: 
+	.word	STARTUP_PAGETABLE_ADDR
+
+#define MMU_INIT(va,pa,n_sec,attr) \
+	.word	n_sec					    ; \
+	.word	4*((va)>>L1_S_SHIFT)			    ; \
+	.word	(pa)|(attr)				    ;
+	
+mmu_init_table:	
+	/* fill all table VA==PA */
+	MMU_INIT(0x00000000, 0x00000000, 1<<(32-L1_S_SHIFT), L1_TYPE_S|L1_S_AP(AP_KRW))
+	/* map SDRAM VA==PA, WT cacheable */
+	MMU_INIT(SDRAM_START, SDRAM_START, 64, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
+
+	/* map SDRAM at 0xc0000000, WT cachable */
+	MMU_INIT(0xc0000000, SDRAM_START, 64, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
+
+	/* Map I/O regions */
+	/* map 1M VA @ 0xfd100000 to 1M PA @ 0x40e00000 (GPIO_BASE) */
+	MMU_INIT(0xfd100000, 0x40e00000, 1, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
+	/* map 1M VA @ 0xfd200000 to 1M PA @ 0x41300000 (CLKMAN_BASE) */
+	MMU_INIT(0xfd200000, 0x41300000, 1, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
+	/* map 1M VA @ 0xfd300000 to 1M PA @ 0x40d00000 (INTCTL_BASE) */
+	MMU_INIT(0xfd300000, 0x40d00000, 1, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
+	/* map 1M VA @ 0xfd400000 to 1M PA @ 0x40100000 (FFUART_BASE) */
+	MMU_INIT(0xfd400000, 0x40100000, 1, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
+	/* map 1M VA @ 0xfd500000 to 1M PA @ 0x40200000 (BTUART_BASE) */
+	MMU_INIT(0xfd500000, 0x40200000, 1, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
+	/* map 1M VA @ 0xfd600000 to 1M PA @ 0x40700000 (STUART_BASE) */
+	MMU_INIT(0xfd600000, 0x40700000, 1, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
+	/* map 1M VA @ 0xfd700000 to 1M PA @ 0x15000000 (ASIC2_BASE) */
+	MMU_INIT(0xfd700000, 0x15000000, 1, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
+	/* map 1M VA @ 0xfd800000 to 1M PA @ 0x14800000 (ASIC3_BASE) */
+	MMU_INIT(0xfd800000, 0x14800000, 1, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
+	/* map 1M VA @ 0xfd900000 to 1M PA @ 0x14000000 (ASIC3_SD_BASE) */
+	MMU_INIT(0xfd900000, 0x14000000, 1, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
+
+	.word 0	/* end of table */
+
diff --git a/sys/arch/evbarm/stand/board/ipaq3.c b/sys/arch/evbarm/stand/board/ipaq3.c
new file mode 100644
index 0000000..7b53792
--- /dev/null
+++ b/sys/arch/evbarm/stand/board/ipaq3.c
@@ -0,0 +1,59 @@
+/*	$NetBSD: iq80321.c,v 1.1 2002/04/17 17:37:52 thorpej Exp $	*/
+
+/*
+ * Copyright (c) 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+
+/*
+ * Board initialization routines for the HP IPAQ3900.
+ */
+
+#include <sys/types.h>
+#include <lib/libsa/stand.h>
+
+#include "board.h"
+
+void
+board_init(void)
+{
+
+	mem_init();
+}
+
+void
+board_fini(void)
+{
+
+	/* Nothing to do here. */
+}
diff --git a/sys/arch/evbarm/stand/board/pxa25x_com.c b/sys/arch/evbarm/stand/board/pxa25x_com.c
new file mode 100644
index 0000000..bb3b507
--- /dev/null
+++ b/sys/arch/evbarm/stand/board/pxa25x_com.c
@@ -0,0 +1,136 @@
+/*	$NetBSD: ns16550.c,v 1.3 2005/12/24 20:07:03 perry Exp $	*/
+
+/*
+ * Copyright (c) 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+
+/* 
+ * This file provides the cons_init() function and console I/O routines
+ * for boards that use 16550-compatible UARTs.
+ */
+
+#include <sys/types.h>
+#include <dev/ic/comreg.h>
+#include <lib/libsa/stand.h>
+
+#include "board.h"
+
+#define	INB(x)		*((volatile uint8_t *) (CONADDR + (4 * x)))
+#define	INW(x)		*((volatile uint32_t *) (CONADDR + (4 * x)))
+#define	OUTB(x, v)	*((volatile uint8_t *) (CONADDR + (4 * x))) = (v)
+#define	OUTW(x, v)	*((volatile uint32_t *) (CONADDR + (4 * x))) = (v)
+
+#define	ISSET(t,f)	((t) & (f))
+
+#ifndef NS16550_FREQ
+#define	NS16550_FREQ	COM_FREQ
+#endif
+
+static int
+comspeed(int speed)
+{
+#define	divrnd(n, q)	(((n)*2/(q)+1)/2)	/* divide and round off */
+
+	int x, err;
+
+	if (speed <= 0)  
+		return (-1);
+	x = divrnd((NS16550_FREQ / 16), speed);
+	if (x <= 0)
+		return (-1);
+	err = divrnd((((quad_t)NS16550_FREQ) / 16) * 1000, speed * x) - 1000;
+	if (err < 0)
+		err = -err; 
+	if (err > COM_TOLERANCE)
+		return (-1);
+	return (x);
+#undef divrnd
+}
+
+void
+cons_init(void)
+{
+	int rate;
+
+	OUTW(com_cfcr, LCR_DLAB);
+	rate = comspeed(CONSPEED);
+	OUTW(com_dlbl, rate);
+	OUTW(com_dlbh, rate >> 8);
+	OUTW(com_cfcr, LCR_8BITS);
+	OUTW(com_mcr, MCR_DTR | MCR_RTS); 
+	OUTW(com_fifo,
+	    FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_1);
+	OUTW(com_ier, 0);
+}
+
+int
+getchar(void)
+{
+	uint8_t stat;
+
+	while (!ISSET(stat = INB(com_lsr), LSR_RXRDY))
+		/* spin */ ;
+	return (INB(com_data));
+}
+
+static void
+iputchar(int c)
+{
+	uint8_t stat;
+	int timo;
+
+	/* Wait for any pending transmission to finish. */
+	timo = 50000;   
+	while (!ISSET(stat = INB(com_lsr), LSR_TXRDY) && --timo)
+		/* spin */ ;
+
+	OUTB(com_data, c);
+
+	/* Wait for this transmission to complete. */
+	timo = 1500000;
+	while (!ISSET(stat = INB(com_lsr), LSR_TXRDY) && --timo)
+		/* spin */ ;
+
+	/* Clear any interrupts generated by this transmission. */
+	(void) INB(com_iir);
+}
+
+void
+putchar(int c)
+{
+
+	if (c == '\n')
+		iputchar('\r');
+	iputchar(c);
+}
diff --git a/sys/arch/evbarm/stand/board/pxa25x_mem.c b/sys/arch/evbarm/stand/board/pxa25x_mem.c
new file mode 100644
index 0000000..0ad29e0
--- /dev/null
+++ b/sys/arch/evbarm/stand/board/pxa25x_mem.c
@@ -0,0 +1,62 @@
+/*	$NetBSD$	*/
+
+/*
+ * Copyright (c) 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed for the NetBSD Project by
+ *	Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+
+/*
+ * This file provides the mem_init() function for boards using the
+ * HP IPAQ3900 handheld.
+ */
+
+#include <sys/types.h>
+#include <lib/libsa/stand.h>
+
+#include "board.h"
+
+void
+mem_init(void)
+{
+	uint32_t start, size, heap;
+
+	start = 0xa0000000;
+
+	/* HP CRL bootloader loads at top of RAM */
+	size = (64 * 1024 * 1024) - (1024 * 1024);
+	heap = (start + size) - BOARD_HEAP_SIZE;
+
+	printf(">> RAM 0x%x - 0x%x, heap at 0x%x\n",
+	    start, (start + size) - 1, heap);
+	setheap((void *)heap, (void *)(start + size - 1));
+}
diff --git a/sys/arch/evbarm/stand/gzboot/IPAQ3_ram_noreloc/Makefile b/sys/arch/evbarm/stand/gzboot/IPAQ3_ram_noreloc/Makefile
new file mode 100644
index 0000000..f0c8bdb
--- /dev/null
+++ b/sys/arch/evbarm/stand/gzboot/IPAQ3_ram_noreloc/Makefile
@@ -0,0 +1,18 @@
+#	$NetBSD: Makefile,v 1.2 2003/04/29 05:36:20 thorpej Exp $
+
+S=	${.CURDIR}/../../../../..
+
+PLATFORM= IPAQ3
+RELOC= 0
+MAXIMAGESIZE= 0		# concatenate
+LOADADDR= 0xa0200000
+
+CPPFLAGS+= -DNORELOC
+CPPFLAGS+= -DCONSPEED=115200
+CPPFLAGS+= -DCONADDR=0x40100000UL
+
+LDSCRIPT= ${.CURDIR}/ldscript
+
+SRCS+=	ipaq3.c pxa25x_com.c pxa25x_mem.c
+
+.include "${S}/arch/evbarm/stand/gzboot/Makefile.gzboot"
diff --git a/sys/arch/evbarm/stand/gzboot/IPAQ3_ram_noreloc/ldscript b/sys/arch/evbarm/stand/gzboot/IPAQ3_ram_noreloc/ldscript
new file mode 100644
index 0000000..189d17c
--- /dev/null
+++ b/sys/arch/evbarm/stand/gzboot/IPAQ3_ram_noreloc/ldscript
@@ -0,0 +1,81 @@
+/*	$NetBSD: ldscript,v 1.4 2005/12/11 12:17:10 christos Exp $	*/
+
+OUTPUT_ARCH(arm)
+ENTRY(FLASH)
+MEMORY
+{
+  /* We will locate the .text section in flash, and will run directly
+     from there just long enough to relocate our .text and .data into
+     a small chunk of SDRAM starting at (SDRAM + 1M).  */
+  flash : o = 0x00000000, l = 2M	/* XXXrkb: lie about flash size */
+  sdram : o = 0xa0100000, l = 1M	/* kernel loads at 0xc0200000 */
+}
+SECTIONS
+{
+  FLASH = 0x00000000;
+
+  /* Read-only sections, merged into text segment: */
+  __text_store = FLASH;
+  .text      :
+  AT (FLASH)
+  {
+    *(.text)
+    *(.text.*)
+    *(.stub)
+    *(.glue_7t) *(.glue_7)
+    *(.rodata) *(.rodata.*)
+  } > sdram =0
+  PROVIDE (__etext = .);
+  PROVIDE (_etext = .);
+  PROVIDE (etext = .);
+  __data_store = FLASH + SIZEOF(.text);
+  .data    :
+  AT (LOADADDR(.text) + SIZEOF(.text))
+  {
+    __data_start = . ;
+    *(.data)
+    *(.data.*)
+  } > sdram
+  .sdata     : 
+  AT (LOADADDR(.data) + SIZEOF(.data))
+  {
+    *(.sdata) 
+    *(.sdata.*)
+    . = ALIGN(32 / 8);
+  } > sdram
+  _edata = .;
+  PROVIDE (edata = .);
+  __bss_start = .;
+  __bss_start__ = .;
+  .sbss      :
+  {
+    PROVIDE (__sbss_start = .);
+    PROVIDE (___sbss_start = .);
+    *(.dynsbss)
+    *(.sbss)
+    *(.sbss.*)
+    *(.scommon)
+    PROVIDE (__sbss_end = .);
+    PROVIDE (___sbss_end = .);
+  } > sdram
+  .bss       :
+  {
+   *(.dynbss)
+   *(.bss)
+   *(.bss.*)
+   *(COMMON)
+   /* Align here to ensure that the .bss section occupies space up to
+      _end.  Align after .bss to ensure correct alignment even if the
+      .bss section disappears because there are no input sections.  */
+   . = ALIGN(32 / 8);
+  } > sdram
+  . = ALIGN(32 / 8);
+  _end = .;
+  _bss_end__ = . ; __bss_end__ = . ; __end__ = . ;
+  PROVIDE (end = .);
+  .image   (FLASH + SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.sdata)) :
+  AT (LOADADDR(.sdata) + SIZEOF(.sdata))
+  {
+    *(.image)
+  }
+}
diff --git a/sys/arch/hpc/stand/include/sys/cdefs.h b/sys/arch/hpc/stand/include/sys/cdefs.h
new file mode 100644
index 0000000..49a23bc
--- /dev/null
+++ b/sys/arch/hpc/stand/include/sys/cdefs.h
@@ -0,0 +1,399 @@
+/*	$NetBSD$	*/
+/*	@NetBSD: cdefs.h,v 1.66 2007/11/26 14:52:34 joerg Exp @	*/
+
+/*
+ * Copyright (c) 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Berkeley Software Design, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)cdefs.h	8.8 (Berkeley) 1/9/95
+ */
+
+#ifndef	_SYS_CDEFS_H_
+#define	_SYS_CDEFS_H_
+
+/*
+ * Macro to test if we're using a GNU C compiler of a specific vintage
+ * or later, for e.g. features that appeared in a particular version
+ * of GNU C.  Usage:
+ *
+ *	#if __GNUC_PREREQ__(major, minor)
+ *	...cool feature...
+ *	#else
+ *	...delete feature...
+ *	#endif
+ */
+#ifdef __GNUC__
+#define	__GNUC_PREREQ__(x, y)						\
+	((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) ||			\
+	 (__GNUC__ > (x)))
+#else
+#define	__GNUC_PREREQ__(x, y)	0
+#endif
+
+#include <machine/cdefs.h>
+#ifdef __ELF__
+#include <sys/cdefs_elf.h>
+#else
+#include <sys/cdefs_aout.h>
+#endif
+
+#if defined(__cplusplus)
+#define	__BEGIN_DECLS		extern "C" {
+#define	__END_DECLS		}
+#define	__static_cast(x,y)	static_cast<x>(y)
+#else
+#define	__BEGIN_DECLS
+#define	__END_DECLS
+#define	__static_cast(x,y)	(x)y
+#endif
+
+/*
+ * The __CONCAT macro is used to concatenate parts of symbol names, e.g.
+ * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
+ * The __CONCAT macro is a bit tricky -- make sure you don't put spaces
+ * in between its arguments.  __CONCAT can also concatenate double-quoted
+ * strings produced by the __STRING macro, but this only works with ANSI C.
+ */
+
+#define	___STRING(x)	__STRING(x)
+#define	___CONCAT(x,y)	__CONCAT(x,y)
+
+#if __STDC__ || defined(__cplusplus)
+#define	__P(protos)	protos		/* full-blown ANSI C */
+#define	__CONCAT(x,y)	x ## y
+#define	__STRING(x)	#x
+
+#define	__const		const		/* define reserved names to standard */
+#define	__signed	signed
+#define	__volatile	volatile
+#if defined(__cplusplus) || defined(__PCC__)
+#define	__inline	inline		/* convert to C++/C99 keyword */
+#else
+#if !defined(__GNUC__) && !defined(__lint__) && !defined(_MSC_VER)
+#define	__inline			/* delete GCC keyword */
+#endif /* !__GNUC__  && !__lint__ */
+#endif /* !__cplusplus */
+
+#else	/* !(__STDC__ || __cplusplus) */
+#define	__P(protos)	()		/* traditional C preprocessor */
+#define	__CONCAT(x,y)	x/**/y
+#define	__STRING(x)	"x"
+
+#ifndef __GNUC__
+#define	__const				/* delete pseudo-ANSI C keywords */
+#define	__inline
+#define	__signed
+#define	__volatile
+#endif	/* !__GNUC__ */
+
+/*
+ * In non-ANSI C environments, new programs will want ANSI-only C keywords
+ * deleted from the program and old programs will want them left alone.
+ * Programs using the ANSI C keywords const, inline etc. as normal
+ * identifiers should define -DNO_ANSI_KEYWORDS.
+ */
+#ifndef	NO_ANSI_KEYWORDS
+#define	const		__const		/* convert ANSI C keywords */
+#define	inline		__inline
+#define	signed		__signed
+#define	volatile	__volatile
+#endif /* !NO_ANSI_KEYWORDS */
+#endif	/* !(__STDC__ || __cplusplus) */
+
+/*
+ * Used for internal auditing of the NetBSD source tree.
+ */
+#ifdef __AUDIT__
+#define	__aconst	__const
+#else
+#define	__aconst
+#endif
+
+/*
+ * The following macro is used to remove const cast-away warnings
+ * from gcc -Wcast-qual; it should be used with caution because it
+ * can hide valid errors; in particular most valid uses are in
+ * situations where the API requires it, not to cast away string
+ * constants. We don't use *intptr_t on purpose here and we are
+ * explicit about unsigned long so that we don't have additional
+ * dependencies.
+ */
+#define __UNCONST(a)	((void *)(unsigned long)(const void *)(a))
+
+/*
+ * The following macro is used to remove the volatile cast-away warnings
+ * from gcc -Wcast-qual; as above it should be used with caution
+ * because it can hide valid errors or warnings.  Valid uses include
+ * making it possible to pass a volatile pointer to memset().
+ * For the same reasons as above, we use unsigned long and not intptr_t.
+ */
+#define __UNVOLATILE(a)	((void *)(unsigned long)(volatile void *)(a))
+
+/*
+ * GCC2 provides __extension__ to suppress warnings for various GNU C
+ * language extensions under "-ansi -pedantic".
+ */
+#if !__GNUC_PREREQ__(2, 0)
+#define	__extension__		/* delete __extension__ if non-gcc or gcc1 */
+#endif
+
+/*
+ * GCC1 and some versions of GCC2 declare dead (non-returning) and
+ * pure (no side effects) functions using "volatile" and "const";
+ * unfortunately, these then cause warnings under "-ansi -pedantic".
+ * GCC2 uses a new, peculiar __attribute__((attrs)) style.  All of
+ * these work for GNU C++ (modulo a slight glitch in the C++ grammar
+ * in the distribution version of 2.5.5).
+ */
+#if !__GNUC_PREREQ__(2, 0)
+#define __attribute__(x)
+#endif
+
+#if __GNUC_PREREQ__(2, 5)
+#define	__dead		__attribute__((__noreturn__))
+#elif defined(__GNUC__)
+#define	__dead		__volatile
+#else
+#define	__dead
+#endif
+
+#if __GNUC_PREREQ__(2, 96)
+#define	__pure		__attribute__((__pure__))
+#elif defined(__GNUC__)
+#define	__pure		__const
+#else
+#define	__pure
+#endif
+
+#if __GNUC_PREREQ__(2, 7)
+#define	__unused	__attribute__((__unused__))
+#else
+#define	__unused	/* delete */
+#endif
+
+#if __GNUC_PREREQ__(3, 1)
+#define	__used		__attribute__((__used__))
+#else
+#define	__used		__unused
+#endif
+
+#if __GNUC_PREREQ__(2, 7)
+#define	__packed	__attribute__((__packed__))
+#define	__aligned(x)	__attribute__((__aligned__(x)))
+#define	__section(x)	__attribute__((__section__(x)))
+#elif defined(__PCC__)
+#define	__packed	/* XXX ignore for now */
+#define	__aligned(x)   	/* XXX ignore for now */
+#define	__section(x)   	/* XXX ignore for now */
+#elif defined(_MSC_VER)
+#define	__packed	/* XXX ignore */
+#define	__aligned(x)   	/* XXX ignore */
+#define	__section(x)   	/* XXX ignore */
+#elif defined(__lint__)
+#define	__packed	/* delete */
+#define	__aligned(x)	/* delete */
+#define	__section(x)	/* delete */
+#else
+#define	__packed	error: no __packed for this compiler
+#define	__aligned(x)	error: no __aligned for this compiler
+#define	__section(x)	error: no __section for this compiler
+#endif
+
+/*
+ * C99 defines the restrict type qualifier keyword, which was made available
+ * in GCC 2.92.
+ */
+#if __STDC_VERSION__ >= 199901L
+#define	__restrict	restrict
+#else
+#if !__GNUC_PREREQ__(2, 92)
+#define	__restrict	/* delete __restrict when not supported */
+#endif
+#endif
+
+/*
+ * C99 defines __func__ predefined identifier, which was made available
+ * in GCC 2.95.
+ */
+#if !(__STDC_VERSION__ >= 199901L)
+#if __GNUC_PREREQ__(2, 6)
+#define	__func__	__PRETTY_FUNCTION__
+#elif __GNUC_PREREQ__(2, 4)
+#define	__func__	__FUNCTION__
+#else
+#define	__func__	""
+#endif
+#endif /* !(__STDC_VERSION__ >= 199901L) */
+
+#if defined(_KERNEL)
+#if defined(NO_KERNEL_RCSIDS)
+#undef __KERNEL_RCSID
+#define	__KERNEL_RCSID(_n, _s)		/* nothing */
+#endif /* NO_KERNEL_RCSIDS */
+#endif /* _KERNEL */
+
+#if !defined(_STANDALONE) && !defined(_KERNEL)
+#if defined(__GNUC__) || defined(__PCC__)
+#define	__RENAME(x)	___RENAME(x)
+#else
+#ifdef __lint__
+#define	__RENAME(x)	__symbolrename(x)
+#else
+#error "No function renaming possible"
+#endif /* __lint__ */
+#endif /* __GNUC__ */
+#else /* _STANDALONE || _KERNEL */
+#define	__RENAME(x)	no renaming in kernel or standalone environment
+#endif
+
+/*
+ * A barrier to stop the optimizer from moving code or assume live
+ * register values. This is gcc specific, the version is more or less
+ * arbitrary, might work with older compilers.
+ */
+#if __GNUC_PREREQ__(2, 95)
+#define	__insn_barrier()	__asm __volatile("":::"memory")
+#else
+#define	__insn_barrier()	/* */
+#endif
+
+/*
+ * GNU C version 2.96 adds explicit branch prediction so that
+ * the CPU back-end can hint the processor and also so that
+ * code blocks can be reordered such that the predicted path
+ * sees a more linear flow, thus improving cache behavior, etc.
+ *
+ * The following two macros provide us with a way to use this
+ * compiler feature.  Use __predict_true() if you expect the expression
+ * to evaluate to true, and __predict_false() if you expect the
+ * expression to evaluate to false.
+ *
+ * A few notes about usage:
+ *
+ *	* Generally, __predict_false() error condition checks (unless
+ *	  you have some _strong_ reason to do otherwise, in which case
+ *	  document it), and/or __predict_true() `no-error' condition
+ *	  checks, assuming you want to optimize for the no-error case.
+ *
+ *	* Other than that, if you don't know the likelihood of a test
+ *	  succeeding from empirical or other `hard' evidence, don't
+ *	  make predictions.
+ *
+ *	* These are meant to be used in places that are run `a lot'.
+ *	  It is wasteful to make predictions in code that is run
+ *	  seldomly (e.g. at subsystem initialization time) as the
+ *	  basic block reordering that this affects can often generate
+ *	  larger code.
+ */
+#if __GNUC_PREREQ__(2, 96)
+#define	__predict_true(exp)	__builtin_expect((exp) != 0, 1)
+#define	__predict_false(exp)	__builtin_expect((exp) != 0, 0)
+#else
+#define	__predict_true(exp)	(exp)
+#define	__predict_false(exp)	(exp)
+#endif
+
+/*
+ * Macros for manipulating "link sets".  Link sets are arrays of pointers
+ * to objects, which are gathered up by the linker.
+ *
+ * Object format-specific code has provided us with the following macros:
+ *
+ *	__link_set_add_text(set, sym)
+ *		Add a reference to the .text symbol `sym' to `set'.
+ *
+ *	__link_set_add_rodata(set, sym)
+ *		Add a reference to the .rodata symbol `sym' to `set'.
+ *
+ *	__link_set_add_data(set, sym)
+ *		Add a reference to the .data symbol `sym' to `set'.
+ *
+ *	__link_set_add_bss(set, sym)
+ *		Add a reference to the .bss symbol `sym' to `set'.
+ *
+ *	__link_set_decl(set, ptype)
+ *		Provide an extern declaration of the set `set', which
+ *		contains an array of the pointer type `ptype'.  This
+ *		macro must be used by any code which wishes to reference
+ *		the elements of a link set.
+ *
+ *	__link_set_start(set)
+ *		This points to the first slot in the link set.
+ *
+ *	__link_set_end(set)
+ *		This points to the (non-existent) slot after the last
+ *		entry in the link set.
+ *
+ *	__link_set_count(set)
+ *		Count the number of entries in link set `set'.
+ *
+ * In addition, we provide the following macros for accessing link sets:
+ *
+ *	__link_set_foreach(pvar, set)
+ *		Iterate over the link set `set'.  Because a link set is
+ *		an array of pointers, pvar must be declared as "type **pvar",
+ *		and the actual entry accessed as "*pvar".
+ *
+ *	__link_set_entry(set, idx)
+ *		Access the link set entry at index `idx' from set `set'.
+ */
+#define	__link_set_foreach(pvar, set)					\
+	for (pvar = __link_set_start(set); pvar < __link_set_end(set); pvar++)
+
+#define	__link_set_entry(set, idx)	(__link_set_begin(set)[idx])
+
+/*
+ * Return the number of elements in a statically-allocated array,
+ * __x.
+ */
+#define	__arraycount(__x)	(sizeof(__x) / sizeof(__x[0]))
+
+/* __BIT(n): nth bit, where __BIT(0) == 0x1. */
+#define	__BIT(__n)	\
+	(((__n) >= NBBY * sizeof(uintmax_t)) ? 0 : ((uintmax_t)1 << (__n)))
+
+/* __BITS(m, n): bits m through n, m < n. */
+#define	__BITS(__m, __n)	\
+	((__BIT(MAX((__m), (__n)) + 1) - 1) ^ (__BIT(MIN((__m), (__n))) - 1))
+
+/* find least significant bit that is set */
+#define	__LOWEST_SET_BIT(__mask) ((((__mask) - 1) & (__mask)) ^ (__mask))
+
+#define	__PRIuBIT	PRIuMAX
+#define	__PRIuBITS	__PRIuBIT
+
+#define	__PRIxBIT	PRIxMAX
+#define	__PRIxBITS	__PRIxBIT
+
+#define	__SHIFTOUT(__x, __mask)	(((__x) & (__mask)) / __LOWEST_SET_BIT(__mask))
+#define	__SHIFTIN(__x, __mask) ((__x) * __LOWEST_SET_BIT(__mask))
+#define	__SHIFTOUT_MASK(__mask) __SHIFTOUT((__mask), (__mask))
+
+#endif /* !_SYS_CDEFS_H_ */
