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_ */