NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

port-evbarm/42151: New evbarm port - Tin Can Tools Hammer module



>Number:         42151
>Category:       port-evbarm
>Synopsis:       There's no port for the TCT Hammer Module
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    port-evbarm-maintainer
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sun Oct 04 23:00:00 +0000 2009
>Originator:     Brett Slager
>Release:        NetBSD 5.99.19
>Organization:
>Environment:
System: NetBSD hammer 5.99.19 NetBSD 5.99.19 (TCTHAMMER) #2: Sun Oct 4 01:14:52 
CDT 2009 
bds@xxxx:/home/bds/src/netbsd/builds/2009092701/src/sys/arch/evbarm/compile/obj/TCTHAMMER
 evbarm
Architecture: arm
Machine: evbarm
>Description:
        Want to run NetBSD on an easy to build around system module?
>How-To-Repeat:
        Buy an unsupported by NetBSD arm cpu system.
        (Well unsupported in that the SMDK2410 kernel touches things it need
        not to on the Hammer...)
>Fix:
        Port NetBSD's SMDK2410 code to run on the Hammer module.


mkdir sys/arch/evbarm/tcthammer
Patches:

Index: sys/arch/evbarm/conf/TCTHAMMER
===================================================================
RCS file: sys/arch/evbarm/conf/TCTHAMMER
diff -N sys/arch/evbarm/conf/TCTHAMMER
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ sys/arch/evbarm/conf/TCTHAMMER      4 Oct 2009 22:14:35 -0000
@@ -0,0 +1,338 @@
+#      $NetBSD$
+#
+#      TCTHAMMER -- Tin Can Tools Hammer Module
+#
+
+include        "arch/evbarm/conf/std.tcthammer"
+
+#options       INCLUDE_CONFIG_FILE     # embed config file in kernel binary
+
+# Enable the hooks used for initializing the root memory-disk.
+#options       MEMORY_DISK_HOOKS
+#options       MEMORY_DISK_DYNAMIC
+#options       MEMORY_DISK_IS_ROOT     # force root on memory disk
+#options       MEMORY_DISK_SERVER=0    # no userspace memory disk support
+#options       MEMORY_DISK_ROOT_SIZE=4096      # size of memory disk, in blocks
+#options       MEMORY_DISK_ROOT_SIZE=2880      # 1.44M, same as a floppy
+
+# 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_ARM9        # Support the ARM9TDMI core
+makeoptions    CPUFLAGS="-march=armv4"
+#options       ARM9_CACHE_WRITE_THROUGH
+
+# 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        WAPBL           # File system journaling support - Experimental
+#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
+
+# These options enable verbose messages for several subsystems.
+# Warning, these may compile large string tables into the kernel!
+#options       MIIVERBOSE      # verbose PHY autoconfig messages
+#options       PCMCIAVERBOSE   # verbose PCMCIA configuration messages
+#options       SCSIVERBOSE     # human readable SCSI error messages
+options        USBVERBOSE      # verbose USB device autoconfig messages
+
+options        NFS_BOOT_BOOTP
+options        NFS_BOOT_DHCP
+options        NFS_BOOT_BOOTPARAM
+
+# Compatibility options
+
+#options       COMPAT_43       # 4.3BSD compatibility.
+options        COMPAT_40       # NetBSD 4.0 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
+
+# Miscellaneous kernel options
+options        KTRACE          # system call tracing, a la ktrace(1)
+#XXX: options  IRQSTATS        # manage IRQ statistics
+#options       KMEMSTATS       # kernel memory statistics
+options        SCSIVERBOSE     # Verbose SCSI errors
+options        PCIVERBOSE      # Verbose PCI descriptions
+options        MIIVERBOSE      # Verbose MII autoconfuration messages
+#options       PCI_CONFIG_DUMP # verbosely dump PCI config space
+options        PCI_NETBSD_CONFIGURE    # Do not rely on BIOS/whatever to
+                                       # configure PCI devices
+#options       PCI_CONFIGURE_VERBOSE   # Show PCI config information
+#options       PCI_DEBUG
+options        DDB_KEYCODE=0x1d        # Enter ddb on ^]
+options        USERCONF        # userconf(4) support
+#options       PIPE_SOCKETPAIR # smaller, but slower pipe(2)
+#options       SYSCTL_INCLUDE_DESCR    # Include sysctl descriptions in kernel
+
+# Development and Debugging options
+
+#options       ARM700BUGTRACK  # track the ARM700 swi bug
+#options       PORTMASTER      # Enable PortMaster only options
+#options       DIAGNOSTIC      # internal consistency checks
+#options       PMAP_DEBUG      # Enable pmap_debug_level code
+#options       VERBOSE_INIT_ARM # verbose bootstraping messages
+#options       KGDB
+#options       DEBUG_KGDB
+#options       DDB             # in-kernel debugger
+#options       DDB_HISTORY_SIZE=100    # Enable history editing in DDB
+#makeoptions   DEBUG="-g"      # compile full symbol table
+config         netbsd  root on ? type ?
+
+# The main bus device
+mainbus0       at root
+
+# The boot CPU
+cpu0           at mainbus?
+
+# Core logic on Samsung S3C2410
+ssio0  at mainbus?
+ssextio0 at ssio0
+
+# integrated UART
+sscom0 at ssio? index 0
+sscom1 at ssio? index 1
+#sscom2        at ssio? index 2
+options        SSCOM0CONSOLE
+#options       SSCOM1CONSOLE
+options CONSPEED=115200
+options KGDB_DEVNAME="\"sscom1\""   # sscom0 or sscom1
+options KGDB_DEVRATE=115200
+
+# SCSI bus support
+scsibus* at scsi?
+
+# SCSI devices
+sd*    at scsibus? target ? lun ?      # SCSI disk drives
+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
+uk*    at scsibus? target ? lun ?      # SCSI unknown
+
+# ATAPI bus support
+atapibus* at atapi?
+
+# ATAPI devices
+# flags have the same meaning as for IDE drives.
+cd*    at atapibus? drive ? flags 0x0000       # ATAPI CD-ROM drives
+sd*    at atapibus? drive ? flags 0x0000       # ATAPI disk drives
+st*    at atapibus? drive ? flags 0x0000       # ATAPI tape drives
+uk*    at atapibus? drive ? flags 0x0000       # ATAPI unknown
+
+# MIDI support
+midi*  at midibus?
+# midi*        at pcppi?               # MIDI interface to the PC speaker
+
+# Audio support
+audio* at audiobus?
+
+# built-in OHCI USB controller
+ohci0  at ssio? addr 0x49000000 intr 26
+options        OHCI_DEBUG
+
+usb*   at ohci0
+
+# USB Hubs
+uhub*  at usb?
+uhub*  at uhub? port ?
+
+# USB HID device
+uhidev*        at uhub? port ? configuration ? interface ?
+
+# USB Mice
+ums*   at uhidev? reportid ?
+wsmouse* at ums? mux 0
+
+# USB Keyboards
+ukbd*  at uhidev? reportid ?
+wskbd* at ukbd? console ? mux 1
+
+# USB serial adapter
+ucycom*        at uhidev? reportid ?
+
+# USB Generic HID devices
+uhid*  at uhidev? reportid ?
+
+# USB Printer
+ulpt*  at uhub? port ? configuration ? interface ?
+
+# USB Modem
+umodem*        at uhub? port ? configuration ?
+ucom*  at umodem?
+
+# USB Mass Storage
+umass* at uhub? port ? configuration ? interface ?
+wd* at umass?
+
+# USB audio
+uaudio*        at uhub? port ? configuration ?
+
+# USB MIDI
+umidi* at uhub? port ? configuration ?
+
+# USB IrDA
+# USB-IrDA bridge spec
+uirda* at uhub? port ? configuration ? interface ?
+irframe* at uirda?
+
+# SigmaTel STIr4200 USB/IrDA Bridge
+ustir* at uhub? port ?
+irframe* at ustir?
+
+# USB Ethernet adapters
+aue*   at uhub? port ?         # ADMtek AN986 Pegasus based adapters
+axe*   at uhub? port ?         # ASIX AX88172 based adapters
+cue*   at uhub? port ?         # CATC USB-EL1201A based adapters
+kue*   at uhub? port ?         # Kawasaki LSI KL5KUSB101B based adapters
+url*   at uhub? port ?         # Realtek RTL8150L based adapters
+
+# Prolific PL2301/PL2302 host-to-host adapter
+upl*   at uhub? port ?
+
+# Serial adapters
+ubsa*  at uhub? port ?         # Belkin serial adapter
+ucom*  at ubsa? portno ?
+
+uftdi* at uhub? port ?         # FTDI FT8U100AX serial adapter
+ucom*  at uftdi? portno ?
+
+umct*  at uhub? port ?         # MCT USB-RS232 serial adapter
+ucom*  at umct? portno ?
+
+uplcom*        at uhub? port ?         # I/O DATA USB-RSAQ2 serial adapter
+ucom*  at uplcom? portno ?
+
+uvscom*        at uhub? port ?         # SUNTAC Slipper U VS-10U serial adapter
+ucom*  at uvscom? portno ?
+
+# Diamond Multimedia Rio 500
+urio*  at uhub? port ?
+
+# USB Handspring Visor
+uvisor*        at uhub? port ?
+ucom*  at uvisor?
+
+# Kyocera AIR-EDGE PHONE
+ukyopon* at uhub? port ?
+ucom*  at ukyopon? portno ?
+
+# USB scanners
+uscanner* at uhub? port ?
+
+# USB scanners that use SCSI emulation, e.g., HP5300
+usscanner* at uhub? port ?
+
+# Y@P firmware loader
+uyap* at uhub? port ?
+
+# D-Link DSB-R100 USB radio
+udsbr* at uhub? port ?
+radio* at udsbr?
+
+# USB Generic driver
+ugen*  at uhub? port ?
+
+# Pseudo-Devices
+
+# disk/mass storage pseudo-devices
+#pseudo-device md              1       # memory disk device (ramdisk)
+#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  ipfilter                # IP filter (firewall) and NAT
+pseudo-device  loop                    # network loopback
+#pseudo-device ppp                     # Point-to-Point Protocol
+#pseudo-device pppoe                   # PPP over Ethernet (RFC 2516)
+#pseudo-device sl                      # Serial Line IP
+#pseudo-device strip                   # Starmode Radio IP (Metricom)
+#pseudo-device irframetty              # IrDA frame line discipline
+#pseudo-device tun                     # network tunneling over tty
+#pseudo-device tap                     # virtual Ethernet
+#pseudo-device gre                     # generic L3 over IP tunnel
+#pseudo-device gif                     # IPv[46] over IPv[46] tunnel (RFC1933)
+#pseudo-device faith                   # IPv[46] tcp relay translation i/f
+#pseudo-device stf                     # 6to4 IPv6 over IPv4 encapsulation
+#pseudo-device vlan                    # IEEE 802.1q encapsulation
+#pseudo-device bridge                  # simple inter-network bridging
+#options       BRIDGE_IPF              # bridge uses IP/IPv6 pfil hooks too
+
+# miscellaneous pseudo-devices
+pseudo-device  pty                     # pseudo-terminals
+pseudo-device  rnd                     # /dev/random and in-kernel generator
+pseudo-device  clockctl                # user control of clock subsystem
+
+# wscons pseudo-devices
+pseudo-device  wsmux                   # mouse & keyboard multiplexor
+#pseudo-device wsfont
+
+#pseudo-device ksyms                   # /dev/ksyms
Index: sys/arch/evbarm/conf/files.tcthammer
===================================================================
RCS file: sys/arch/evbarm/conf/files.tcthammer
diff -N sys/arch/evbarm/conf/files.tcthammer
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ sys/arch/evbarm/conf/files.tcthammer        4 Oct 2009 22:14:35 -0000
@@ -0,0 +1,9 @@
+#      $NetBSD$
+#
+# Tin Can Tools Hammer Module configuration info
+#
+
+# CPU support and integrated peripherals
+include "arch/arm/s3c2xx0/files.s3c2410"
+
+file   arch/evbarm/tcthammer/tcthammer_machdep.c
Index: sys/arch/evbarm/conf/mk.tcthammer
===================================================================
RCS file: sys/arch/evbarm/conf/mk.tcthammer
diff -N sys/arch/evbarm/conf/mk.tcthammer
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ sys/arch/evbarm/conf/mk.tcthammer   4 Oct 2009 22:14:36 -0000
@@ -0,0 +1,12 @@
+#      $NetBSD$
+
+SYSTEM_FIRST_OBJ=      ${BOARDTYPE}_start.o
+SYSTEM_FIRST_SFILE=    ${THISARM}/tcthammer/${BOARDTYPE}_start.S
+
+KERNEL_BASE_VIRT=0xc0200000
+
+SYSTEM_LD_TAIL_EXTRA+=; \
+       echo ${OBJCOPY} -S -O binary $@ $@.bin; \
+       ${OBJCOPY} -S -O binary $@ $@.bin;
+
+EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.bin@}
Index: sys/arch/evbarm/conf/std.tcthammer
===================================================================
RCS file: sys/arch/evbarm/conf/std.tcthammer
diff -N sys/arch/evbarm/conf/std.tcthammer
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ sys/arch/evbarm/conf/std.tcthammer  4 Oct 2009 22:14:36 -0000
@@ -0,0 +1,32 @@
+#      $NetBSD$
+#
+# standard NetBSD/evbarm for TCTHAMMER options
+
+machine        evbarm arm
+include                "conf/std"      # MI standard options
+include                "arch/arm/conf/std.arm" # arch standard options
+
+# Config definitions for TCTHAMMER
+include "arch/evbarm/conf/files.tcthammer"
+
+options        EXEC_ELF32
+options        EXEC_AOUT
+options        EXEC_SCRIPT
+
+# To support easy transit to ../arch/arm/arm32
+options        ARM32
+
+#options       ARM32_NEW_VM_LAYOUT     # Not yet ready for prime-time
+
+# Architecture options
+
+options        S3C2XX0_XTAL_CLK=12000000     # 12MHz Xtal
+
+options        SSCOM_S3C2410
+
+makeoptions    BOARDTYPE="tcthammer"
+makeoptions    BOARDMKFRAG="${THISARM}/conf/mk.tcthammer"
+makeoptions    KERNEL_BASE_PHYS=0x30200000
+options        KERNEL_BASE_EXT=0xc0000000
+
+options        ARM_INTR_IMPL="<arch/arm/s3c2xx0/s3c2410_intr.h>"
Index: sys/arch/evbarm/tcthammer/README
===================================================================
RCS file: sys/arch/evbarm/tcthammer/README
diff -N sys/arch/evbarm/tcthammer/README
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ sys/arch/evbarm/tcthammer/README    4 Oct 2009 22:14:36 -0000
@@ -0,0 +1,143 @@
+This directory contains the NetBSD port to the Tin Can Tools Hammer module.
+
+Support for the TCTHammer was derived by Brett Slager from the SMDK2410 port.
+
+I. Introduction
+---------------
+The Tin Can Tools Hammer module contains a 200 MHz Samsung ARM 920T S3C2410A
+processor, 32MB SDRAM, 16MB NOR flash, and all regulators needed to run on a
+single 5v supply mounted on a 40 pin DIP socket pluggable circuit board.  The
+40 pins bring out a number of S3C2410 features including 2 UART ports, USB
+host, USB device, 8-bit LCD interface, 1 I2C bus, 2 SPI busses, 2 ADC inputs,
+5 external interrupts, 2 timers / PWMs, and various GPIOs.  The Hammer module
+also has a 14 pin JTAG pin header for programming and debugging.
+
+Two accessory boards are also available from Tin Can Tools for Hammer Module
+development:  the Hammer Carrier, and the Nail Board.  Tin Can Tools also
+produces the Flyswatter USB JTAG interface that can be used with the Hammer
+module.  See the Tin Can Tools web site and eLinux Wiki for more details on
+these and the Hammer module.
+       http://www.tincantools.com/
+       http://www.elinux.org/Hammer_Board
+
+Current Hammer peripheral support includes:
+       o On-CPU serial port (sscom)
+       o On-CPU USB host controller (ohci)
+       o On-CPU timers (system clocks)
+
+II. Getting NetBSD Running
+--------------------------
+Initial efforts to load NetBSD on the Hammer module used the Hammer Carrier
+board for it's USB host socket.  The entire ebvarm userland build was placed in
+an ffs filesystem on a USB memork stick.  An NFS root could probably also be
+used with a supported USB ethernet adapter.
+
+The Hammer module comes with the Apex bootloader flashed onto the NOR flash.
+(A linux zImage, initrd rootfs, and JFFS2 filesystem are also preinstalled to
+flash.) Loading NetBSD onto the Hammer requires downloading code via Apex's
+xreceive command:
+
+       Type ^C key to cancel autoboot. 
+
+<hit control-C here>
+
+       apex> xr 0x30800000    
+       C
+
+<send "netbsd.bin" using xmodem in terminal program>
+
+       *** file: netbsd.bin
+       lsx -vv netbsd.bin 
+       Sending netbsd.bin, 19737 blocks: Give your local XMODEM receive 
command now.
+
+<wait a loooong time>
+
+       Bytes Sent:2526464   BPS:8932                            
+
+       Transfer complete
+
+       *** exit status: 0
+
+       apex> go 0x30800000
+       Jumping to 0x30800000...
+
+<NetBSD boots: enter sd0a for root device, none for dump device, ffs for type>
+<Hit enter for /sbin/init, and you're running NetBSD!>
+
+Note #1: resist the urge to load the NetBSD kernel to it's expected physical
+memory location at 0x30200000. The Apex bootloader loads itself to and runs
+from the same location.  The kernel will relocate itself in it's startup code.
+
+Note #2: The stock NetBSD tip program had problems getting the file descriptor
+plumbing right with the sx (send xmodem) command.  I downloaded and compiled
+picocom which worked well with sx for sending the NetBSD kernel to Apex.
+
+III. Writing NetBSD kernel to flash
+First load the NetBSD kernel into SDRAM memory like above:
+
+       apex> xr 0x30800000
+       C
+       *** file: netbsd.bin
+       lsx -vv netbsd.bin 
+       Sending netbsd.bin, 19737 blocks: Give your local XMODEM receive 
command now.
+       Bytes Sent:2526464   BPS:8981                            
+
+       Transfer complete
+
+       *** exit status: 0
+
+Now, we need to erase an area of flash.  Apex and it's environment are stored
+in the first 256k of flash and linux lives in the rest.  WARNING!!!:  This will
+erase linux and linux will no longer auto boot without restoring it to NOR
+flash.  The size we need to erase depends on the size of the netbsd.bin kernel.
+Take it's size and round up to the nearest 128k (flash blocks are 128k in size
+on the Hammer.)  Here the kernel was 2526424 bytes, which rounded up to the
+nearest 128k is 2560k:
+
+       apex> erase nor:256k+2560k
+
+Now we copy the kernel from SDRAM memory to NOR flash:
+
+       apex> copy 0x30800000+2560k nor:256k
+       2621440 bytes transferred
+
+Now to boot, we can simply jump into NOR flash at 256k as the kernel will
+relocate itself:
+
+       apex> g 0x40000
+       Jumping to 0x00040000...
+
+To automatically boot NetBSD from flash we can set the Apex environment to
+execute the NetBSD kernel after a delay that allows access back into Apex:
+
+       apex> setenv startup wait 50 Type ^C key to cancel autoboot.; go 0x40000
+
+Restart Apex:
+
+       apex> g 0
+
+Now NetBSD will automatically boot after a 5 second delay.  Linux can be
+restored by following the instructions from the eLinux wiki.  The original
+startup environment can be restored with "unsetenv startup".
+
+IV. Missing support (TODO)
+---------------------------
+o      Generic support for "System on Chip" platform multiplexed pin glue
+       (CPU / MD / MI)
+o      sscom driver only works with the first two UARTs -- allow for the 3rd
+       (CPU)
+o      On-CPU RTC driver (Hammer is missing battery backup for it though)
+       (CPU)
+o      On-CPU watchdog timer (CPU)
+o      On-CPU spi driver that works with the MI SPI bus (CPU)
+o      On-CPU i2c driver for MI iic bus (CPU)
+o      NOR flash driver (MD / MI)
+o      USB device port driver / MI USB device level support (CPU / MD / MI)
+o      MI gpio driver support for usable CPU gpio pins (CPU / MD)
+o      SD/MMC support for SPI connected cards (Carrier has socket hooked up to
+       2nd SPI port) (MD / MI)
+o      LED device support for GPF0 on module LED, and Carrier / Nail LEDs
+       (MD / MI)
+o      Pushbutton device support for Carrier / Nail pushbuttons (MD / MI)
+o      Power and peripheral clock management support (CPU / MI?)
+o      Gzboot adaptation of SMDK2410 version (MD standalone)
Index: sys/arch/evbarm/tcthammer/tcthammer_machdep.c
===================================================================
RCS file: sys/arch/evbarm/tcthammer/tcthammer_machdep.c
diff -N sys/arch/evbarm/tcthammer/tcthammer_machdep.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ sys/arch/evbarm/tcthammer/tcthammer_machdep.c       4 Oct 2009 22:14:37 
-0000
@@ -0,0 +1,1002 @@
+/*     $NetBSD$ */
+
+/*
+ * Copyright (c) 2002, 2003 Fujitsu Component Limited
+ * Copyright (c) 2002, 2003, 2005 Genetec Corporation
+ * 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. Neither the name of The Fujitsu Component Limited nor 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 FUJITSU COMPONENT LIMITED AND 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 FUJITSU COMPONENT LIMITED OR 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.
+ */
+/*
+ * Copyright (c) 2001,2002 ARM Ltd
+ * 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. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD
+ * 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 integrator board
+ *
+ * Created      : 24/11/97
+ */
+
+/*
+ * Machine dependant functions for kernel setup for Tin Can Tools Hammer 
module.
+ * Derived from sys/arch/evbarm/smdk2xx0/smdk2410_machdep.c
+ * XXXX bds This should be shared among similar platforms
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD$");
+
+#include "opt_ddb.h"
+#include "opt_kgdb.h"
+#include "opt_pmap_debug.h"
+#include "opt_md.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/termios.h>
+#include <sys/ksyms.h>
+
+#include <uvm/uvm_extern.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
+
+#include <machine/bootconfig.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/frame.h>
+#include <machine/intr.h>
+#include <arm/undefined.h>
+
+#include <arm/arm32/machdep.h>
+
+#include <arm/s3c2xx0/s3c2410reg.h>
+#include <arm/s3c2xx0/s3c2410var.h>
+
+#include "ksyms.h"
+
+#ifndef        SDRAM_START
+#define        SDRAM_START     S3C2410_SDRAM_START
+#endif
+
+/* TCT Hammer module has 32MB SDRAM, 16MB NOR Flash. */
+#ifndef        SDRAM_SIZE
+#define        SDRAM_SIZE      (32*1024*1024)
+#endif
+
+/*
+ * Address to map I/O registers in early initialize stage.
+ */
+#define TCTHAMMER_IO_VBASE     0xfd000000
+
+/* 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
+
+/* Memory disk support */
+#if defined(MEMORY_DISK_DYNAMIC) && defined(MEMORY_DISK_ROOT_ADDR)
+#define DO_MEMORY_DISK
+/* We have memory disk image outside of the kernel on ROM. */
+#ifdef MEMORY_DISK_ROOT_ROM
+/* map the image directory and use read-only */
+#else
+/* copy the image to RAM */
+#endif
+#endif
+
+
+/*
+ * 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 = (u_int)0;
+
+/* Define various stack sizes in pages */
+#define IRQ_STACK_SIZE 1
+#define ABT_STACK_SIZE 1
+#define UND_STACK_SIZE 1
+
+BootConfig bootconfig;         /* Boot config storage */
+char *boot_args = NULL;
+char *boot_file = NULL;
+
+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 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 irqstack;
+pv_addr_t undstack;
+pv_addr_t abtstack;
+pv_addr_t kernelstack;
+
+vm_offset_t msgbufphys;
+
+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       /* L2 table for mapping zero page */
+#define KERNEL_PT_KERNEL       1       /* L2 table for mapping kernel */
+#define        KERNEL_PT_KERNEL_NUM    2       /* L2 tables for mapping kernel 
VM */
+
+#define KERNEL_PT_VMDATA       (KERNEL_PT_KERNEL + KERNEL_PT_KERNEL_NUM)
+
+#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;
+
+/* Prototypes */
+
+void consinit(void);
+void kgdb_port_init(void);
+
+
+#include "com.h"
+#if NCOM > 0
+#include <dev/ic/comreg.h>
+#include <dev/ic/comvar.h>
+#endif
+
+#include "sscom.h"
+#if NSSCOM > 0
+#include "opt_sscom.h"
+#include <arm/s3c2xx0/sscom_var.h>
+#endif
+
+/*
+ * Define the default console speed for the board.  This is generally
+ * what the firmware provided with the board defaults to.
+ */
+#ifndef CONSPEED
+#define CONSPEED B115200       /* TTYDEF_SPEED */
+#endif
+#ifndef CONMODE
+#define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8)   /* 8N1 */
+#endif
+
+int comcnspeed = CONSPEED;
+int comcnmode = CONMODE;
+
+
+/*
+ * 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
+
+       cpu_reset_address = vtophys((u_int)s3c2410_softreset);
+
+       /*
+        * If we are still cold then hit the air brakes
+        * and crash to earth fast
+        */
+       if (cold) {
+               doshutdownhooks();
+               pmf_system_shutdown(boothowto);
+               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 */
+
+       /*
+        * 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();
+
+       pmf_system_shutdown(boothowto);
+
+       /* 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))
+
+#define        _V(n)   (TCTHAMMER_IO_VBASE + (n) * L1_S_SIZE)
+
+#define        GPIO_VBASE      _V(0)
+#define        INTCTL_VBASE    _V(1)
+#define        CLKMAN_VBASE    _V(2)
+#define        UART_VBASE      _V(3)
+#ifdef MEMORY_DISK_DYNAMIC
+#define        MEMORY_DISK_VADDR       _V(4)
+#endif
+
+static const struct pmap_devmap tcthammer_devmap[] = {
+       /* GPIO registers */
+       {
+               GPIO_VBASE,
+               _A(S3C2410_GPIO_BASE),
+               _S(S3C2410_GPIO_SIZE),
+               VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE,
+       },
+       {
+               INTCTL_VBASE,
+               _A(S3C2410_INTCTL_BASE),
+               _S(S3C2410_INTCTL_SIZE),
+               VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE,
+       },
+       {
+               CLKMAN_VBASE,
+               _A(S3C2410_CLKMAN_BASE),
+               _S(S3C24X0_CLKMAN_SIZE),
+               VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE,
+       },
+       {       /* UART registers for UART0, 1, 2. */
+               UART_VBASE,
+               _A(S3C2410_UART0_BASE),
+               _S(S3C2410_UART_BASE(3) - S3C2410_UART0_BASE),
+               VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE,
+       },
+
+       { 0, 0, 0, 0 }
+};
+
+#undef _A
+#undef _S
+
+static inline  pd_entry_t *
+read_ttb(void)
+{
+       long ttb;
+
+       __asm volatile("mrc     p15, 0, %0, c2, c0, 0" : "=r"(ttb));
+
+
+       return (pd_entry_t *)(ttb & ~((1 << 14) - 1));
+}
+
+
+#define        ioreg_read8(a)          (*(volatile uint8_t *)(a))
+#define        ioreg_write8(a,v)       (*(volatile uint8_t *)(a)=(v))
+#define        ioreg_read32(a)         (*(volatile uint32_t *)(a))
+#define        ioreg_write32(a,v)      (*(volatile uint32_t *)(a)=(v))
+
+/*
+ * 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)
+{
+       int loop;
+       int loop1;
+       u_int l1pagetable;
+       extern int etext __asm("_etext");
+       extern int end __asm("_end");
+
+#ifdef DO_MEMORY_DISK
+       vm_offset_t md_root_start;
+#define MD_ROOT_SIZE (MEMORY_DISK_ROOT_SIZE * DEV_BSIZE)
+#endif
+
+       /*
+        * Heads up ... Setup the CPU / MMU / TLB functions
+        */
+       if (set_cpufuncs())
+               panic("cpu not recognized!");
+
+       /*
+        * Map I/O registers that are used in startup.  Now we are
+        * still using page table prepared by bootloader.  Later we'll
+        * map those registers at the same address in the kernel page
+        * table.
+        */
+       pmap_devmap_bootstrap((vaddr_t)read_ttb(), tcthammer_devmap);
+
+       /* Disable all peripheral interrupts */
+       ioreg_write32(INTCTL_VBASE + INTCTL_INTMSK, ~0);
+
+       /* initialize some variables so that splfoo() doesn't
+          touch illegal address.  */
+       s3c2xx0_intr_bootstrap(INTCTL_VBASE);
+
+       consinit();
+#ifdef VERBOSE_INIT_ARM
+       printf("consinit done\n");
+#endif
+
+#ifdef KGDB
+       kgdb_port_init();
+#endif
+
+#ifdef VERBOSE_INIT_ARM
+       /* Talk to the user */
+       printf("\nNetBSD/evbarm (TCTHAMMER) booting ...\n");
+#endif
+       /*
+        * Ok we have the following memory map
+        *
+        * Physical Address Range     Description
+        * -----------------------    ----------------------------------
+        * 0x00000000 - 0x00ffffff    Intel flash Memory   (16MB)
+        * 0x02000000 - 0x020fffff    AMD flash Memory   (1MB)
+        * or                          (depend on DIPSW setting)
+        * 0x00000000 - 0x000fffff    AMD flash Memory   (1MB)
+        * 0x02000000 - 0x02ffffff    Intel flash Memory   (16MB)
+        *
+        * 0x30000000 - 0x31ffffff    SDRAM (32MB)
+        *
+        * The initarm() has the responsibility for creating the kernel
+        * page tables.
+        * It must also set up various memory pointers that are used
+        * by pmap etc.
+        */
+
+       /* 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 = SDRAM_START;
+       bootconfig.dram[0].pages = SDRAM_SIZE / PAGE_SIZE;
+
+       /*
+        * Set up the variables that define the availablilty of
+        * physical memory.  For now, we're going to set
+        * physical_freestart to 0x08200000 (where the kernel
+        * was loaded), and allocate the memory we need downwards.
+        * If we get too close to the bottom of SDRAM, 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);
+
+#ifdef DO_MEMORY_DISK
+#ifdef MEMORY_DISK_ROOT_ROM
+       md_root_start = MEMORY_DISK_ROOT_ADDR;
+       boothowto |= RB_RDONLY;
+#else
+       /* Reserve physmem for ram disk */
+       md_root_start = ((physical_end - MD_ROOT_SIZE) & ~(L1_S_SIZE-1));
+       printf("Reserve %ld bytes for memory disk\n",  
+           physical_end - md_root_start);
+       /* copy fs contents */
+       memcpy((void *)md_root_start, (void *)MEMORY_DISK_ROOT_ADDR,
+           MD_ROOT_SIZE);
+       physical_end = md_root_start;
+#endif
+#endif
+
+       physical_freestart = SDRAM_START;       /* XXX */
+       physical_freeend = SDRAM_START + 0x00200000;
+
+       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
+
+       /*
+        * XXX
+        * 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;
+       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\n");
+
+       /*
+        * Allocate a page for the system page mapped to V0x00000000
+        * This page will just contain the system vectors and can be
+        * shared by all processes.
+        */
+       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);
+
+#ifdef VERBOSE_INIT_ARM
+       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);
+#endif
+
+       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, 0x00000000,
+           &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;
+
+               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. */
+#if 1
+       /* MULTI-ICE requires that page 0 is NC/NB so that it can download the
+        * cache-clean code there.  */
+       pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa,
+           VM_PROT_READ | VM_PROT_WRITE, PTE_NOCACHE);
+#else
+       pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa,
+           VM_PROT_READ | VM_PROT_WRITE, PTE_CACHE);
+#endif
+
+#ifdef MEMORY_DISK_DYNAMIC
+       /* map MD root image */
+       pmap_map_chunk(l1pagetable, MEMORY_DISK_VADDR, md_root_start,
+           MD_ROOT_SIZE, VM_PROT_READ | VM_PROT_WRITE, PTE_CACHE);
+
+       md_root_setconf((void *)md_root_start, MD_ROOT_SIZE);
+#endif /* MEMORY_DISK_DYNAMIC */
+       /*
+        * map integrated peripherals at same address in l1pagetable
+        * so that we can continue to use console.
+        */
+       pmap_devmap_bootstrap(l1pagetable, tcthammer_devmap);
+
+       /*
+        * 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.
+        */
+       {
+               physical_freestart = physical_start +
+                   (((((uintptr_t)&end) + 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
+       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));
+
+       /*
+        * 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("done!\n");
+#endif
+
+#ifdef VERBOSE_INIT_ARM
+       printf("bootstrap done.\n");
+#endif
+
+       arm32_vector_init(ARM_VECTORS_LOW, ARM_VEC_ALL);
+
+       /*
+        * 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.
+        */
+#ifdef VERBOSE_INIT_ARM
+       printf("init subsystems: stacks ");
+#endif
+
+       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.
+        */
+#ifdef VERBOSE_INIT_ARM
+       printf("vectors ");
+#endif
+       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 */
+#ifdef VERBOSE_INIT_ARM
+       printf("undefined ");
+#endif
+       undefined_init();
+
+       /* Load memory into UVM. */
+#ifdef VERBOSE_INIT_ARM
+       printf("page ");
+#endif
+       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 */
+#ifdef VERBOSE_INIT_ARM
+       printf("pmap ");
+#endif
+       pmap_bootstrap(KERNEL_VM_BASE, KERNEL_VM_BASE + KERNEL_VM_SIZE);
+
+       /* Setup the IRQ system */
+#ifdef VERBOSE_INIT_ARM
+       printf("irq ");
+#endif
+       /* XXX irq_init(); */
+
+#ifdef VERBOSE_INIT_ARM
+       printf("done.\n");
+#endif
+
+/* XXXX bds: Need a way to get boot args from the loader */
+#ifdef BOOTHOWTO
+       boothowto |= BOOTHOWTO;
+#endif
+#ifdef VERBOSE_INIT_ARM
+       printf( "boothowto: %x\n", boothowto );
+#endif
+
+#ifdef KGDB
+       if (boothowto & RB_KDB) {
+               kgdb_debug_init = 1;
+               kgdb_connect(1);
+       }
+#endif
+
+#ifdef DDB
+       db_machine_init();
+       if (boothowto & RB_KDB)
+               Debugger();
+#endif
+
+       /* We return the new stack pointer address */
+       return (kernelstack.pv_va + USPACE_SVC_STACK_TOP);
+}
+
+void
+consinit(void)
+{
+       static int consinit_done = 0;
+       bus_space_tag_t iot = &s3c2xx0_bs_tag;
+       int pclk;
+
+       if (consinit_done != 0)
+               return;
+
+       consinit_done = 1;
+
+       s3c24x0_clock_freq2(CLKMAN_VBASE, NULL, NULL, &pclk);
+
+#if NSSCOM > 0
+#ifdef SSCOM0CONSOLE
+       if (0 == s3c2410_sscom_cnattach(iot, 0, comcnspeed,
+               pclk, comcnmode))
+               return;
+#endif
+#ifdef SSCOM1CONSOLE
+       if (0 == s3c2410_sscom_cnattach(iot, 1, comcnspeed,
+               pclk, comcnmode))
+               return;
+#endif
+#endif                         /* NSSCOM */
+#if NCOM>0 && defined(CONCOMADDR)
+       if (comcnattach(&isa_io_bs_tag, CONCOMADDR, comcnspeed,
+               COM_FREQ, COM_TYPE_NORMAL, comcnmode))
+               panic("can't init serial console @%x", CONCOMADDR);
+       return;
+#endif
+
+       consinit_done = 0;
+}
+
+
+#ifdef KGDB
+
+#if (NSSCOM > 0)
+
+#ifdef KGDB_DEVNAME
+const char kgdb_devname[] = KGDB_DEVNAME;
+#else
+const char kgdb_devname[] = "";
+#endif
+
+#ifndef KGDB_DEVMODE
+#define KGDB_DEVMODE ((TTYDEF_CFLAG & ~(CSIZE|CSTOPB|PARENB))|CS8) /* 8N1 */
+#endif
+int kgdb_sscom_mode = KGDB_DEVMODE;
+
+#endif                         /* NSSCOM */
+
+void
+kgdb_port_init(void)
+{
+#if (NSSCOM > 0)
+       int unit = -1;
+       int pclk;
+
+       if (strcmp(kgdb_devname, "sscom0") == 0)
+               unit = 0;
+       else if (strcmp(kgdb_devname, "sscom1") == 0)
+               unit = 1;
+
+       if (unit >= 0) {
+               s3c24x0_clock_freq2(CLKMAN_VBASE, NULL, NULL, &pclk);
+
+               s3c2410_sscom_kgdb_attach(&s3c2xx0_bs_tag,
+                   unit, kgdb_rate, pclk, kgdb_sscom_mode);
+       }
+#endif
+}
+#endif
+
+static inline void
+writeback_dcache_line(vaddr_t va)
+{
+       /* writeback Dcache line */
+       /* we can't use cpu_dcache_wb_range() here, because cpufuncs for ARM9
+        * assume write-through cache, and always flush Dcache instead of
+        * cleaning it. Since Boot loader maps page table with write-back
+        * cached, we really need to clean Dcache. */
+       __asm("mcr      p15, 0, %0, c7, c10, 1"
+           : : "r"(va));
+}
+
+static inline void
+clean_dcache_line(vaddr_t va)
+{
+       /* writeback and invalidate Dcache line */
+       __asm("mcr      p15, 0, %0, c7, c14, 1"
+           : : "r"(va));
+}
+
+static struct arm32_dma_range tcthammer_dma_ranges[1];
+
+bus_dma_tag_t
+s3c2xx0_bus_dma_init(struct arm32_bus_dma_tag *dma_tag_template)
+{
+       extern paddr_t physical_start, physical_end;
+       struct arm32_bus_dma_tag *dmat;
+
+       tcthammer_dma_ranges[0].dr_sysbase = physical_start;
+       tcthammer_dma_ranges[0].dr_busbase = physical_start;
+       tcthammer_dma_ranges[0].dr_len = physical_end - physical_start;
+
+#if 1
+       dmat = dma_tag_template;
+#else
+       dmat = malloc(sizeof *dmat, M_DEVBUF, M_NOWAIT);
+       if (dmat == NULL)
+               return NULL;
+       *dmat =  *dma_tag_template;
+#endif
+
+       dmat->_ranges = tcthammer_dma_ranges;
+       dmat->_nranges = 1;
+
+       return dmat;
+}
Index: sys/arch/evbarm/tcthammer/tcthammer_start.S
===================================================================
RCS file: sys/arch/evbarm/tcthammer/tcthammer_start.S
diff -N sys/arch/evbarm/tcthammer/tcthammer_start.S
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ sys/arch/evbarm/tcthammer/tcthammer_start.S 4 Oct 2009 22:14:37 -0000
@@ -0,0 +1,171 @@
+/*     $NetBSD$ */
+
+/*
+ * Copyright (c) 2002, 2003 Fujitsu Component Limited
+ * Copyright (c) 2002, 2003 Genetec Corporation
+ * 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. Neither the name of The Fujitsu Component Limited nor 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 FUJITSU COMPONENT LIMITED AND 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 FUJITSU COMPONENT LIMITED OR 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 */
+
+#include <arm/s3c2xx0/s3c2410reg.h>    /* for S3C2410_SDRAM_START */
+
+/*
+ * Kernel start routine for Tin Can Tools Hammer Module.
+ * Derived from sys/arch/evbarm/smdk2xx0/smdk2410_start.S
+ * This is the first code excuted after the kernel is loaded by boot program.
+ * Kernel must be prepared to relocate itself because it wants to run from the
+ * same location as the Apex bootloader occupies.
+ */
+       .text
+
+#ifndef        SDRAM_START
+#define        SDRAM_START     S3C2410_SDRAM_START
+#endif
+#define KERNEL_TEXT_ADDR       (SDRAM_START+0x00200000)
+
+       .global _C_LABEL(tcthammer_start)
+_C_LABEL(tcthammer_start):
+       /* Disable interrupt */
+       mrs     r0, cpsr
+       orr     r0, r0, #I32_bit
+       msr     cpsr, r0
+
+       /* Are we running on right place ? */
+       adr r0, _C_LABEL(tcthammer_start)
+       ldr     r2, =KERNEL_TEXT_ADDR
+       cmp     r0, r2
+       beq     tcthammer_start_ram
+       
+       /*
+        * move me to RAM
+        */
+       ldr r1, Lcopy_size
+       adr r0, _C_LABEL(tcthammer_start)
+       add r1, r1, #3
+       mov r1, r1, LSR #2
+       mov r4, r2
+
+       cmp r0, r2
+       bhs 5f
+
+       /* src < dest. copy from top */
+       add r0,r0,r1,LSL #2
+       add r2,r2,r1,LSL #2
+
+3:     ldr r3,[r0,#-4]!
+       str r3,[r2,#-4]!
+       subs r1,r1,#1
+       bhi 3b
+       b 7f
+
+       /* src >= dest. copy from bottom */
+5:     ldr r3,[r0],#4
+       str r3,[r2],#4
+       subs r1,r1,#1
+       bhi 5b
+
+7:     
+       /* Jump to RAM */
+       ldr r0, Lstart_off
+       add pc, r4, r0
+
+Lcopy_size:    .word _edata-_C_LABEL(tcthammer_start)
+Lstart_off:    .word tcthammer_start_ram-_C_LABEL(tcthammer_start)
+
+tcthammer_start_ram:   
+       /*
+        *  Kernel is loaded in SDRAM (0x30200000..), and is expected to run
+        *  in VA 0xc0200000..  
+        */
+
+       /* Disable MMU for a while */
+       mrc     p15, 0, r2, c1, c0, 0
+       bic     r2, r2, #CPU_CONTROL_MMU_ENABLE
+       mcr     p15, 0, r2, c1, c0, 0
+
+       nop
+       nop
+       nop
+       
+       mov     r0,#SDRAM_START      /* pagetable */
+       adr     r4, mmu_init_table
+       b       2f
+1:
+       str     r3, [r0, r2]
+       add     r2, r2, #4
+       add     r3, r3, #(L1_S_SIZE)
+       adds    r1, r1, #-1
+       bhi     1b
+2:     
+       ldmia   r4!, {r1,r2,r3}   /* # of sections, PA|attr, VA */
+       cmp     r1, #0
+       bne     1b      
+
+       mcr     p15, 0, r0, c2, c0, 0   /* Set TTB */
+       mcr     p15, 0, r0, c8, c7, 0   /* Flush TLB */
+
+       /* Set the Domain Access register.  Very important! */
+       mov     r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT)
+       mcr     p15, 0, r0, c3, c0, 0
+
+       /* Enable MMU */
+       mrc     p15, 0, r0, c1, c0, 0
+       orr     r0, r0, #CPU_CONTROL_MMU_ENABLE
+       mcr     p15, 0, r0, c1, c0, 0
+       
+       nop
+       nop
+       nop
+
+       /* Jump to kernel code in TRUE VA */
+       adr     r0, Lstart
+       ldr     pc, [r0]
+
+Lstart:
+       .word   start
+       
+#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 VA 0xc0000000..0xc3ffffff to PA 0x30000000..0x33ffffff */
+       MMU_INIT(0xc0000000, SDRAM_START, 64, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
+
+       .word 0 /* end of table */
+



Home | Main Index | Thread Index | Old Index