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