diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/arch/hpcarm/conf/INSTALL_WZERO3 src/sys/arch/hpcarm/conf/INSTALL_WZERO3 --- src.orig/sys/arch/hpcarm/conf/INSTALL_WZERO3 1970-01-01 09:00:00.000000000 +0900 +++ src/sys/arch/hpcarm/conf/INSTALL_WZERO3 2009-01-30 02:57:20.000000000 +0900 @@ -0,0 +1,13 @@ +# +# kernel config file for system install +# +# $NetBSD$ +# + +include "arch/hpcarm/conf/WZERO3" + +# Enable the hooks used for initializing the root memory-disk. +options MEMORY_DISK_HOOKS +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=8704 # size of memory disk, in blocks diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/arch/hpcarm/conf/IPAQ src/sys/arch/hpcarm/conf/IPAQ --- src.orig/sys/arch/hpcarm/conf/IPAQ 2009-12-07 17:26:26.000000000 +0900 +++ src/sys/arch/hpcarm/conf/IPAQ 2009-12-07 17:36:33.000000000 +0900 @@ -3,7 +3,7 @@ # iPAQ H3600 -- Windows-CE based PDA # -include "arch/hpcarm/conf/std.hpcarm" +include "arch/hpcarm/conf/std.sa11x0" #options INCLUDE_CONFIG_FILE # embed config file in kernel binary diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/arch/hpcarm/conf/JORNADA720 src/sys/arch/hpcarm/conf/JORNADA720 --- src.orig/sys/arch/hpcarm/conf/JORNADA720 2009-12-07 17:26:26.000000000 +0900 +++ src/sys/arch/hpcarm/conf/JORNADA720 2009-12-07 17:36:33.000000000 +0900 @@ -3,7 +3,7 @@ # JORNADA -- Windows-CE based jornada 720 # -include "arch/hpcarm/conf/std.hpcarm" +include "arch/hpcarm/conf/std.sa11x0" #options INCLUDE_CONFIG_FILE # embed config file in kernel binary diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/arch/hpcarm/conf/JORNADA820 src/sys/arch/hpcarm/conf/JORNADA820 --- src.orig/sys/arch/hpcarm/conf/JORNADA820 2009-12-07 17:26:26.000000000 +0900 +++ src/sys/arch/hpcarm/conf/JORNADA820 2009-12-07 17:36:33.000000000 +0900 @@ -3,7 +3,7 @@ # JORNADA -- Windows-CE based jornada 820 # -include "arch/hpcarm/conf/std.hpcarm" +include "arch/hpcarm/conf/std.sa11x0" #options INCLUDE_CONFIG_FILE # embed config file in kernel binary diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/arch/hpcarm/conf/WZERO3 src/sys/arch/hpcarm/conf/WZERO3 --- src.orig/sys/arch/hpcarm/conf/WZERO3 1970-01-01 09:00:00.000000000 +0900 +++ src/sys/arch/hpcarm/conf/WZERO3 2009-12-07 17:39:05.000000000 +0900 @@ -0,0 +1,268 @@ +# $NetBSD$ +# +# WZERO3 -- Sharp Windows Mobile 5 based PDA +# + +include "arch/hpcarm/conf/std.pxa2x0" + +#options INCLUDE_CONFIG_FILE # embed config file in kernel binary + +#ident "GENERIC-$Revision$" + +# memory size +options DRAM_PAGES="16384" # 4Ki * 16384page = 64MiB +#options DRAM_PAGES="32768" # 4Ki * 32768page = 128MiB (WS011SH) + +# 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 + +# For XScale systems +options CPU_XSCALE_PXA270 # Support the XScale PXA27x core +makeoptions CPUFLAGS="-mcpu=xscale" + +# Architecture options +options XSCALE_CACHE_READ_WRITE_ALLOCATE +options PXAGPIO_HAS_GPION_INTRS + +# 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 OVERLAY # overlay filesystem +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 TMPFS # Efficient memory file-system +#file-system UDF # experimental - OSTA UDF CD/DVD file-system + +# File system options +#options QUOTA # UFS quotas +#options FFS_EI # FFS Endian Independant support +#options SOFTDEP # FFS soft updates support. +options WAPBL # File system journaling support - Experimental +#options FFS_NO_SNAPSHOT # No FFS snapshot support +#options NFSSERVER + +# 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 + +# Compatibility options + +#options COMPAT_43 # 4.3BSD compatibility. +options COMPAT_50 # NetBSD 5.0 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 SYSVSHM # System V-like memory sharing + + +# Miscellaneous kernel options +options KTRACE # system call tracing, a la ktrace(1) +options IRQSTATS # manage IRQ statistics +options KMEMSTATS # kernel memory statistics +#options SCSIVERBOSE # Verbose SCSI errors +options USERCONF # userconf(4) support +#options PIPE_SOCKETPAIR # smaller, but slower pipe(2) +#options SYSCTL_INCLUDE_DESCR # Include sysctl descriptions in kernel +options NFS_BOOT_DHCP + +# +# wscons options +# +# builtin terminal emulations +options WSEMUL_VT100 +# allocate a number of virtual screens at autoconfiguration time +#options WSDISPLAY_DEFAULTSCREENS=2 + +# customization of console and kernel output - see dev/wscons/wsdisplayvar.h +#options WSDISPLAY_CUSTOM_OUTPUT # color customization from wsconsctl(8) +#options WS_DEFAULT_FG=WSCOL_WHITE +#options WS_DEFAULT_BG=WSCOL_BLACK +#options WS_DEFAULT_COLATTR="(0)" +#options WS_DEFAULT_MONOATTR="(0)" +options WS_KERNEL_FG=WSCOL_GREEN +#options WS_KERNEL_BG=WSCOL_BLACK +#options WS_KERNEL_COLATTR="" +#options WS_KERNEL_MONOATTR="" + +# Development and Debugging options + +#options VERBOSE_INIT_ARM +#options BOOT_DUMP # Enable memorydump at boot +options DIAGNOSTIC # internal consistency checks +#options DEBUG # expensive debugging checks/support +#options PMAP_DEBUG # Enable pmap_debug_level code +options DDB # in-kernel debugger +options DDB_HISTORY_SIZE=512 # 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? + +# integrated peripherals +pxaip0 at mainbus? + +pxaintc0 at pxaip? addr 0x40d00000 # interrupt controller +pxagpio0 at pxaip? addr 0x40e00000 # GPIO +pxartc0 at pxaip? addr 0x40900000 # RTC + +# 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 + +# Serial +# integrated 16550 UARTs +options COM_PXA2X0 +com0 at pxaip? addr 0x40100000 intr 22 # Full Function UART +#options CONSPEED=115200 + +# OS Timer +saost* at pxaip? addr 0x40a00000 size 0x20 + +# Physical console +lcd* at pxaip? +wsdisplay* at lcd? console ? + +# Keyboard +wzero3kbd0 at pxaip? +hpckbd* at wzero3kbd? +wskbd0 at hpckbd? mux 1 + +# integrated MMC/SD contoller +pxamci0 at pxaip? addr 0x41100000 size 0x48 +sdmmc* at pxamci? +ld* at sdmmc? # MMC/SD/SDHC card + +# USB Controller and Devices +#wzero3usb* at pxaip? +#ohci0 at pxaip? # USB Host Controller + +# USB bus support +#usb* at ohci? + +# 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 Generic HID devices +#uhid* at uhidev? reportid ? + +# USB Mass Storage +#umass* at uhub? port ? configuration ? interface ? +#wd* at umass? + +# SCSI bus support +#scsibus* at scsi? + +# SCSI devices +#sd* at scsibus? target ? lun ? # SCSI disk drives +#cd* at scsibus? target ? lun ? # SCSI CD-ROM drives +#uk* at scsibus? target ? lun ? # SCSI unknown + +# USB Generic driver +#ugen* at uhub? port ? +# On ugen bulk endpoints, perform read-ahead and write-behind. +#options UGEN_BULK_RA_WB + + +# Pseudo-devices +pseudo-device loop # network loopback +pseudo-device bpfilter # packet filter +pseudo-device sl # CSLIP +pseudo-device ppp # PPP +pseudo-device tun # network tunneling over tty +#pseudo-device gre # generic L3 over IP tunnel +#pseudo-device ipfilter # ip filter +#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 strip # STarmode Radio IP (Metricon Ricochet) + +#pseudo-device vlan # IEEE 802.1q encapsulation +pseudo-device pty # pseudo-terminals +pseudo-device vnd # disk-like interface to files +#pseudo-device ccd 2 # concatenated disk devices +#pseudo-device cgd 2 # cryptographic disk devices +#pseudo-device raid 4 # RAIDframe disk driver +#options RAID_AUTOCONFIG # auto-configuration of RAID components +#pseudo-device fss 4 # file system snapshot device + +pseudo-device biconsdev 1 # build-in console device +#pseudo-device wsmux + +pseudo-device md 1 # Ramdisk driver +pseudo-device rnd # /dev/random and in-kernel generator +pseudo-device clockctl # user control of clock subsystem +pseudo-device ksyms # /dev/ksyms +#pseudo-device bcsp # BlueCore Serial Protocol +#pseudo-device btuart # Bluetooth HCI UART (H4) + +# wscons pseudo-devices +pseudo-device wsmux # mouse & keyboard multiplexor +pseudo-device wsfont diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/arch/hpcarm/conf/files.hpcarm src/sys/arch/hpcarm/conf/files.hpcarm --- src.orig/sys/arch/hpcarm/conf/files.hpcarm 2008-04-29 11:38:35.000000000 +0900 +++ src/sys/arch/hpcarm/conf/files.hpcarm 2009-02-02 08:46:36.000000000 +0900 @@ -14,44 +14,19 @@ define todservice {} +defparam opt_dram_pages.h DRAM_PAGES + # Memory disk driver file dev/md_root.c memory_disk_hooks +file dev/cninit.c + # Generic MD files file arch/hpcarm/hpcarm/autoconf.c -#file arch/hpcarm/hpcarm/intr.c -file arch/hpcarm/hpcarm/spl.S -file arch/arm/arm32/intr.c -file arch/arm/arm32/spl.S # HPCARM specific files file arch/hpcarm/hpcarm/hpc_machdep.c -# Include hpcarm/StrongARM config definitions. -include "arch/arm/conf/files.sa11x0" - -# SA-11[01]1 companion chips -file arch/hpcarm/dev/sacc_hpcarm.c sacc - -# Jornada 720 dependent part of PCMCIA support. -file arch/hpcarm/dev/j720pcic.c sacpcic - -# XXX iPAQ Virtual bus -device ipaqbus {} -attach ipaqbus at saip -file arch/hpcarm/dev/ipaq_saip.c ipaqbus - -# iPAQ PCMCIA -device ipaqpcic: pcmciabus -attach ipaqpcic at ipaqbus -file arch/hpcarm/dev/ipaq_pcic.c ipaqpcic needs-flag - -# PCMCIA -include "dev/pcmcia/files.pcmcia" - -# XXX this is a hack to use dev/pcmcia without fdc.c -device fdc - # # H/PC Platform common files. # @@ -63,59 +38,8 @@ include "dev/hpc/files.hpckbd" include "dev/hpc/files.hpctp" -# iPAQ LCD -device ipaqlcd: hpcfbif -attach ipaqlcd at ipaqbus -file arch/hpcarm/dev/ipaq_lcd.c ipaqlcd - -# Epson SED1356 framebuffer -device sed: hpcfbif -attach sed at saip -file arch/hpcarm/dev/sed_saip.c sed - -# Jornada 720 SSP port -device j720ssp {} -attach j720ssp at saip -file arch/hpcarm/dev/j720ssp.c j720ssp - -# Jornada 720 keyboard -device j720kbd: hpckbdif -attach j720kbd at j720ssp -file arch/hpcarm/dev/j720kbd.c j720kbd - -# Jornada 720 touch-panel -device j720tp: hpctpanel, wsmousedev, wskbddev -attach j720tp at j720ssp -file arch/hpcarm/dev/j720tp.c j720tp -defflag opt_j720tp.h J720TP_DEBUG -defparam opt_j720tp.h J720TP_SETTINGS_ICON_KEYSYM - J720TP_BACKUP_ICON_KEYSYM - J720TP_DIALUP_ICON_KEYSYM - J720TP_MEDIA_ICON_KEYSYM - -# Jornada 720 LCD screen -device j720lcd -attach j720lcd at j720ssp -file arch/hpcarm/dev/j720lcd.c j720lcd - -# Jornada 720 power management -device j720pwr: hpcapmif -attach j720pwr at j720ssp -file arch/hpcarm/dev/j720pwr.c j720pwr - -# Atmel microcontroller -device atmelgpioif {} -device atmelgpio: atmelgpioif -attach atmelgpio at ipaqbus -file arch/hpcarm/dev/ipaq_atmelgpio.c atmelgpio - -# uda1341 Codec -device udaif {} -device uda: udaif -attach uda at ipaqbus -file arch/hpcarm/dev/uda1341.c uda - -file dev/cninit.c +# Machine-independent PCMCIA +include "dev/pcmcia/files.pcmcia" # Machine-independent ATA drivers include "dev/ata/files.ata" @@ -123,10 +47,13 @@ # Machine-independent SCSI/ATAPI drivers include "dev/scsipi/files.scsipi" -# USB +# Machine-independent USB include "dev/usb/files.usb" -# Bluetooth +# Machine-independent Bluetooth include "dev/bluetooth/files.bluetooth" +# Machine-independent SD/MMC +include "dev/sdmmc/files.sdmmc" + include "arch/hpcarm/conf/majors.hpcarm" diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/arch/hpcarm/conf/files.pxa2x0 src/sys/arch/hpcarm/conf/files.pxa2x0 --- src.orig/sys/arch/hpcarm/conf/files.pxa2x0 1970-01-01 09:00:00.000000000 +0900 +++ src/sys/arch/hpcarm/conf/files.pxa2x0 2009-04-20 06:59:27.000000000 +0900 @@ -0,0 +1,31 @@ +# $NetBSD$ +# +# PXA2x0 specific configuration info +# + +file arch/hpcarm/hpcarm/pxa2x0_hpc_machdep.c + +# Include hpcarm/XScale config definitions. +include "arch/arm/xscale/files.pxa2x0" + +# +# W-ZERO3 specific configuration info +# + +# LCD frame buffer +attach lcd at pxaip with wzero3lcd +file arch/hpcarm/dev/wzero3_lcd.c wzero3lcd needs-flag + +# keyboard +device wzero3kbd: hpckbdif, sysmon_power, sysmon_taskq +attach wzero3kbd at pxaip +file arch/hpcarm/dev/wzero3_kbd.c wzero3kbd + +# MMC/SD controller +attach pxamci at pxaip with wzero3mci +file arch/hpcarm/dev/wzero3_mci.c wzero3mci + +# USB power control +device wzero3usb +attach wzero3usb at pxaip +file arch/hpcarm/dev/wzero3_usb.c wzero3usb diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/arch/hpcarm/conf/files.sa11x0 src/sys/arch/hpcarm/conf/files.sa11x0 --- src.orig/sys/arch/hpcarm/conf/files.sa11x0 1970-01-01 09:00:00.000000000 +0900 +++ src/sys/arch/hpcarm/conf/files.sa11x0 2009-04-20 07:00:42.000000000 +0900 @@ -0,0 +1,90 @@ +# $NetBSD$ +# +# SA-11x0 model specific configuration info +# + +# SA-11x0 specific files. +#file arch/hpcarm/hpcarm/intr.c +file arch/hpcarm/hpcarm/sa11x0_hpc_machdep.c +file arch/hpcarm/hpcarm/spl.S +file arch/arm/arm32/intr.c +file arch/arm/arm32/spl.S + +# Include hpcarm/StrongARM config definitions. +include "arch/arm/conf/files.sa11x0" + +# SA-11[01]1 companion chips +file arch/hpcarm/dev/sacc_hpcarm.c sacc + +# +# iPaq specific configuration info +# + +# XXX iPAQ Virtual bus +device ipaqbus {} +attach ipaqbus at saip +file arch/hpcarm/dev/ipaq_saip.c ipaqbus + +# iPAQ PCMCIA +device ipaqpcic: pcmciabus +attach ipaqpcic at ipaqbus +file arch/hpcarm/dev/ipaq_pcic.c ipaqpcic needs-flag + +# iPAQ LCD +device ipaqlcd: hpcfbif +attach ipaqlcd at ipaqbus +file arch/hpcarm/dev/ipaq_lcd.c ipaqlcd + +# Atmel microcontroller +device atmelgpioif {} +device atmelgpio: atmelgpioif +attach atmelgpio at ipaqbus +file arch/hpcarm/dev/ipaq_atmelgpio.c atmelgpio + +# uda1341 Codec +device udaif {} +device uda: udaif +attach uda at ipaqbus +file arch/hpcarm/dev/uda1341.c uda + +# +# JORNADA specific configuration info +# + +# Jornada 720 dependent part of PCMCIA support. +file arch/hpcarm/dev/j720pcic.c sacpcic + +# Epson SED1356 framebuffer +device sed: hpcfbif +attach sed at saip +file arch/hpcarm/dev/sed_saip.c sed + +# Jornada 720 SSP port +device j720ssp {} +attach j720ssp at saip +file arch/hpcarm/dev/j720ssp.c j720ssp + +# Jornada 720 keyboard +device j720kbd: hpckbdif +attach j720kbd at j720ssp +file arch/hpcarm/dev/j720kbd.c j720kbd + +# Jornada 720 touch-panel +device j720tp: hpctpanel, wsmousedev, wskbddev +attach j720tp at j720ssp +file arch/hpcarm/dev/j720tp.c j720tp +defflag opt_j720tp.h J720TP_DEBUG +defparam opt_j720tp.h J720TP_SETTINGS_ICON_KEYSYM + J720TP_BACKUP_ICON_KEYSYM + J720TP_DIALUP_ICON_KEYSYM + J720TP_MEDIA_ICON_KEYSYM + +# Jornada 720 LCD screen +device j720lcd +attach j720lcd at j720ssp +file arch/hpcarm/dev/j720lcd.c j720lcd + +# Jornada 720 power management +device j720pwr: hpcapmif +attach j720pwr at j720ssp +file arch/hpcarm/dev/j720pwr.c j720pwr diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/arch/hpcarm/conf/std.pxa2x0 src/sys/arch/hpcarm/conf/std.pxa2x0 --- src.orig/sys/arch/hpcarm/conf/std.pxa2x0 1970-01-01 09:00:00.000000000 +0900 +++ src/sys/arch/hpcarm/conf/std.pxa2x0 2009-01-30 05:53:27.000000000 +0900 @@ -0,0 +1,12 @@ +# $NetBSD$ +# +# standard NetBSD/hpcarm options for PXA2x0 model + +include "arch/hpcarm/conf/std.hpcarm" # arch standard options + +# Pull in iPaq config definitions. +include "arch/hpcarm/conf/files.pxa2x0" + +options ARM_INTR_IMPL="" + +makeoptions TEXTADDR=0xc0200000 diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/arch/hpcarm/conf/std.sa11x0 src/sys/arch/hpcarm/conf/std.sa11x0 --- src.orig/sys/arch/hpcarm/conf/std.sa11x0 1970-01-01 09:00:00.000000000 +0900 +++ src/sys/arch/hpcarm/conf/std.sa11x0 2008-04-25 17:03:12.000000000 +0900 @@ -0,0 +1,10 @@ +# $NetBSD$ +# +# standard NetBSD/hpcarm options for SA-11x0 model + +include "arch/hpcarm/conf/std.hpcarm" # arch standard options + +# Pull in iPaq config definitions. +include "arch/hpcarm/conf/files.sa11x0" + +options __OLD_INTERRUPT_CODE diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/arch/hpcarm/dev/wzero3_kbd.c src/sys/arch/hpcarm/dev/wzero3_kbd.c --- src.orig/sys/arch/hpcarm/dev/wzero3_kbd.c 1970-01-01 09:00:00.000000000 +0900 +++ src/sys/arch/hpcarm/dev/wzero3_kbd.c 2009-04-20 18:15:12.000000000 +0900 @@ -0,0 +1,711 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 2008, 2009 NONAKA Kimihiro + * 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. + * + * 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. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#ifdef DEBUG +#define DPRINTF(arg) printf arg +#else +#define DPRINTF(arg) /* nothing */ +#endif + +#define CSR_READ1(r) bus_space_read_1(sc->sc_iot, sc->sc_ioh, (r)) +#define CSR_WRITE1(r,v) bus_space_write_1(sc->sc_iot, sc->sc_ioh, (r), (v)) + +/* register */ +#define KBDCOL_L (0x00) /* Write */ +#define KBDCOL_U (0x04) /* Write */ +#define KBDCHARGE (0x08) /* Write */ +#define KBDDATA (0x08) /* Read */ +#define REGMAPSIZE 0x0c + +#define KEYWAIT 20 /* us */ + +#define WS003SH_NCOLUMN 12 +#define WS003SH_NROW 7 + +struct wzero3kbd_softc { + device_t sc_dev; + + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + + int sc_ncolumn; + int sc_nrow; + uint8_t *sc_okeystat; + uint8_t *sc_keystat; + + void *sc_key_ih; + void *sc_power_ih; + void *sc_reset_ih; + + int sc_key_pin; + int sc_power_pin; + int sc_reset_pin; + + struct hpckbd_ic_if sc_if; + struct hpckbd_if *sc_hpckbd; + + struct sysmon_pswitch sc_smpsw; /* for reset key */ + + int sc_enabled; + + /* polling stuff */ + struct callout sc_keyscan_ch; + int sc_interval; + int sc_stable_count; +#define KEY_INTERVAL 50 /* ms */ +#define STABLE_COUNT 2 + +#if defined(KEYTEST) || defined(KEYTEST2) || defined(KEYTEST3) || defined(KEYTEST4) + void *sc_test_ih; + int sc_test_pin; + int sc_nouse_pin; + int sc_nouse_pin2; + int sc_nouse_pin3; +#endif +}; + +static int wzero3kbd_match(device_t, cfdata_t, void *); +static void wzero3kbd_attach(device_t, device_t, void *); + +CFATTACH_DECL_NEW(wzero3kbd, sizeof(struct wzero3kbd_softc), + wzero3kbd_match, wzero3kbd_attach, NULL, NULL); + +static int wzero3kbd_intr(void *arg); +#if defined(KEYTEST) +static int wzero3kbd_intr2(void *arg); +#endif +#if defined(KEYTEST3) +static int wzero3kbd_intr3(void *arg); +#endif +static void wzero3kbd_tick(void *arg); +static int wzero3kbd_power_intr(void *arg); +static int wzero3kbd_reset_intr(void *arg); +static int wzero3kbd_input_establish(void *arg, struct hpckbd_if *kbdif); +static void wzero3kbd_sysmon_reset_event(void *arg); +static int wzero3kbd_poll(void *arg); +static int wzero3kbd_poll1(void *arg); + +/* + * WS003SH keyscan map + col#0 col#1 col#2 col#3 col#4 col#5 col#6 col#7 col#8 col#9 col#10 col#11 +row#0: CTRL 1 3 5 6 7 9 0 BS (none) ROTATE CAMERA +row#1: (none) 2 4 r y 8 i o p (none) VOL- VOL+ +row#2: TAB q e t g u j k (none) (none) (none) (none) +row#3: (none) w s f v h m l (none) (none) SHIFT (none) +row#4: CALL a d c b n . (none) ENTER (none) WIN (none) +row#5: MAIL z x - SPACE / (none) UP (none) (none) LSOFT FN +row#6: IE MOJI (none) OK ACTION , LEFT DOWN RIGHT (none) RSOFT (none) +*/ + +/* + * WS011SH keyscan map + col#0 col#1 col#2 col#3 col#4 col#5 col#6 col#7 col#8 col#9 col#10 col#11 +row#0 Ctrl (none) (none) (none) (none) (none) (none) (none) Del (none) ROTATE (none) +row#1 (none) (none) (none) R Y (none) I O (none) (none) (none) (none) +row#2 Tab Q E T G U J K (none) (none) (none) (none) +row#3 (none) W S F V H M L (none) (none) Shift (none) +row#4 (none) A D C B N . (none) Enter (none) (none) (none) +row#5 (none) Z X - Space / (none) UP (none) (none) (none) (none) +row#6 (none) MOJI HAN/ZEN OK (none) , LEFT DOWN RIGHT (none) Fn (none) +*/ + +static const struct wzero3kbd_model { + platid_mask_t *platid; + int key_pin; + int power_pin; + int reset_pin; + int ncolumn; + int nrow; +} wzero3kbd_table[] = { + /* WS003SH */ + { + &platid_mask_MACH_SHARP_WZERO3_WS003SH, + -1, /* XXX */ + GPIO_WS003SH_POWER_BUTTON, + -1, /* None */ + WS003SH_NCOLUMN, + WS003SH_NROW, + }, + /* WS004SH */ + { + &platid_mask_MACH_SHARP_WZERO3_WS004SH, + -1, /* XXX */ + GPIO_WS003SH_POWER_BUTTON, + -1, /* None */ + WS003SH_NCOLUMN, + WS003SH_NROW, + }, + /* WS007SH */ + { + &platid_mask_MACH_SHARP_WZERO3_WS007SH, + -1, /* XXX */ + GPIO_WS007SH_POWER_BUTTON, + GPIO_WS007SH_RESET_BUTTON, + WS003SH_NCOLUMN, + WS003SH_NROW, + }, + /* WS011SH */ + { + &platid_mask_MACH_SHARP_WZERO3_WS011SH, + -1, /* XXX */ + GPIO_WS011SH_POWER_BUTTON, + GPIO_WS011SH_RESET_BUTTON, + WS003SH_NCOLUMN, + WS003SH_NROW, + }, + /* WS020SH */ + { + &platid_mask_MACH_SHARP_WZERO3_WS020SH, + -1, /* XXX */ + -1, /* XXX */ + -1, /* XXX */ + WS003SH_NCOLUMN, + WS003SH_NROW, + }, + + { NULL, -1, -1, -1, 0, 0, } +}; + +static const struct wzero3kbd_model * +wzero3kbd_lookup(void) +{ + const struct wzero3kbd_model *model; + + for (model = wzero3kbd_table; model->platid != NULL; model++) { + if (platid_match(&platid, model->platid)) { + return model; + } + } + return NULL; +} + +static int +wzero3kbd_match(struct device *parent, struct cfdata *cf, void *aux) +{ + + if (strcmp(cf->cf_name, "wzero3kbd") != 0) + return 0; + if (wzero3kbd_lookup() == NULL) + return 0; + return 1; +} + +static void +wzero3kbd_attach(struct device *parent, struct device *self, void *aux) +{ + struct wzero3kbd_softc *sc = device_private(self); + struct pxaip_attach_args *pxa = (struct pxaip_attach_args *)aux; + struct hpckbd_attach_args haa; + const struct wzero3kbd_model *model; + + sc->sc_dev = self; + + model = wzero3kbd_lookup(); + if (model == NULL) { + aprint_error(": unknown model\n"); + return; + } + + aprint_normal(": keyboard\n"); + aprint_naive("\n"); + + sc->sc_key_pin = model->key_pin; + sc->sc_power_pin = model->power_pin; + sc->sc_reset_pin = model->reset_pin; + sc->sc_ncolumn = model->ncolumn; + sc->sc_nrow = model->nrow; + + sc->sc_iot = pxa->pxa_iot; + if (bus_space_map(sc->sc_iot, PXA2X0_CS2_START, REGMAPSIZE, 0, + &sc->sc_ioh)) { + aprint_error_dev(self, "couldn't map registers.\n"); + return; + } + + sc->sc_okeystat = malloc(sc->sc_nrow * sc->sc_ncolumn, M_DEVBUF, + M_NOWAIT | M_ZERO); + sc->sc_keystat = malloc(sc->sc_nrow * sc->sc_ncolumn, M_DEVBUF, + M_NOWAIT | M_ZERO); + if (sc->sc_okeystat == NULL || sc->sc_keystat == NULL) { + aprint_error_dev(self, "couldn't alloc memory.\n"); + if (sc->sc_okeystat) + free(sc->sc_okeystat, M_DEVBUF); + if (sc->sc_keystat) + free(sc->sc_keystat, M_DEVBUF); + return; + } + + sc->sc_if.hii_ctx = sc; + sc->sc_if.hii_establish = wzero3kbd_input_establish; + sc->sc_if.hii_poll = wzero3kbd_poll; + + /* Attach console if not using serial. */ + if (!(bootinfo->bi_cnuse & BI_CNUSE_SERIAL)) + hpckbd_cnattach(&sc->sc_if); + + /* Install interrupt handler. */ + if (sc->sc_key_pin >= 0) { + sc->sc_stable_count = 1; + pxa2x0_gpio_set_function(sc->sc_key_pin, GPIO_IN); + sc->sc_key_ih = pxa2x0_gpio_intr_establish(sc->sc_key_pin, + IST_EDGE_BOTH, IPL_TTY, wzero3kbd_intr, sc); + if (sc->sc_key_ih == NULL) { + aprint_error_dev(sc->sc_dev, + "couldn't establish key interrupt\n"); + } + } else { + sc->sc_stable_count = STABLE_COUNT; + sc->sc_interval = KEY_INTERVAL / (1000 / hz); + if (sc->sc_interval < 1) + sc->sc_interval = 1; + callout_init(&sc->sc_keyscan_ch, 0); + callout_reset(&sc->sc_keyscan_ch, sc->sc_interval, + wzero3kbd_tick, sc); + } + + /* power key */ + if (sc->sc_power_pin >= 0) { + pxa2x0_gpio_set_function(sc->sc_power_pin, GPIO_IN); + sc->sc_power_ih = pxa2x0_gpio_intr_establish( + sc->sc_power_pin, IST_EDGE_BOTH, IPL_TTY, + wzero3kbd_power_intr, sc); + if (sc->sc_power_ih == NULL) { + aprint_error_dev(sc->sc_dev, + "couldn't establish power key interrupt\n"); + } + } + + /* reset button */ + if (sc->sc_reset_pin >= 0) { + pxa2x0_gpio_set_function(sc->sc_reset_pin, GPIO_IN); + sc->sc_reset_ih = pxa2x0_gpio_intr_establish( + sc->sc_reset_pin, IST_EDGE_BOTH, IPL_TTY, + wzero3kbd_reset_intr, sc); + if (sc->sc_reset_ih == NULL) { + aprint_error_dev(sc->sc_dev, + "couldn't establish reset key interrupt\n"); + } + + sc->sc_smpsw.smpsw_name = device_xname(self); + sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_RESET; + if (sysmon_pswitch_register(&sc->sc_smpsw) != 0) { + aprint_error_dev(sc->sc_dev, + "unable to register reset event handler\n"); + } + } + + /* Attach hpckbd. */ + haa.haa_ic = &sc->sc_if; + config_found(self, &haa, hpckbd_print); + +#if defined(KEYTEST) || defined(KEYTEST2) || defined(KEYTEST3) || defined(KEYTEST4) + sc->sc_test_ih = NULL; + sc->sc_test_pin = -1; + sc->sc_nouse_pin = -1; + sc->sc_nouse_pin2 = -1; + sc->sc_nouse_pin3 = -1; + if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS003SH) + || platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS004SH)) { + sc->sc_nouse_pin = GPIO_WS003SH_SD_DETECT; /* SD_DETECT */ + sc->sc_nouse_pin2 = 86; /* Vsync? */ + sc->sc_nouse_pin3 = 89; /* RESET? */ + } + if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS007SH)) { + sc->sc_nouse_pin = GPIO_WS007SH_SD_DETECT; /* SD_DETECT */ + sc->sc_nouse_pin2 = 77; /* Vsync? */ + } + if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS011SH)) { + sc->sc_nouse_pin = GPIO_WS011SH_SD_DETECT; /* SD_DETECT */ + sc->sc_nouse_pin2 = 77; /* Vsync? */ + } + +#ifdef KEYTEST + for (sc->sc_test_pin = 2; sc->sc_test_pin < PXA270_GPIO_NPINS; sc->sc_test_pin++) { + if (sc->sc_test_pin != sc->sc_nouse_pin + && sc->sc_test_pin != sc->sc_nouse_pin2 + && sc->sc_test_pin != sc->sc_nouse_pin3 + && sc->sc_test_pin != sc->sc_key_pin + && sc->sc_test_pin != sc->sc_power_pin + && sc->sc_test_pin != sc->sc_reset_pin + && GPIO_IS_GPIO_IN(pxa2x0_gpio_get_function(sc->sc_test_pin))) + break; + } + if (sc->sc_test_pin < PXA270_GPIO_NPINS) { + printf("GPIO_IN: GPIO pin #%d\n", sc->sc_test_pin); + sc->sc_test_ih = pxa2x0_gpio_intr_establish(sc->sc_test_pin, + IST_EDGE_BOTH, IPL_TTY, wzero3kbd_intr2, sc); + } else { + sc->sc_test_pin = -1; + } +#endif + +#ifdef KEYTEST3 + { + int i; + printf("pin: "); + for (i = 0; i < PXA270_GPIO_NPINS; i++) { + if (i == sc->sc_nouse_pin + || i == sc->sc_nouse_pin2 + || i == sc->sc_nouse_pin3 + || i == sc->sc_key_pin + || i == sc->sc_power_pin + || i == sc->sc_reset_pin) + continue; + + printf("%d, ", i); + if (GPIO_IS_GPIO_IN(pxa2x0_gpio_get_function(i))) { + pxa2x0_gpio_intr_establish(i, IST_EDGE_BOTH, + IPL_TTY, wzero3kbd_intr3, (void *)(long)i); + } + } + } +#endif + +#ifdef KEYTEST4 + for (sc->sc_test_pin = 2; sc->sc_test_pin < PXA270_GPIO_NPINS; sc->sc_test_pin++) { + if (sc->sc_test_pin != sc->sc_nouse_pin + && sc->sc_test_pin != sc->sc_nouse_pin2 + && sc->sc_test_pin != sc->sc_nouse_pin3 + && sc->sc_test_pin != sc->sc_key_pin + && sc->sc_test_pin != sc->sc_power_pin + && sc->sc_test_pin != sc->sc_reset_pin + && GPIO_IS_GPIO_OUT(pxa2x0_gpio_get_function(sc->sc_test_pin))) + break; + } + if (sc->sc_test_pin < PXA270_GPIO_NPINS) { + printf("GPIO_OUT: GPIO pin #%d\n", sc->sc_test_pin); + } else { + sc->sc_test_pin = -1; + } +#endif +#endif +} + +static int +wzero3kbd_intr(void *arg) +{ + struct wzero3kbd_softc *sc = (struct wzero3kbd_softc *)arg; + +#if defined(KEYTEST) || defined(KEYTEST2) || defined(KEYTEST3) || defined(KEYTEST4) + printf("wzero3kbd_intr: GPIO pin #%d = %s\n", sc->sc_key_pin, + pxa2x0_gpio_get_bit(sc->sc_key_pin) ? "on" : "off"); +#endif + +#if defined(KEYTEST4) + if (sc->sc_test_pin >= 0) { + if (pxa2x0_gpio_get_bit(sc->sc_test_pin)) { + printf("GPIO_OUT: GPIO pin #%d: L\n",sc->sc_test_pin); + pxa2x0_gpio_clear_bit(sc->sc_test_pin); + } else { + printf("GPIO_OUT: GPIO pin #%d: H\n", sc->sc_test_pin); + pxa2x0_gpio_set_bit(sc->sc_test_pin); + } + } +#endif + + (void) wzero3kbd_poll1(sc); + + pxa2x0_gpio_clear_intr(sc->sc_key_pin); + + return 1; +} + +#if defined(KEYTEST) +static int +wzero3kbd_intr2(void *arg) +{ + struct wzero3kbd_softc *sc = (struct wzero3kbd_softc *)arg; + + printf("wzero3kbd_intr2: GPIO_IN: GPIO pin #%d = %s\n", sc->sc_test_pin, + pxa2x0_gpio_get_bit(sc->sc_test_pin) ? "on" : "off"); + + return 1; +} +#endif + +#if defined(KEYTEST3) +static int +wzero3kbd_intr3(void *arg) +{ + int pin = (int)arg; + + printf("wzero3kbd_intr3: GPIO pin #%d = %s\n", pin, + pxa2x0_gpio_get_bit(pin) ? "on" : "off"); + + return 1; +} +#endif + + +static void +wzero3kbd_tick(void *arg) +{ + struct wzero3kbd_softc *sc = (struct wzero3kbd_softc *)arg; + + (void) wzero3kbd_poll1(sc); + + callout_reset(&sc->sc_keyscan_ch, sc->sc_interval, wzero3kbd_tick, sc); +} + +static int +wzero3kbd_power_intr(void *arg) +{ + struct wzero3kbd_softc *sc = (struct wzero3kbd_softc *)arg; + +#if defined(KEYTEST) || defined(KEYTEST2) || defined(KEYTEST3) || defined(KEYTEST4) + printf("wzero3kbd_power_intr: status = %s\n", + pxa2x0_gpio_get_bit(sc->sc_power_pin) ? "on" : "off"); +#endif + +#if defined(KEYTEST) + if (pxa2x0_gpio_get_bit(sc->sc_power_pin)) { + if (sc->sc_test_pin >= 0) { + int orig_pin = sc->sc_test_pin; + pxa2x0_gpio_intr_disestablish(sc->sc_test_ih); + sc->sc_test_ih = NULL; + + for (;;) { + if (++sc->sc_test_pin >= PXA270_GPIO_NPINS) + sc->sc_test_pin = 2; + if (sc->sc_test_pin == orig_pin) + break; + if (sc->sc_test_pin != sc->sc_nouse_pin + && sc->sc_test_pin != sc->sc_nouse_pin2 + && sc->sc_test_pin != sc->sc_nouse_pin3 + && sc->sc_test_pin != sc->sc_key_pin + && sc->sc_test_pin != sc->sc_power_pin + && sc->sc_test_pin != sc->sc_reset_pin + && GPIO_IS_GPIO_IN(pxa2x0_gpio_get_function(sc->sc_test_pin))) + break; + } + if (sc->sc_test_pin != orig_pin) { + printf("GPIO_IN: GPIO pin #%d\n", + sc->sc_test_pin); + sc->sc_test_ih = + pxa2x0_gpio_intr_establish(sc->sc_test_pin, + IST_EDGE_BOTH, IPL_TTY, wzero3kbd_intr2,sc); + } else { + sc->sc_test_pin = -1; + } + } + } +#endif + +#if defined(KEYTEST2) + if (pxa2x0_gpio_get_bit(sc->sc_power_pin)) { + sc->sc_enabled ^= 2; + if (sc->sc_enabled & 2) { + printf("print col/row\n"); + } else { + printf("keyscan\n"); + } + } +#endif +#if defined(KEYTEST4) + if (pxa2x0_gpio_get_bit(sc->sc_power_pin)) { + if (sc->sc_test_pin >= 0) { + int orig_pin = sc->sc_test_pin; + for (;;) { + if (++sc->sc_test_pin >= PXA270_GPIO_NPINS) + sc->sc_test_pin = 2; + if (sc->sc_test_pin == orig_pin) + break; + if (sc->sc_test_pin != sc->sc_nouse_pin + && sc->sc_test_pin != sc->sc_nouse_pin2 + && sc->sc_test_pin != sc->sc_nouse_pin3 + && sc->sc_test_pin != sc->sc_key_pin + && sc->sc_test_pin != sc->sc_power_pin + && sc->sc_test_pin != sc->sc_reset_pin + && GPIO_IS_GPIO_OUT(pxa2x0_gpio_get_function(sc->sc_test_pin))) + break; + } + if (sc->sc_test_pin != orig_pin) { + printf("GPIO_OUT: GPIO pin #%d\n", sc->sc_test_pin); + } else { + sc->sc_test_pin = -1; + } + } + } +#endif + + pxa2x0_gpio_clear_intr(sc->sc_power_pin); + + return 1; +} + +static int +wzero3kbd_reset_intr(void *arg) +{ + struct wzero3kbd_softc *sc = (struct wzero3kbd_softc *)arg; + + sysmon_task_queue_sched(0, wzero3kbd_sysmon_reset_event, sc); + + pxa2x0_gpio_clear_intr(sc->sc_reset_pin); + + return 1; +} + +static int +wzero3kbd_input_establish(void *arg, struct hpckbd_if *kbdif) +{ + struct wzero3kbd_softc *sc = (struct wzero3kbd_softc *)arg; + + /* Save hpckbd interface. */ + sc->sc_hpckbd = kbdif; + sc->sc_enabled = 1; + + return 0; +} + +static void +wzero3kbd_sysmon_reset_event(void *arg) +{ + struct wzero3kbd_softc *sc = (struct wzero3kbd_softc *)arg; + + sysmon_pswitch_event(&sc->sc_smpsw, PSWITCH_EVENT_PRESSED); +} + +static int +wzero3kbd_poll(void *arg) +{ + int keydown; + + keydown = wzero3kbd_poll1(arg); + + return keydown; +} + +static int +wzero3kbd_poll1(void *arg) +{ + struct wzero3kbd_softc *sc = (struct wzero3kbd_softc *)arg; + int row, col, data; + int keydown; + int i; + int s; + + if (!sc->sc_enabled) { + DPRINTF(("wzero3kbd_poll: disabled\n")); + return 0; + } + + s = spltty(); + + for (col = 0; col < sc->sc_ncolumn; col++) { + /* deselect column# and charge */ + CSR_WRITE1(KBDCOL_L, 0); + CSR_WRITE1(KBDCOL_U, 0); + CSR_WRITE1(KBDCHARGE, 1); + delay(KEYWAIT); + CSR_WRITE1(KBDCHARGE, 0); + + /* select scan column# */ + if (col < 8) { + CSR_WRITE1(KBDCOL_L, 1U << col); + CSR_WRITE1(KBDCOL_U, 0); + } else { + CSR_WRITE1(KBDCOL_L, 0); + CSR_WRITE1(KBDCOL_U, 1U << (col - 8)); + } + delay(KEYWAIT); + CSR_WRITE1(KBDCHARGE, 0); + + /* read key data */ + data = CSR_READ1(KBDDATA); + for (row = 0; row < sc->sc_nrow; row++) { +#ifdef KEYTEST2 + if (!(sc->sc_enabled & 2)) { +#endif + sc->sc_keystat[row + col * sc->sc_nrow] = + (data >> row) & 1; +#ifdef KEYTEST2 + } else if (data & (1 << row)) { + printf("col = %d, row = %d, idx = %d, data = 0x%02x\n", col, row, row + col * sc->sc_nrow, data); + } +#endif + } + } + + /* deselect column# and charge */ + CSR_WRITE1(KBDCOL_L, 0); + CSR_WRITE1(KBDCOL_U, 0); + CSR_WRITE1(KBDCHARGE, 1); + delay(KEYWAIT); + CSR_WRITE1(KBDCHARGE, 0); + + /* send key scan code */ + keydown = 0; + for (i = 0; i < sc->sc_nrow * sc->sc_ncolumn; i++) { + uint8_t keystat = sc->sc_keystat[i]; + keydown |= keystat; + if (keystat == 0) { + if (sc->sc_okeystat[i] != 0) { + /* key release */ + hpckbd_input(sc->sc_hpckbd, 0, i); + sc->sc_okeystat[i] = 0; + } + } else { + if (++sc->sc_okeystat[i] >= sc->sc_stable_count) { + /* key press */ + hpckbd_input(sc->sc_hpckbd, 1, i); + sc->sc_okeystat[i] = sc->sc_stable_count; + } + } + } + + splx(s); + + return keydown; +} diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/arch/hpcarm/dev/wzero3_lcd.c src/sys/arch/hpcarm/dev/wzero3_lcd.c --- src.orig/sys/arch/hpcarm/dev/wzero3_lcd.c 1970-01-01 09:00:00.000000000 +0900 +++ src/sys/arch/hpcarm/dev/wzero3_lcd.c 2009-02-01 21:04:29.000000000 +0900 @@ -0,0 +1,476 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 2008,2009 NONAKA Kimihiro + * 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. + * + * 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. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD$"); + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#ifdef DEBUG +#define DPRINTF(arg) printf arg +#else +#define DPRINTF(arg) /* nothing */ +#endif + +/* + * wsdisplay glue + */ +static struct pxa2x0_wsscreen_descr wzero3lcd_std_screen = { + .c = { + .name = "std", + .textops = &pxa2x0_lcd_emulops, + .fontwidth = 8, + .fontheight = 16, + .capabilities = WSSCREEN_WSCOLORS, + }, + .depth = 16, /* bits per pixel */ + .flags = 0, +}; + +static const struct wsscreen_descr *wzero3lcd_scr_descr[] = { + &wzero3lcd_std_screen.c +}; + +static const struct wsscreen_list wzero3lcd_screen_list = { + .nscreens = __arraycount(wzero3lcd_scr_descr), + .screens = wzero3lcd_scr_descr, +}; + +static int wzero3lcd_ioctl(void *, void *, u_long, void *, int, struct lwp *); +static int wzero3lcd_param(struct pxa2x0_lcd_softc *, u_long, struct wsdisplay_param *); +static int wzero3lcd_show_screen(void *, void *, int, void (*)(void *, int, int), void *); + +static struct wsdisplay_accessops wzero3lcd_accessops = { + wzero3lcd_ioctl, + pxa2x0_lcd_mmap, + pxa2x0_lcd_alloc_screen, + pxa2x0_lcd_free_screen, + wzero3lcd_show_screen, + NULL, + NULL, + NULL, +}; + +/* WS003SH or WS004SH */ +static const struct lcd_panel_geometry sharp_ws003sh = { + 480, /* Width */ + 640, /* Height */ + 0, /* No extra lines */ + + LCDPANEL_ACTIVE | LCDPANEL_VSP | LCDPANEL_HSP, + 1, /* clock divider */ + 0, /* AC bias pin freq */ + + 0x14, /* horizontal sync pulse width */ + 0x4e, /* BLW */ + 0x46, /* ELW */ + + 0, /* vertical sync pulse width */ + 2, /* BFW */ + 5, /* EFW */ + + 0, /* PCDDIV */ +}; + +/* WS007SH */ +static const struct lcd_panel_geometry sharp_ws007sh = { + 480, /* Width */ + 640, /* Height */ + 0, /* No extra lines */ + + LCDPANEL_ACTIVE | LCDPANEL_VSP | LCDPANEL_HSP | LCDPANEL_PCP | LCDPANEL_OEP, + 3, /* clock divider */ + 0, /* AC bias pin freq */ + + 0x27, /* horizontal sync pulse width */ + 0x68, /* BLW */ + 0x5b, /* ELW */ + + 0, /* vertical sync pulse width */ + 2, /* BFW */ + 5, /* EFW */ + + 1, /* PCDDIV */ +}; + +/* WS011SH */ +static const struct lcd_panel_geometry sharp_ws011sh = { + 480, /* Width */ + 800, /* Height */ + 0, /* No extra lines */ + + LCDPANEL_ACTIVE | LCDPANEL_VSP | LCDPANEL_HSP | LCDPANEL_PCP, + 1, /* clock divider */ + 0, /* AC bias pin freq */ + + 0x0a, /* horizontal sync pulse width */ + 0x0c, /* BLW */ + 0x5e, /* ELW */ + + 0, /* vertical sync pulse width */ + 2, /* BFW */ + 1, /* EFW */ + + 0, /* PCDDIV */ +}; + +/* WS020SH */ +static const struct lcd_panel_geometry sharp_ws020sh = { + 480, /* Width */ + 800, /* Height */ + 0, /* No extra lines */ + + LCDPANEL_ACTIVE | LCDPANEL_VSP | LCDPANEL_HSP | LCDPANEL_PCP, + 1, /* clock divider */ + 0, /* AC bias pin freq */ + + 0x0a, /* horizontal sync pulse width */ + 0x0c, /* BLW */ + 0x5e, /* ELW */ + + 0, /* vertical sync pulse width */ + 2, /* BFW */ + 1, /* EFW */ + + 0, /* PCDDIV */ +}; + +static int wzero3lcd_match(struct device *, struct cfdata *, void *); +static void wzero3lcd_attach(struct device *, struct device *, void *); + +CFATTACH_DECL_NEW(wzero3lcd, sizeof(struct pxa2x0_lcd_softc), + wzero3lcd_match, wzero3lcd_attach, NULL, NULL); + +static const struct lcd_panel_geometry *wzero3lcd_lookup(void); +void wzero3lcd_cnattach(void); +static bool wzero3lcd_suspend(device_t dv PMF_FN_ARGS); +static bool wzero3lcd_resume(device_t dv PMF_FN_ARGS); + +int screen_rotate = 270; + +static const struct lcd_panel_geometry * +wzero3lcd_lookup(void) +{ + + if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS003SH) + || platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS004SH)) + return &sharp_ws003sh; + if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS007SH)) + return &sharp_ws007sh; + if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS011SH)) + return &sharp_ws011sh; + if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS020SH)) + return &sharp_ws020sh; + return NULL; +} + +static int +wzero3lcd_match(struct device *parent, struct cfdata *cf, void *aux) +{ + + if (strcmp(cf->cf_name, "lcd") != 0) + return 0; + if (wzero3lcd_lookup() == NULL) + return 0; + return 1; +} + +static void +wzero3lcd_attach(struct device *parent, struct device *self, void *aux) +{ + struct pxa2x0_lcd_softc *sc = device_private(self); + struct wsemuldisplaydev_attach_args aa; + const struct lcd_panel_geometry *panel; + + sc->dev = self; + + panel = wzero3lcd_lookup(); + if (panel == NULL) { + aprint_error(": unknown model\n"); + return; + } + + if ((platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS007SH)) + || (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS011SH)) + || (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS020SH))) + sc->flags |= FLAG_NOUSE_ACBIAS; + + switch (screen_rotate) { + default: + case 0: + wzero3lcd_std_screen.flags &= ~(RI_ROTATE_CW|RI_ROTATE_CCW); + break; + + case 90: /* quarter clockwise rotation */ + wzero3lcd_std_screen.flags |= RI_ROTATE_CW; + wzero3lcd_std_screen.flags &= ~RI_ROTATE_CCW; + break; + + case 270: /* quarter counter clockwise rotation */ + wzero3lcd_std_screen.flags |= RI_ROTATE_CCW; + wzero3lcd_std_screen.flags &= ~RI_ROTATE_CW; + break; + } + pxa2x0_lcd_attach_sub(sc, aux, panel); + + aa.console = (bootinfo->bi_cnuse != BI_CNUSE_SERIAL); + aa.scrdata = &wzero3lcd_screen_list; + aa.accessops = &wzero3lcd_accessops; + aa.accesscookie = sc; + + (void) config_found(self, &aa, wsemuldisplaydevprint); + + if (!pmf_device_register(sc->dev, wzero3lcd_suspend, wzero3lcd_resume)) + aprint_error_dev(sc->dev, "couldn't establish power handler\n"); +} + +void +wzero3lcd_cnattach(void) +{ + const struct lcd_panel_geometry *panel; + + panel = wzero3lcd_lookup(); + if (panel == NULL) + return; + + pxa2x0_lcd_cnattach(&wzero3lcd_std_screen, panel); +} + +/* + * Power management + */ +static bool +wzero3lcd_suspend(device_t dv PMF_FN_ARGS) +{ + struct pxa2x0_lcd_softc *sc = device_private(dv); + + pxa2x0_lcd_suspend(sc); + + return true; +} + +static bool +wzero3lcd_resume(device_t dv PMF_FN_ARGS) +{ + struct pxa2x0_lcd_softc *sc = device_private(dv); + + pxa2x0_lcd_resume(sc); + + return true; +} + +/* + * wsdisplay accessops overrides + */ +static int +wzero3lcd_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l) +{ + struct pxa2x0_lcd_softc *sc = (struct pxa2x0_lcd_softc *)v; + struct hpcfb_fbconf *fbconf; + struct hpcfb_dspconf *dspconf; + int res = EINVAL; + + switch (cmd) { + case WSDISPLAYIO_GETPARAM: + case WSDISPLAYIO_SETPARAM: + res = wzero3lcd_param(sc, cmd, (struct wsdisplay_param *)data); + break; + + case HPCFBIO_GCONF: + fbconf = (struct hpcfb_fbconf *)data; + if (fbconf->hf_conf_index != 0 && + fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) { + break; + } + + fbconf->hf_conf_index = 0; + fbconf->hf_nconfs = 1; + fbconf->hf_class = HPCFB_CLASS_RGBCOLOR; + strlcpy(fbconf->hf_name, "Sharp W-ZERO3 frame buffer", + sizeof(fbconf->hf_name)); + strlcpy(fbconf->hf_conf_name, "default", + sizeof(fbconf->hf_conf_name)); + fbconf->hf_width = sc->geometry->panel_width; + fbconf->hf_height = sc->geometry->panel_height; + fbconf->hf_baseaddr = (u_long)sc->active->buf_va; + fbconf->hf_offset = 0; + fbconf->hf_bytes_per_line = sc->geometry->panel_width * + sc->active->depth / 8; + fbconf->hf_nplanes = 1; + fbconf->hf_bytes_per_plane = sc->geometry->panel_width * + sc->geometry->panel_height * sc->active->depth / 8; + fbconf->hf_pack_width = sc->active->depth; + fbconf->hf_pixels_per_pack = 1; + fbconf->hf_pixel_width = sc->active->depth; + fbconf->hf_access_flags = (0 + | HPCFB_ACCESS_BYTE + | HPCFB_ACCESS_WORD + | HPCFB_ACCESS_DWORD); + fbconf->hf_order_flags = 0; + fbconf->hf_reg_offset = 0; + + fbconf->hf_class_data_length = sizeof(struct hf_rgb_tag); + fbconf->hf_u.hf_rgb.hf_flags = 0; + fbconf->hf_u.hf_rgb.hf_red_width = 5; + fbconf->hf_u.hf_rgb.hf_red_shift = 11; + fbconf->hf_u.hf_rgb.hf_green_width = 6; + fbconf->hf_u.hf_rgb.hf_green_shift = 5; + fbconf->hf_u.hf_rgb.hf_blue_width = 5; + fbconf->hf_u.hf_rgb.hf_blue_shift = 0; + fbconf->hf_u.hf_rgb.hf_alpha_width = 0; + fbconf->hf_u.hf_rgb.hf_alpha_shift = 0; + + fbconf->hf_ext_size = 0; + fbconf->hf_ext_data = NULL; + + res = 0; + break; + + case HPCFBIO_SCONF: + fbconf = (struct hpcfb_fbconf *)data; + if (fbconf->hf_conf_index != 0 && + fbconf->hf_conf_index != HPCFB_CURRENT_CONFIG) { + break; + } + /* nothing to do because we have only one configuration */ + res = 0; + break; + + case HPCFBIO_GDSPCONF: + dspconf = (struct hpcfb_dspconf *)data; + if ((dspconf->hd_unit_index != 0 && + dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) || + (dspconf->hd_conf_index != 0 && + dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) { + break; + } + + dspconf->hd_unit_index = 0; + dspconf->hd_nunits = 1; + dspconf->hd_class = HPCFB_DSP_CLASS_COLORLCD; + strlcpy(dspconf->hd_name, "PXA2x0 Internal LCD controller", + sizeof(dspconf->hd_name)); + dspconf->hd_op_flags = 0; + dspconf->hd_conf_index = 0; + dspconf->hd_nconfs = 1; + strlcpy(dspconf->hd_conf_name, "default", + sizeof(dspconf->hd_conf_name)); + dspconf->hd_width = sc->geometry->panel_width; + dspconf->hd_height = sc->geometry->panel_height; + dspconf->hd_xdpi = HPCFB_DSP_DPI_UNKNOWN; + dspconf->hd_ydpi = HPCFB_DSP_DPI_UNKNOWN; + + res = 0; + break; + + case HPCFBIO_SDSPCONF: + dspconf = (struct hpcfb_dspconf *)data; + if ((dspconf->hd_unit_index != 0 && + dspconf->hd_unit_index != HPCFB_CURRENT_UNIT) || + (dspconf->hd_conf_index != 0 && + dspconf->hd_conf_index != HPCFB_CURRENT_CONFIG)) { + break; + } + /* + * nothing to do + * because we have only one unit and one configuration + */ + res = 0; + break; + + case HPCFBIO_GOP: + case HPCFBIO_SOP: + /* curently not implemented... */ + break; + } + + if (res == EINVAL) + res = pxa2x0_lcd_ioctl(v, vs, cmd, data, flag, l); + return res; +} + +static int +wzero3lcd_show_screen(void *v, void *cookie, int waitok, void (*cb_func)(void *, int, int), void *cb_arg) +{ + int error; + + error = pxa2x0_lcd_show_screen(v, cookie, waitok, cb_func, cb_arg); + if (error) + return (error); + + return 0; +} + +/* + * wsdisplay I/O controls + */ +static int +wzero3lcd_param(struct pxa2x0_lcd_softc *sc, u_long cmd, struct wsdisplay_param *dp) +{ + int res = EINVAL; + + switch (dp->param) { + case WSDISPLAYIO_PARAM_BACKLIGHT: + /* unsupported */ + DPRINTF(("%s: ioctl(WSDISPLAYIO_PARAM_BACKLIGHT) isn't supported\n", device_xname(&sc->dev))); + res = ENOTTY; + break; + + case WSDISPLAYIO_PARAM_CONTRAST: + DPRINTF(("%s: ioctl(WSDISPLAYIO_PARAM_CONTRAST) isn't supported\n", device_xname(&sc->dev))); + /* unsupported */ + res = ENOTTY; + break; + + case WSDISPLAYIO_PARAM_BRIGHTNESS: + DPRINTF(("%s: ioctl(WSDISPLAYIO_PARAM_BRIGHTNESS) isn't supported\n", device_xname(&sc->dev))); + /* unsupported */ + res = ENOTTY; + } + + return res; +} diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/arch/hpcarm/dev/wzero3_mci.c src/sys/arch/hpcarm/dev/wzero3_mci.c --- src.orig/sys/arch/hpcarm/dev/wzero3_mci.c 1970-01-01 09:00:00.000000000 +0900 +++ src/sys/arch/hpcarm/dev/wzero3_mci.c 2009-02-02 12:12:30.000000000 +0900 @@ -0,0 +1,264 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2009 NONAKA Kimihiro + * 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. + * + * 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. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD$"); + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#if defined(PXAMCI_DEBUG) +#define DPRINTF(s) do { printf s; } while (0) +#else +#define DPRINTF(s) do {} while (0) +#endif + +struct wzero3mci_softc { + struct pxamci_softc sc; + + void *sc_detect_ih; + int sc_detect_pin; + int sc_power_pin; +}; + +static int pxamci_match(device_t, cfdata_t, void *); +static void pxamci_attach(device_t, device_t, void *); + +CFATTACH_DECL_NEW(wzero3mci, sizeof(struct wzero3mci_softc), + pxamci_match, pxamci_attach, NULL, NULL); + +static int wzero3mci_intr(void *arg); + +static uint32_t wzero3mci_get_ocr(void *); +static int wzero3mci_set_power(void *, uint32_t); +static int wzero3mci_card_detect(void *); +static int wzero3mci_write_protect(void *); + +struct wzero3mci_model { + platid_mask_t *platid; + int detect_pin; /* card detect pin# */ + int power_pin; /* card power pin # */ +} wzero3mci_table[] = { + /* WS003SH */ + { + &platid_mask_MACH_SHARP_WZERO3_WS003SH, + GPIO_WS003SH_SD_DETECT, + GPIO_WS003SH_SD_POWER, + }, + /* WS004SH */ + { + &platid_mask_MACH_SHARP_WZERO3_WS004SH, + GPIO_WS003SH_SD_DETECT, + GPIO_WS003SH_SD_POWER, + }, + /* WS007SH */ + { + &platid_mask_MACH_SHARP_WZERO3_WS007SH, + GPIO_WS007SH_SD_DETECT, + GPIO_WS007SH_SD_POWER, + }, + /* WS011SH */ + { + &platid_mask_MACH_SHARP_WZERO3_WS011SH, + GPIO_WS011SH_SD_DETECT, + GPIO_WS011SH_SD_POWER, + }, + /* WS0020H */ + { + &platid_mask_MACH_SHARP_WZERO3_WS020SH, + -1, + -1 + }, + + { + NULL, -1, -1 + }, +}; + + +static const struct wzero3mci_model * +wzero3mci_lookup(void) +{ + const struct wzero3mci_model *model; + + for (model = wzero3mci_table; model->platid != NULL; model++) { + if (platid_match(&platid, model->platid)) { + return model; + } + } + return NULL; +} + +static int +pxamci_match(device_t parent, cfdata_t cf, void *aux) +{ + + if (strcmp(cf->cf_name, "pxamci") != 0) + return 0; + if (wzero3mci_lookup() == NULL) + return 0; + return 1; +} + +static void +pxamci_attach(device_t parent, device_t self, void *aux) +{ + struct wzero3mci_softc *sc = device_private(self); + struct pxaip_attach_args *pxa = aux; + const struct wzero3mci_model *model; + + sc->sc.sc_dev = self; + + model = wzero3mci_lookup(); + if (model == NULL) { + aprint_error(": Unknown model."); + return; + } + + sc->sc_detect_pin = model->detect_pin; + sc->sc_power_pin = model->power_pin; + + /* Establish SD detect interrupt */ + if (sc->sc_detect_pin >= 0) { + pxa2x0_gpio_set_function(sc->sc_detect_pin, GPIO_IN); + sc->sc_detect_ih = pxa2x0_gpio_intr_establish(sc->sc_detect_pin, + IST_EDGE_BOTH, IPL_BIO, wzero3mci_intr, sc); + if (sc->sc_detect_ih == NULL) { + aprint_error_dev(self, + "unable to establish card detect interrupt\n"); + return; + } + } + + sc->sc.sc_tag.cookie = sc; + sc->sc.sc_tag.get_ocr = wzero3mci_get_ocr; + sc->sc.sc_tag.set_power = wzero3mci_set_power; + sc->sc.sc_tag.card_detect = wzero3mci_card_detect; + sc->sc.sc_tag.write_protect = wzero3mci_write_protect; + sc->sc.sc_caps = 0; + + if (pxamci_attach_sub(self, pxa)) { + aprint_error_dev(self, "unable to attach MMC controller\n"); + goto free_intr; + } + + if (!pmf_device_register(self, NULL, NULL)) { + aprint_error_dev(self, "couldn't establish power handler\n"); + } + + return; + +free_intr: + pxa2x0_gpio_intr_disestablish(sc->sc_detect_ih); + sc->sc_detect_ih = NULL; +} + +static int +wzero3mci_intr(void *arg) +{ + struct wzero3mci_softc *sc = (struct wzero3mci_softc *)arg; + + pxa2x0_gpio_clear_intr(sc->sc_detect_pin); + + pxamci_card_detect_event(&sc->sc); + + return 1; +} + +/*ARGSUSED*/ +static uint32_t +wzero3mci_get_ocr(void *arg) +{ + + return MMC_OCR_3_2V_3_3V|MMC_OCR_3_3V_3_4V; +} + +static int +wzero3mci_set_power(void *arg, uint32_t ocr) +{ + struct wzero3mci_softc *sc = (struct wzero3mci_softc *)arg; + int error = 0; + + if (sc->sc_power_pin >= 0) { + if (ISSET(ocr, MMC_OCR_3_2V_3_3V|MMC_OCR_3_3V_3_4V)) { + /* power on */ + pxa2x0_gpio_set_bit(sc->sc_power_pin); + } else if (ocr == 0) { + /* power off */ + pxa2x0_gpio_clear_bit(sc->sc_power_pin); + } else { + aprint_error_dev(sc->sc.sc_dev, + "unsupported OCR (%#x)\n", ocr); + error = EINVAL; + } + } + return error; +} + +/* + * Return non-zero if the card is currently inserted. + */ +static int +wzero3mci_card_detect(void *arg) +{ + struct wzero3mci_softc *sc = (struct wzero3mci_softc *)arg; + + if (sc->sc_detect_pin >= 0) { + if (pxa2x0_gpio_get_bit(sc->sc_detect_pin)) + return 0; + } + return 1; +} + +/* + * Return non-zero if the card is currently write-protected. + */ +/*ARGSUSED*/ +static int +wzero3mci_write_protect(void *arg) +{ + + return 0; +} diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/arch/hpcarm/dev/wzero3_reg.h src/sys/arch/hpcarm/dev/wzero3_reg.h --- src.orig/sys/arch/hpcarm/dev/wzero3_reg.h 1970-01-01 09:00:00.000000000 +0900 +++ src/sys/arch/hpcarm/dev/wzero3_reg.h 2009-02-02 13:27:57.000000000 +0900 @@ -0,0 +1,96 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 2008, 2009 NONAKA Kimihiro + * 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. + * + * 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. + */ + +#ifndef _HPCARM_DEV_WZERO3_REG_H_ +#define _HPCARM_DEV_WZERO3_REG_H_ + +/* GPIO --------------------------------------------------------------------- */ + +/* + * WS003SH/WS004SH specific parameter + */ +#define GPIO_WS003SH_SD_DETECT 9 /* In */ +#define GPIO_WS003SH_SLIDE 12 /* In */ +#define GPIO_WS003SH_FULLKEY_LED 17 /* Out: H:ON, L*OFF */ +#define GPIO_WS003SH_ANTENNA_LED 37 /* Out: H:ON, L:OFF */ +// DONT_TOUCH(RESET?) 89 /* Out */ +#define GPIO_WS003SH_POWER_BUTTON 95 /* In */ +#define GPIO_WS003SH_VIB 97 /* Out */ +#define GPIO_WS003SH_USB_CLIENT_DETECT 103 /* In */ +#define GPIO_WS003SH_SD_POWER 107 /* Out: H:ON, L:OFF */ +#define GPIO_WS003SH_LCD_POWER 114 /* Out: H:ON, L:OFF XXX */ +#define GPIO_WS003SH_AC_DETECT 115 /* In */ + +/* + * WS007SH specific parameter + */ +#define GPIO_WS007SH_RESET_BUTTON 1 /* In: L: press, H: release */ +#define GPIO_WS007SH_POWER_BUTTON 9 /* In */ +#define GPIO_WS007SH_TOUCH_PANEL 21 /* In */ +#define GPIO_WS007SH_USB_CLIENT_DETECT 35 /* In */ +#define GPIO_WS007SH_USB_HOST_POWER 37 /* Out */ +#define GPIO_WS007SH_USB_HOST_DETECT 41 /* In */ +#define GPIO_WS007SH_SD_DETECT 48 /* In */ +#define GPIO_WS007SH_SLIDE 104 /* In */ +#define GPIO_WS007SH_SD_POWER 107 /* Out: H:ON, L:OFF */ + +/* + * WS011SH specific parameter + */ +/* +port I/O(Active) name desc +1 I(?) RESET_BTN button detect: reset (on: release, off:press) +9 I(?) PWR_BTN button detect: power-on (on: press, off:release) +21 I(?) TPANEL touch panel (on: release, off: press) +37 O USBH_PWR USB Host power (H: enable, L: disable) +41 I(L) USBH_DET USB Host cable detect (on: remove, off: insert) +48 I(L) SD_DET microSD card detect (on: remove, off: insert) +51 I(?) SLIDE LCD slider (on: open, off: close) +52 I(?) KEYLOCK key lock slider (on: unlock, off:lock) +57 I(?) EXCRWAL_DET +81 I(L) EPDET earphone adapter detect (on: remove, off: insert) +91 I(?) FULLKEYBOARD? +96 I(?) JACKET_DET jacket detect (on: close, off: open) +?105 I(?) WSIM_DET W-SIM detect (on: insert, off: remove) +?106 I(?) WSIM? (same as GPIO#105?) +107 O(?) SD_PWR: SD Card power (on: on, off: off) +115 I(H) ACDET AC adapter detect (on: insert, off: remove) +116 I(?) USBC_DET USB Client cable detect (on: insert, off: remove) + */ +#define GPIO_WS011SH_RESET_BUTTON 1 /* In */ +#define GPIO_WS011SH_POWER_BUTTON 9 /* In */ +#define GPIO_WS011SH_TOUCH_PANEL 21 /* In */ +#define GPIO_WS011SH_USB_HOST_POWER 37 /* Out */ +#define GPIO_WS011SH_USB_HOST_DETECT 41 /* In */ +#define GPIO_WS011SH_SD_DETECT 48 /* In */ +#define GPIO_WS011SH_SLIDE 51 /* In */ +#define GPIO_WS011SH_KEY_LOCK 52 /* In */ +#define GPIO_WS011SH_SD_POWER 107 /* Out */ +#define GPIO_WS011SH_USB_CLIENT_DETECT 116 /* In */ + +#endif /* _HPCARM_DEV_WZERO3_REG_H_ */ diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/arch/hpcarm/dev/wzero3_usb.c src/sys/arch/hpcarm/dev/wzero3_usb.c --- src.orig/sys/arch/hpcarm/dev/wzero3_usb.c 1970-01-01 09:00:00.000000000 +0900 +++ src/sys/arch/hpcarm/dev/wzero3_usb.c 2009-02-02 17:08:43.000000000 +0900 @@ -0,0 +1,228 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 2009 NONAKA Kimihiro + * All rights reserved. + * + * 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. + * + * 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. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD$"); + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#if defined(WZERO3USB_DEBUG) +#define DPRINTF(s) printf s +#else +#define DPRINTF(s) +#endif + +struct wzero3usb_softc { + device_t sc_dev; + + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + + int sc_client_pin; + int sc_host_pin; + int sc_host_power_pin; + + void *sc_client_ih; + void *sc_host_ih; +}; + +static int wzero3usb_match(device_t, cfdata_t, void *); +static void wzero3usb_attach(device_t, device_t, void *); + +CFATTACH_DECL_NEW(wzero3usb, sizeof(struct wzero3usb_softc), + wzero3usb_match, wzero3usb_attach, NULL, NULL); + +static int wzero3usb_client_intr(void *); +static int wzero3usb_host_intr(void *); +static void wzero3usb_host_power(struct wzero3usb_softc *); + +static const struct wzero3usb_model { + platid_mask_t *platid; + int client_pin; + int host_pin; + int host_power_pin; +} wzero3usb_table[] = { + /* WS003SH */ + { + &platid_mask_MACH_SHARP_WZERO3_WS003SH, + GPIO_WS003SH_USB_CLIENT_DETECT, + -1, /* None */ + -1, /* None */ + }, + /* WS004SH */ + { + &platid_mask_MACH_SHARP_WZERO3_WS004SH, + GPIO_WS003SH_USB_CLIENT_DETECT, + -1, /* None */ + -1, /* None */ + }, + /* WS007SH */ + { + &platid_mask_MACH_SHARP_WZERO3_WS007SH, + GPIO_WS007SH_USB_CLIENT_DETECT, + GPIO_WS007SH_USB_HOST_DETECT, + GPIO_WS007SH_USB_HOST_POWER, + }, + /* WS011SH */ + { + &platid_mask_MACH_SHARP_WZERO3_WS011SH, + GPIO_WS011SH_USB_CLIENT_DETECT, + GPIO_WS011SH_USB_HOST_DETECT, + GPIO_WS011SH_USB_HOST_POWER, + }, + /* XXX: WS020SH */ + + { NULL, -1, -1, -1, } +}; + +static const struct wzero3usb_model * +wzero3usb_lookup(void) +{ + const struct wzero3usb_model *model; + + for (model = wzero3usb_table; model->platid != NULL; model++) { + if (platid_match(&platid, model->platid)) { + return model; + } + } + return NULL; +} + +static int +wzero3usb_match(device_t parent, cfdata_t cf, void *aux) +{ + + if (strcmp(cf->cf_name, "wzero3usb") != 0) + return 0; + if (wzero3usb_lookup() == NULL) + return 0; + return 1; +} + +static void +wzero3usb_attach(device_t parent, device_t self, void *aux) +{ + struct wzero3usb_softc *sc = device_private(self); + struct pxaip_attach_args *pxa = aux; + const struct wzero3usb_model *model; + + sc->sc_dev = self; + sc->sc_iot = pxa->pxa_iot; + + aprint_normal(": USB Mode detection\n"); + + model = wzero3usb_lookup(); + if (model == NULL) { + aprint_error_dev(self, "unknown model\n"); + return; + } + sc->sc_client_pin = model->client_pin; + sc->sc_host_pin = model->host_pin; + sc->sc_host_power_pin = model->host_power_pin; + + if (bus_space_map(sc->sc_iot, PXA2X0_USBDC_BASE, PXA270_USBDC_SIZE, 0, + &sc->sc_ioh)) { + aprint_error_dev(self, "couldn't map memory space\n"); + return; + } + + if (sc->sc_client_pin >= 0) { + sc->sc_client_ih = pxa2x0_gpio_intr_establish(sc->sc_client_pin, + IST_EDGE_BOTH, IPL_BIO, wzero3usb_client_intr, sc); + } + if (sc->sc_host_pin >= 0) { + sc->sc_host_ih = pxa2x0_gpio_intr_establish(sc->sc_host_pin, + IST_EDGE_BOTH, IPL_BIO, wzero3usb_host_intr, sc); + } + + /* configure port 2 for input */ + bus_space_write_4(sc->sc_iot, sc->sc_ioh, USBDC_UP2OCR, + USBDC_UP2OCR_HXS | USBDC_UP2OCR_HXOE | + USBDC_UP2OCR_DPPDE | USBDC_UP2OCR_DMPDE); + + wzero3usb_host_power(sc); +} + +static int +wzero3usb_host_intr(void *v) +{ + struct wzero3usb_softc *sc = (struct wzero3usb_softc *)v; + + DPRINTF(("%s: USB host cable changed: level = %s\n", + device_xname(sc->sc_dev), + pxa2x0_gpio_get_bit(sc->sc_host_pin) ? "H" : "L")); + + wzero3usb_host_power(sc); + + return 1; +} + +static int +wzero3usb_client_intr(void *v) +{ + struct wzero3usb_softc *sc = (struct wzero3usb_softc *)v; + + DPRINTF(("%s: USB client cable changed: level = %s\n", + device_xname(sc->sc_dev), + pxa2x0_gpio_get_bit(sc->sc_client_pin) ? "H" : "L")); + + (void)sc; /*XXX*/ + + return 1; +} + +static void +wzero3usb_host_power(struct wzero3usb_softc *sc) +{ + int host_cable; + + if (sc->sc_host_pin >= 0 && sc->sc_host_power_pin >= 0) { + host_cable = pxa2x0_gpio_get_bit(sc->sc_host_pin); + + if (!host_cable) { + DPRINTF(("%s: enable USB host power\n", + device_xname(sc->sc_dev))); + pxa2x0_gpio_set_bit(sc->sc_host_power_pin); + } else { + DPRINTF(("%s: disable USB host power\n", + device_xname(sc->sc_dev))); + pxa2x0_gpio_clear_bit(sc->sc_host_power_pin); + } + } +} diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/arch/hpcarm/hpcarm/autoconf.c src/sys/arch/hpcarm/hpcarm/autoconf.c --- src.orig/sys/arch/hpcarm/hpcarm/autoconf.c 2008-06-14 19:45:39.000000000 +0900 +++ src/sys/arch/hpcarm/hpcarm/autoconf.c 2008-11-10 01:16:59.000000000 +0900 @@ -54,7 +54,10 @@ #include #include +#include "opt_cputypes.h" +#if defined(CPU_SA1100) || defined(CPU_SA1110) #include "sacom.h" +#endif extern dev_t dumpdev; @@ -163,9 +166,11 @@ panic("configure: mainbus not configured"); /* Debugging information */ -#ifdef DIAGNOSTIC +#if defined(DIAGNOSTIC) +#if defined(CPU_SA1100) || defined(CPU_SA1110) dump_spl_masks(); #endif +#endif /* DIAGNOSTIC */ /* Time to start taking interrupts so lets open the flood gates .... */ (void)spl0(); diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/arch/hpcarm/hpcarm/hpc_machdep.c src/sys/arch/hpcarm/hpcarm/hpc_machdep.c --- src.orig/sys/arch/hpcarm/hpcarm/hpc_machdep.c 2010-03-06 06:01:13.000000000 +0900 +++ src/sys/arch/hpcarm/hpcarm/hpc_machdep.c 2010-03-06 06:23:50.000000000 +0900 @@ -42,80 +42,24 @@ #include __KERNEL_RCSID(0, "$NetBSD: hpc_machdep.c,v 1.96 2010/03/02 21:17:31 pooka Exp $"); -#include "opt_ddb.h" -#include "opt_modular.h" -#include "opt_pmap_debug.h" -#include "ksyms.h" - #include -#include #include #include -#include -#include -#include -#include -#include -#include /* XXX for consinit related hacks */ -#include - -#if NKSYMS || defined(DDB) || defined(MODULAR) -#include -#include -#include -#ifndef DB_ELFSIZE -#error Must define DB_ELFSIZE! -#endif -#define ELFSIZE DB_ELFSIZE -#include -#endif #include -#include -#include -#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include +#include #include #include -#include - -#include -#include -#include -#include -#include - -/* Kernel text starts 256K in from the bottom of the kernel address space. */ -#define KERNEL_TEXT_BASE (KERNEL_BASE + 0x00040000) -#define KERNEL_VM_BASE (KERNEL_BASE + 0x00C00000) -#define KERNEL_VM_SIZE 0x05000000 - -/* - * Address to call from cpu_reset() to reset the machine. - * This is machine architecture dependent 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 BootConfig bootconfig; /* Boot config storage */ struct bootinfo *bootinfo, bootinfo_storage; -static char booted_kernel_storage[80]; +char booted_kernel_storage[80]; char *booted_kernel = booted_kernel_storage; paddr_t physical_start; @@ -127,7 +71,6 @@ 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; @@ -139,52 +82,13 @@ vaddr_t msgbufphys; -extern u_int data_abort_handler_address; -extern u_int prefetch_abort_handler_address; -extern u_int undefined_handler_address; -extern int end; - -#ifdef PMAP_DEBUG -extern int pmap_debug_level; -#endif /* PMAP_DEBUG */ - -#define KERNEL_PT_VMEM 0 /* Page table for mapping video memory */ -#define KERNEL_PT_SYS 1 /* Page table for mapping proc0 zero page */ -#define KERNEL_PT_IO 2 /* Page table for mapping IO */ -#define KERNEL_PT_KERNEL 3 /* 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]; - -#define CPU_SA110_CACHE_CLEAN_SIZE (0x4000 * 2) -extern unsigned int sa1_cache_clean_addr; -extern unsigned int sa1_cache_clean_size; -static vaddr_t sa1_cc_base; +/* Prototypes */ +void dumpsys(void); /* Mode dependent sleep function holder */ void (*__sleep_func)(void *); void *__sleep_ctx; -/* Non-buffered non-cacheable memory needed to enter idle mode */ -extern vaddr_t sa11x0_idle_mem; - -/* Prototypes */ -void data_abort_handler(trapframe_t *); -void prefetch_abort_handler(trapframe_t *); -void undefinedinstruction_bounce(trapframe_t *); -void dumpsys(void); -u_int cpu_get_control(void); - -u_int initarm(int, char **, struct bootinfo *); - -#ifdef DEBUG_BEFOREMMU -static void fakecninit(void); -#endif - #ifdef BOOT_DUMP static void dumppages(char *, int); #endif @@ -257,466 +161,6 @@ /* NOTREACHED */ } -/* Number of DRAM pages which are installed */ -/* Units are 4K pages, so 8192 is 32 MB of memory */ -#ifndef DRAM_PAGES -#define DRAM_PAGES 8192 -#endif - -/* - * 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. - */ -static const struct pmap_devmap sa11x0_devmap[] = { - /* Physical/virtual address for UART #3. */ - { - SACOM3_VBASE, - SACOM3_BASE, - 0x24, - VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE - }, - { 0, 0, 0, 0, 0 } -}; - -/* - * 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. - * Initializing the physical console so characters can be printed. - * Setting up page tables for the kernel. - */ -u_int -initarm(int argc, char **argv, struct bootinfo *bi) -{ - u_int kerneldatasize, symbolsize; - u_int l1pagetable; - vaddr_t freemempos; - vsize_t pt_size; - int loop, i; -#if NKSYMS || defined(DDB) || defined(MODULAR) - Elf_Shdr *sh; -#endif - - __sleep_func = NULL; - __sleep_ctx = NULL; - - /* - * Heads up ... Setup the CPU / MMU / TLB functions. - */ - set_cpufuncs(); - IRQdisable; - -#ifdef DEBUG_BEFOREMMU - /* - * At this point, we cannot call real consinit(). - * Just call a faked up version of consinit(), which does the thing - * with MMU disabled. - */ - fakecninit(); -#endif - - /* - * XXX for now, overwrite bootconfig to hardcoded values. - * XXX kill bootconfig and directly call uvm_physload - */ - bootconfig.dram[0].address = 0xc0000000; - bootconfig.dram[0].pages = DRAM_PAGES; - bootconfig.dramblocks = 1; - kerneldatasize = (uint32_t)&end - (uint32_t)KERNEL_TEXT_BASE; - - symbolsize = 0; -#if NKSYMS || defined(DDB) || defined(MODULAR) - if (!memcmp(&end, "\177ELF", 4)) { - 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; - } -#endif - - printf("kernsize=0x%x\n", kerneldatasize); - kerneldatasize += symbolsize; - kerneldatasize = ((kerneldatasize - 1) & ~(PAGE_SIZE * 4 - 1)) + - PAGE_SIZE * 8; - - /* parse kernel args */ - boothowto = 0; - boot_file[0] = '\0'; - strncpy(booted_kernel_storage, argv[0], sizeof(booted_kernel_storage)); - for (i = 1; i < argc; i++) { - char *cp = argv[i]; - - switch (*cp) { - case 'b': - /* boot device: -b=sd0 etc. */ - cp = cp + 2; - if (strcmp(cp, MOUNT_NFS) == 0) - rootfstype = MOUNT_NFS; - else - strncpy(boot_file, cp, sizeof(boot_file)); - break; - default: - BOOT_FLAG(*cp, boothowto); - break; - } - } - - /* copy bootinfo into known kernel space */ - bootinfo_storage = *bi; - bootinfo = &bootinfo_storage; - -#ifdef BOOTINFO_FB_WIDTH - bootinfo->fb_line_bytes = BOOTINFO_FB_LINE_BYTES; - bootinfo->fb_width = BOOTINFO_FB_WIDTH; - bootinfo->fb_height = BOOTINFO_FB_HEIGHT; - bootinfo->fb_type = BOOTINFO_FB_TYPE; -#endif - - /* - * hpcboot has loaded me with MMU disabled. - * So create kernel page tables and enable MMU. - */ - - /* - * Set up the variables that define the availability of physcial - * memory. - */ - physical_start = bootconfig.dram[0].address; - physical_freestart = physical_start - + (KERNEL_TEXT_BASE - KERNEL_BASE) + kerneldatasize; - physical_end = bootconfig.dram[bootconfig.dramblocks - 1].address - + bootconfig.dram[bootconfig.dramblocks - 1].pages * PAGE_SIZE; - physical_freeend = physical_end; - - for (loop = 0; loop < bootconfig.dramblocks; ++loop) - physmem += bootconfig.dram[loop].pages; - - /* XXX handle UMA framebuffer memory */ - - /* Use the first 256kB to allocate things */ - freemempos = KERNEL_BASE; - memset((void *)KERNEL_BASE, 0, KERNEL_TEXT_BASE - KERNEL_BASE); - - /* - * Right. We have the bottom meg of memory mapped to 0x00000000 - * so was can get at it. The kernel will occupy the start of it. - * After the kernel/args we allocate some of the fixed page tables - * we need to get the system going. - * We allocate one page directory and NUM_KERNEL_PTS page tables - * and store the physical addresses in the kernel_pt_table array. - * Must remember that neither the page L1 or L2 page tables are the - * same size as a page ! - * - * Ok, the next bit of physical allocate may look complex but it is - * simple really. I have done it like this so that no memory gets - * wasted during the allocate of various pages and tables that are - * all different sizes. - * The start address will be page aligned. - * We allocate the kernel page directory on the first free 16KB - * boundary we find. - * We allocate the kernel page tables on the first 1KB boundary we - * find. We allocate at least 9 PT's (12 currently). This means - * that in the process we KNOW that we will encounter at least one - * 16KB boundary. - * - * Eventually if the top end of the memory gets used for process L1 - * page tables the kernel L1 page table may be moved up there. - */ - -#ifdef VERBOSE_INIT_ARM - printf("Allocating page tables\n"); -#endif - - /* Define a macro to simplify memory allocation */ -#define valloc_pages(var, np) \ - (var).pv_pa = (var).pv_va = freemempos; \ - freemempos += (np) * PAGE_SIZE; -#define alloc_pages(var, np) \ - (var) = freemempos; \ - freemempos += (np) * PAGE_SIZE; - - - valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE); - for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) { - alloc_pages(kernel_pt_table[loop].pv_pa, - L2_TABLE_SIZE / PAGE_SIZE); - kernel_pt_table[loop].pv_va = kernel_pt_table[loop].pv_pa; - } - - /* - * 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. - */ - valloc_pages(systempage, 1); - - pt_size = round_page(freemempos) - KERNEL_BASE; - - /* 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); - - /* - * XXX Actually, we only need virtual space and don't need - * XXX physical memory for sa110_cc_base and sa11x0_idle_mem. - */ - /* - * XXX totally stuffed hack to work round problems introduced - * in recent versions of the pmap code. Due to the calls used there - * we cannot allocate virtual memory during bootstrap. - */ - for (;;) { - alloc_pages(sa1_cc_base, 1); - if (!(sa1_cc_base & (CPU_SA110_CACHE_CLEAN_SIZE - 1))) - break; - } - { - vaddr_t dummy; - alloc_pages(dummy, CPU_SA110_CACHE_CLEAN_SIZE / PAGE_SIZE - 1); - } - sa1_cache_clean_addr = sa1_cc_base; - sa1_cache_clean_size = CPU_SA110_CACHE_CLEAN_SIZE / 2; - - alloc_pages(sa11x0_idle_mem, 1); - - /* - * Ok, we have allocated physical pages for the primary kernel - * page tables. - */ - -#ifdef VERBOSE_INIT_ARM - printf("Creating L1 page table\n"); -#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]); -#define SAIPIO_BASE 0xd0000000 /* XXX XXX */ - pmap_link_l2pt(l1pagetable, SAIPIO_BASE, - &kernel_pt_table[KERNEL_PT_IO]); - 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 code/data */ - - /* - * XXX there is no ELF header to find RO region. - * XXX What should we do? - */ -#if 0 - if (N_GETMAGIC(kernexec[0]) == ZMAGIC) { - logical = pmap_map_chunk(l1pagetable, KERNEL_TEXT_BASE, - physical_start, kernexec->a_text, - VM_PROT_READ, PTE_CACHE); - logical += pmap_map_chunk(l1pagetable, - KERNEL_TEXT_BASE + logical, physical_start + logical, - kerneldatasize - kernexec->a_text, - VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); - } else -#endif - pmap_map_chunk(l1pagetable, KERNEL_TEXT_BASE, - KERNEL_TEXT_BASE, kerneldatasize, - 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); - - /* Map page tables */ - pmap_map_chunk(l1pagetable, KERNEL_BASE, KERNEL_BASE, pt_size, - VM_PROT_READ | VM_PROT_WRITE, PTE_PAGETABLE); - - /* Map a page for entering idle mode */ - pmap_map_entry(l1pagetable, sa11x0_idle_mem, sa11x0_idle_mem, - VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE); - - /* Map the vector page. */ - pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa, - VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); - - /* Map the statically mapped devices. */ - pmap_devmap_bootstrap(l1pagetable, sa11x0_devmap); - - pmap_map_chunk(l1pagetable, sa1_cache_clean_addr, 0xe0000000, - CPU_SA110_CACHE_CLEAN_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); - /* - * 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. - */ - - printf("done.\n"); - - /* - * 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); -#ifdef PMAP_DEBUG - if (pmap_debug_level >= 0) - printf("kstack V%08lx P%08lx\n", kernelstack.pv_va, - kernelstack.pv_pa); -#endif /* PMAP_DEBUG */ - - /* - * 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. - * Initialization 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; - printf("%08x %08x %08x\n", data_abort_handler_address, - prefetch_abort_handler_address, undefined_handler_address); - - /* Initialize the undefined instruction handlers */ - printf("undefined "); - undefined_init(); - - /* Set the page table address. */ - cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT); - cpu_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. - */ - uvm_lwp_setuarea(&lwp0, kernelstack.pv_va); - -#ifdef BOOT_DUMP - dumppages((char *)0xc0000000, 16 * PAGE_SIZE); - dumppages((char *)0xb0100000, 64); /* XXX */ -#endif - /* Enable MMU, I-cache, D-cache, write buffer. */ - cpufunc_control(0x337f, 0x107d); - - arm32_vector_init(ARM_VECTORS_LOW, ARM_VEC_ALL); - - consinit(); - -#ifdef VERBOSE_INIT_ARM - printf("freemempos=%08lx\n", freemempos); - printf("MMU enabled. control=%08x\n", cpu_get_control()); -#endif - - /* Load memory into UVM. */ - uvm_setpagesize(); /* initialize PAGE_SIZE-dependent variables */ - for (loop = 0; loop < bootconfig.dramblocks; loop++) { - paddr_t dblk_start = (paddr_t)bootconfig.dram[loop].address; - paddr_t dblk_end = dblk_start - + (bootconfig.dram[loop].pages * PAGE_SIZE); - - if (dblk_start < physical_freestart) - dblk_start = physical_freestart; - if (dblk_end > physical_freeend) - dblk_end = physical_freeend; - - uvm_page_physload(atop(dblk_start), atop(dblk_end), - atop(dblk_start), atop(dblk_end), VM_FREELIST_DEFAULT); - } - - /* Boot strap pmap telling it where the kernel page table is */ - pmap_bootstrap(KERNEL_VM_BASE, KERNEL_VM_BASE + KERNEL_VM_SIZE); - -#ifdef BOOT_DUMP - dumppages((char *)kernel_l1pt.pv_va, 16); -#endif - -#ifdef DDB - db_machine_init(); -#endif -#if NKSYMS || defined(DDB) || defined(MODULAR) - ksyms_addsyms_elf(symbolsize, ((int *)&end), ((char *)&end) + symbolsize); -#endif - - printf("kernsize=0x%x", kerneldatasize); - printf(" (including 0x%x symbols)\n", symbolsize); - -#ifdef DDB - if (boothowto & RB_KDB) - Debugger(); -#endif /* DDB */ - - if (bootinfo->magic == BOOTINFO_MAGIC) { - platid.dw.dw0 = bootinfo->platid_cpu; - platid.dw.dw1 = bootinfo->platid_machine; - } - - /* We return the new stack pointer address */ - return (kernelstack.pv_va + USPACE_SVC_STACK_TOP); -} - void machine_sleep(void) { @@ -728,41 +172,7 @@ void machine_standby(void) { - -} - -void -consinit(void) -{ - static int consinit_called = 0; - - if (consinit_called != 0) - return; - - consinit_called = 1; - if (bootinfo->bi_cnuse == BI_CNUSE_SERIAL) - cninit(); - else { - /* - * Nothing to do here. Console initialization is done at - * autoconf device attach time. - */ - } -} - -#ifdef DEBUG_BEFOREMMU -cons_decl(sacom); - -static void -fakecninit(void) -{ - static struct consdev fakecntab = cons_init(sacom); - cn_tab = &fakecntab; - - (*cn_tab->cn_init)(0); - cn_tab->cn_pri = CN_REMOTE; } -#endif #ifdef BOOT_DUMP static void diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/arch/hpcarm/hpcarm/intr.c src/sys/arch/hpcarm/hpcarm/intr.c --- src.orig/sys/arch/hpcarm/hpcarm/intr.c 2008-11-20 01:29:36.000000000 +0900 +++ src/sys/arch/hpcarm/hpcarm/intr.c 2008-11-20 01:34:24.000000000 +0900 @@ -39,6 +39,7 @@ __KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.16 2008/11/19 06:41:01 matt Exp $"); #include "opt_irqstats.h" +#include "opt_cputypes.h" #include #include @@ -72,10 +73,12 @@ extern void comsoft(void); #endif /* NCOM > 0 */ +#if defined(CPU_SA1100) || defined(CPU_SA1110) #include "sacom.h" #if NSACOM > 0 extern void sacomsoft(void); #endif /* NSACOM > 0 */ +#endif /* Eventually these will become macros */ diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/arch/hpcarm/hpcarm/locore.S src/sys/arch/hpcarm/hpcarm/locore.S --- src.orig/sys/arch/hpcarm/hpcarm/locore.S 2008-01-25 23:45:05.000000000 +0900 +++ src/sys/arch/hpcarm/hpcarm/locore.S 2008-04-21 22:29:32.000000000 +0900 @@ -31,6 +31,7 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "opt_cputypes.h" #include "assym.h" #include #include @@ -38,6 +39,11 @@ #include #include #include +#if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270) +#include +#include +#include /* for PMAP_DOMAIN_KERNEL */ +#endif /* What size should this really be ? It is only used by init_arm() */ #define INIT_ARM_STACK_SIZE 2048 @@ -53,7 +59,7 @@ /* Put the processer in SVC mode */ mov r5, sp mrs r4, cpsr_all - bic r4, r4, #31 + bic r4, r4, #(PSR_MODE) orr r4, r4, #(PSR_SVC32_MODE) msr cpsr_all, r4 mov sp, r5 @@ -62,6 +68,95 @@ mov r4, #0 mcr 15, 0, r4, c13, c0, 0 +#if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270) +/* + * 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_BRANCH \ + sub pc, pc, #4 + +#define CPWAIT(tmp) \ + mrc p15, 0, tmp, c2, c0, 0 /* arbitrary read of CP15 */ ;\ + mov tmp, tmp /* wait for it to complete */ ;\ + CPWAIT_BRANCH /* branch to next insn */ + + /* + * Kernel is loaded in SDRAM (0xa0200000..), and is expected to run + * in VA 0xc0200000.. + */ + + /* build page table from scratch */ + adr r9, .Lstartup_pagetable + ldr r9, [r9] + adr r4, .Lmmu_init_table + b 3f + +2: + str r8, [r9, r7] + add r7, r7, #4 + add r8, r8, #(L1_S_SIZE) + subs r6, r6, #1 + bne 2b +3: + ldmia r4!, {r6,r7,r8} /* # of sections, VA, PA|attr */ + cmp r6, #0 + bne 2b + + /* Set translation table */ + mcr p15, 0, r9, c2, c0, 0 + mcr p15, 0, r9, c8, c7, 0 /* flush I/D-TLBs */ + CPWAIT(r9) + + /* Set the Domain Access register. Very important! */ + mov r9, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT) + mcr p15, 0, r9, c3, c0, 0 + + /* Enable MMU */ + mrc p15, 0, r9, c1, c0, 0 + orr r9, r9, #CPU_CONTROL_SYST_ENABLE + orr r9, r9, #CPU_CONTROL_MMU_ENABLE + mcr p15, 0, r9, c1, c0, 0 + CPWAIT(r9) + + /* Jump to kernel code in TRUE VA */ + adr r9, .Lstart + ldmia r9, {r9, sp} /* and set stack pointer */ + mov pc, r9 + +.Lstart: + .word hpc_start + .word svcstk + INIT_ARM_STACK_SIZE + +#define MMU_INIT(va,pa,n_sec,attr) \ + .word (n_sec); \ + .word 4 * ((va) >> L1_S_SHIFT); \ + .word (pa)|(attr); + +.Lstartup_pagetable: + .word 0xa0004000 + +.Lmmu_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(0xa0000000, 0xa0000000, 256, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW)) + /* map VA 0xc0000000..0xcfffffff to PA 0xa0000000..0xafffffff */ + MMU_INIT(0xc0000000, 0xa0000000, 256, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW)) + + .word 0,0,0 /* end of table */ + + .bss +svcstk: + .space INIT_ARM_STACK_SIZE + + .text + .align 0 +ASENTRY_NP(hpc_start) +#endif + mov fp, #0x00000000 /* trace back starts here */ bl _C_LABEL(initarm) /* Off we go */ @@ -74,19 +169,12 @@ sub fp, ip, #4 /* Setup an initial trap frame for start_init to use */ - PUSHFRAME - mov r0, sp /* parameter to main is trap frame */ - bl _C_LABEL(main) /* Lets light the flame and start her up */ - PULLFRAME /* Pull the trap frame, now valid */ - movs pc, lr /* Exit to user process */ - /* Never gets here */ - b . .text diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/arch/hpcarm/hpcarm/pxa2x0_hpc_machdep.c src/sys/arch/hpcarm/hpcarm/pxa2x0_hpc_machdep.c --- src.orig/sys/arch/hpcarm/hpcarm/pxa2x0_hpc_machdep.c 1970-01-01 09:00:00.000000000 +0900 +++ src/sys/arch/hpcarm/hpcarm/pxa2x0_hpc_machdep.c 2010-03-06 06:24:31.000000000 +0900 @@ -0,0 +1,853 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 1994-1998 Mark Brinicombe. + * Copyright (c) 1994 Brini. + * All rights reserved. + * + * This code is derived from software written for Brini by Mark Brinicombe + * + * 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 Brini. + * 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 BRINI ``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 BRINI 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 dependent functions for kernel setup. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD$"); + +#include "opt_ddb.h" +#include "opt_dram_pages.h" +#include "opt_modular.h" +#include "opt_pmap_debug.h" +#include "ksyms.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* XXX for consinit related hacks */ +#include +#include + +#if NKSYMS || defined(DDB) || defined(MODULAR) +#include +#include +#include +#ifndef DB_ELFSIZE +#error Must define DB_ELFSIZE! +#endif +#define ELFSIZE DB_ELFSIZE +#include +#endif + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "com.h" +#if (NCOM > 0) +#include "opt_com.h" +#include +#endif /* NCOM > 0 */ +#include "lcd.h" +#include "wzero3lcd.h" + +#include +#include +#include +#include +#include + +/* 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 + 0x00C00000) +#define KERNEL_VM_SIZE 0x05000000 + +/* + * 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 + +extern BootConfig bootconfig; /* Boot config storage */ +extern struct bootinfo *bootinfo, bootinfo_storage; +extern char booted_kernel_storage[80]; +extern char *booted_kernel; + +extern paddr_t physical_start; +extern paddr_t physical_freestart; +extern paddr_t physical_freeend; +extern paddr_t physical_end; +extern int physmem; + +/* Physical and virtual addresses for some global pages */ +extern pv_addr_t irqstack; +extern pv_addr_t undstack; +extern pv_addr_t abtstack; +extern pv_addr_t kernelstack; + +extern char *boot_args; +extern char boot_file[16]; + +extern vaddr_t msgbufphys; + +extern u_int data_abort_handler_address; +extern u_int prefetch_abort_handler_address; +extern u_int undefined_handler_address; +extern int end; + +#ifdef PMAP_DEBUG +extern int pmap_debug_level; +#endif /* PMAP_DEBUG */ + +#define KERNEL_PT_VMEM 0 /* Page table for mapping video memory */ +#define KERNEL_PT_SYS 1 /* Page table for mapping proc0 zero page */ +#define KERNEL_PT_IO 2 /* Page table for mapping IO */ +#define KERNEL_PT_KERNEL 3 /* 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]; + +pv_addr_t minidataclean; + +/* Prototypes */ +void data_abort_handler(trapframe_t *); +void prefetch_abort_handler(trapframe_t *); +void undefinedinstruction_bounce(trapframe_t *); +u_int cpu_get_control(void); + +u_int initarm(int, char **, struct bootinfo *); + +/* Mode dependent sleep function holder */ +extern void (*__sleep_func)(void *); +extern void *__sleep_ctx; + +#ifdef DEBUG_BEFOREMMU +static void fakecninit(void); +#endif + +/* Number of DRAM pages which are installed */ +/* Units are 4K pages, so 8192 is 32 MB of memory */ +#ifndef DRAM_PAGES +#define DRAM_PAGES 8192 +#endif + +/* + * 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. + */ +#define PXA2X0_GPIO_VBASE 0xfd000000 +#define PXA2X0_CLKMAN_VBASE 0xfd100000 +#define PXA2X0_INTCTL_VBASE 0xfd200000 +#define PXA2X0_MEMCTL_VBASE 0xfd300000 +#define PXA2X0_FFUART_VBASE 0xfd400000 +#define PXA2X0_BTUART_VBASE 0xfd500000 +#define PXA2X0_STUART_VBASE 0xfd600000 + +#define _A(a) ((a) & L1_S_FRAME) +#define _S(s) (((s) + L1_S_SIZE - 1) & L1_S_FRAME) +const struct pmap_devmap pxa2x0_devmap[] = { + { + PXA2X0_GPIO_VBASE, + _A(PXA2X0_GPIO_BASE), + _S(PXA2X0_GPIO_SIZE), + VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, + }, + { + PXA2X0_CLKMAN_VBASE, + _A(PXA2X0_CLKMAN_BASE), + _S(PXA2X0_CLKMAN_SIZE), + VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, + }, + { + PXA2X0_INTCTL_VBASE, + _A(PXA2X0_INTCTL_BASE), + _S(PXA2X0_INTCTL_SIZE), + VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, + }, + { + PXA2X0_MEMCTL_VBASE, + _A(PXA2X0_MEMCTL_BASE), + _S(PXA2X0_MEMCTL_SIZE), + VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, + }, + { + PXA2X0_FFUART_VBASE, + _A(PXA2X0_FFUART_BASE), + _S(4 * COM_NPORTS), + VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, + }, + { + PXA2X0_BTUART_VBASE, + _A(PXA2X0_BTUART_BASE), + _S(4 * COM_NPORTS), + VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, + }, + { + PXA2X0_STUART_VBASE, + _A(PXA2X0_STUART_BASE), + _S(4 * COM_NPORTS), + VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, + }, + + { 0, 0, 0, 0, 0, } +}; +#undef _A +#undef _S + +static struct pxa2x0_gpioconf ws003sh_boarddep_gpioconf[] = { + { 41, GPIO_ALT_FN_1_IN }, /* FFRXD */ + { 99, GPIO_ALT_FN_3_OUT }, /* FFTXD */ + { 98, GPIO_ALT_FN_3_OUT }, /* FFRTS */ +#if 0 + { 40, GPIO_ALT_FN_2_OUT }, /* FFDTR */ + { 100, GPIO_ALT_FN_1_IN }, /* FFCTS */ +#endif + + { -1 } +}; +static struct pxa2x0_gpioconf *ws003sh_gpioconf[] = { + pxa27x_com_ffuart_gpioconf, + ws003sh_boarddep_gpioconf, + NULL +}; + +static inline pd_entry_t * +read_ttb(void) +{ + u_long ttb; + + __asm volatile("mrc p15, 0, %0, c2, c0, 0" : "=r" (ttb)); + + return (pd_entry_t *)(ttb & ~((1 << 14) - 1)); +} + +/* + * 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. + * Initializing the physical console so characters can be printed. + * Setting up page tables for the kernel. + */ +u_int +initarm(int argc, char **argv, struct bootinfo *bi) +{ +#ifdef DIAGNOSTIC + extern vsize_t xscale_minidata_clean_size; /* used in KASSERT */ +#endif + extern vaddr_t xscale_cache_clean_addr; + u_int kerneldatasize, symbolsize; + u_int l1pagetable; + vaddr_t freemempos; + vsize_t pt_size; + int loop, i; +#if NKSYMS || defined(DDB) || defined(MODULAR) + Elf_Shdr *sh; +#endif + + __sleep_func = NULL; + __sleep_ctx = NULL; + + /* parse kernel args */ + boothowto = 0; + boot_file[0] = '\0'; + strncpy(booted_kernel_storage, argv[0], sizeof(booted_kernel_storage)); + for (i = 1; i < argc; i++) { + char *cp = argv[i]; + + switch (*cp) { + case 'b': + /* boot device: -b=sd0 etc. */ + cp = cp + 2; + if (strcmp(cp, MOUNT_NFS) == 0) + rootfstype = MOUNT_NFS; + else + strncpy(boot_file, cp, sizeof(boot_file)); + break; + default: + BOOT_FLAG(*cp, boothowto); + break; + } + } + + /* copy bootinfo into known kernel space */ + bootinfo_storage = *bi; + bootinfo = &bootinfo_storage; + +#ifdef BOOTINFO_FB_WIDTH + bootinfo->fb_line_bytes = BOOTINFO_FB_LINE_BYTES; + bootinfo->fb_width = BOOTINFO_FB_WIDTH; + bootinfo->fb_height = BOOTINFO_FB_HEIGHT; + bootinfo->fb_type = BOOTINFO_FB_TYPE; +#endif + + if (bootinfo->magic == BOOTINFO_MAGIC) { + platid.dw.dw0 = bootinfo->platid_cpu; + platid.dw.dw1 = bootinfo->platid_machine; + } + + /* + * Heads up ... Setup the CPU / MMU / TLB functions. + */ + set_cpufuncs(); + IRQdisable; + + pxa2x0_memctl_bootstrap(PXA2X0_MEMCTL_BASE); + pxa2x0_intr_bootstrap(PXA2X0_INTCTL_BASE); + pmap_devmap_bootstrap((vaddr_t)read_ttb(), pxa2x0_devmap); + pxa2x0_memctl_bootstrap(PXA2X0_MEMCTL_VBASE); + pxa2x0_intr_bootstrap(PXA2X0_INTCTL_VBASE); + pxa2x0_clkman_bootstrap(PXA2X0_CLKMAN_VBASE); + pxa2x0_gpio_bootstrap(PXA2X0_GPIO_VBASE); + + if (bi->magic == BOOTINFO_MAGIC) { + if (bi->platid_cpu == PLATID_CPU_ARM_XSCALE_PXA270) { + if ((bi->platid_machine == PLATID_MACH_SHARP_WZERO3_WS003SH) + || (bi->platid_machine == PLATID_MACH_SHARP_WZERO3_WS004SH) + || (bi->platid_machine == PLATID_MACH_SHARP_WZERO3_WS007SH) + || (bi->platid_machine == PLATID_MACH_SHARP_WZERO3_WS011SH) + || (bi->platid_machine == PLATID_MACH_SHARP_WZERO3_WS020SH)) { + if (bi->platid_machine == PLATID_MACH_SHARP_WZERO3_WS003SH) { + pxa2x0_gpio_config(ws003sh_gpioconf); + } + pxa2x0_clkman_config(CKEN_FFUART, 1); + pxa2x0_clkman_config(CKEN_NSSP, 1); /* XXXOST */ + pxa2x0_clkman_config(CKEN_USBHC, 0); + pxa2x0_clkman_config(CKEN_USBDC, 0); + pxa2x0_clkman_config(CKEN_AC97, 0); + pxa2x0_clkman_config(CKEN_SSP, 0); + pxa2x0_clkman_config(CKEN_HWUART, 0); + pxa2x0_clkman_config(CKEN_STUART, 0); + pxa2x0_clkman_config(CKEN_BTUART, 0); + pxa2x0_clkman_config(CKEN_I2S, 0); + pxa2x0_clkman_config(CKEN_MMC, 0); + pxa2x0_clkman_config(CKEN_FICP, 0); + pxa2x0_clkman_config(CKEN_I2C, 0); + if (bi->platid_machine != PLATID_MACH_SHARP_WZERO3_WS011SH) + pxa2x0_clkman_config(CKEN_PWM0, 0); /* WS011SH: DON'T DISABLE */ + pxa2x0_clkman_config(CKEN_PWM1, 0); + } + } + } + +#ifdef DEBUG_BEFOREMMU + /* + * At this point, we cannot call real consinit(). + * Just call a faked up version of consinit(), which does the thing + * with MMU disabled. + */ + fakecninit(); +#endif + + /* + * XXX for now, overwrite bootconfig to hardcoded values. + * XXX kill bootconfig and directly call uvm_physload + */ + bootconfig.dram[0].address = 0xa0000000; + bootconfig.dram[0].pages = DRAM_PAGES; + bootconfig.dramblocks = 1; + + kerneldatasize = (uint32_t)&end - (uint32_t)KERNEL_TEXT_BASE; + symbolsize = 0; +#if NKSYMS || defined(DDB) || defined(MODULAR) + if (!memcmp(&end, "\177ELF", 4)) { + 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; + } +#endif + + printf("kernsize=0x%x\n", kerneldatasize); + kerneldatasize += symbolsize; + kerneldatasize = ((kerneldatasize - 1) & ~(PAGE_SIZE * 4 - 1)) + + PAGE_SIZE * 8; + + /* + * hpcboot has loaded me with MMU disabled. + * So create kernel page tables and enable MMU. + */ + + /* + * Set up the variables that define the availability of physcial + * memory. + */ + physical_start = bootconfig.dram[0].address; + physical_freestart = physical_start + + (KERNEL_TEXT_BASE - KERNEL_BASE) + kerneldatasize; + physical_end = bootconfig.dram[bootconfig.dramblocks - 1].address + + bootconfig.dram[bootconfig.dramblocks - 1].pages * PAGE_SIZE; + physical_freeend = physical_end; + + for (loop = 0; loop < bootconfig.dramblocks; ++loop) + physmem += bootconfig.dram[loop].pages; + + /* XXX handle UMA framebuffer memory */ + + freemempos = 0xa0009000UL; + memset((void *)freemempos, 0, KERNEL_TEXT_BASE - KERNEL_BASE - 0x9000); + + /* + * Right. We have the bottom meg of memory mapped to 0x00000000 + * so was can get at it. The kernel will occupy the start of it. + * After the kernel/args we allocate some of the fixed page tables + * we need to get the system going. + * We allocate one page directory and NUM_KERNEL_PTS page tables + * and store the physical addresses in the kernel_pt_table array. + * Must remember that neither the page L1 or L2 page tables are the + * same size as a page ! + * + * Ok, the next bit of physical allocate may look complex but it is + * simple really. I have done it like this so that no memory gets + * wasted during the allocate of various pages and tables that are + * all different sizes. + * The start address will be page aligned. + * We allocate the kernel page directory on the first free 16KB + * boundary we find. + * We allocate the kernel page tables on the first 1KB boundary we + * find. We allocate at least 9 PT's (12 currently). This means + * that in the process we KNOW that we will encounter at least one + * 16KB boundary. + * + * Eventually if the top end of the memory gets used for process L1 + * page tables the kernel L1 page table may be moved up there. + */ + +#ifdef VERBOSE_INIT_ARM + printf("Allocating page tables\n"); +#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) \ + (var) = freemempos; \ + freemempos += (np) * PAGE_SIZE; + + { + int 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 (((freemempos - 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"); + + /* + * 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. + */ + valloc_pages(systempage, 1); + + pt_size = round_page(freemempos) - physical_start; + + /* 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); + + /* Allocate enough pages for cleaning the Mini-Data cache. */ + KASSERT(xscale_minidata_clean_size <= PAGE_SIZE); + valloc_pages(minidataclean, 1); +#ifdef VERBOSE_INIT_ARM + printf("minidataclean: p0x%08lx v0x%08lx, size = %ld\n", + minidataclean.pv_pa, minidataclean.pv_va, + xscale_minidata_clean_size); +#endif + + /* + * Ok, we have allocated physical pages for the primary kernel + * page tables. + */ + +#ifdef VERBOSE_INIT_ARM + printf("Creating L1 page table\n"); +#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 code/data */ + + /* + * XXX there is no ELF header to find RO region. + * XXX What should we do? + */ +#if 0 + if (N_GETMAGIC(kernexec[0]) == ZMAGIC) { + logical = pmap_map_chunk(l1pagetable, KERNEL_TEXT_BASE, + physical_start, kernexec->a_text, + VM_PROT_READ, PTE_CACHE); + logical += pmap_map_chunk(l1pagetable, + KERNEL_TEXT_BASE + logical, physical_start + logical, + kerneldatasize - kernexec->a_text, + VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); + } else +#endif + pmap_map_chunk(l1pagetable, KERNEL_TEXT_BASE, + KERNEL_TEXT_BASE - KERNEL_BASE + physical_start, + kerneldatasize, 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); + + /* Map page tables */ + 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 Mini-Data cache clean area. */ + xscale_setup_minidata(l1pagetable, minidataclean.pv_va, + minidataclean.pv_pa); + + /* Map the vector page. */ + pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa, + VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); + + /* + * map integrated peripherals at same address in l1pagetable + * so that we can continue to use console. + */ + pmap_devmap_bootstrap(l1pagetable, pxa2x0_devmap); + + /* + * 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. + */ + +#ifdef VERBOSE_INIT_ARM + printf("done.\n"); +#endif + + /* + * 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); +#ifdef PMAP_DEBUG + if (pmap_debug_level >= 0) + printf("kstack V%08lx P%08lx\n", kernelstack.pv_va, + kernelstack.pv_pa); +#endif /* PMAP_DEBUG */ + + /* + * 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. + * Initialization 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; +#ifdef DEBUG + printf("%08x %08x %08x\n", data_abort_handler_address, + prefetch_abort_handler_address, undefined_handler_address); +#endif + + /* Initialize the undefined instruction handlers */ +#ifdef VERBOSE_INIT_ARM + printf("undefined\n"); +#endif + undefined_init(); + + /* Set the page table address. */ +#ifdef VERBOSE_INIT_ARM + printf("switching to new L1 page table @%#lx...\n", kernel_l1pt.pv_pa); +#endif + cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT); + cpu_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. + */ + uvm_lwp_setuarea(&lwp0, kernelstack.pv_va); + +#ifdef BOOT_DUMP + dumppages((char *)0xc0000000, 16 * PAGE_SIZE); + dumppages((char *)0xb0100000, 64); /* XXX */ +#endif + + arm32_vector_init(ARM_VECTORS_LOW, ARM_VEC_ALL); + + consinit(); + +#ifdef VERBOSE_INIT_ARM + printf("bootstrap done.\n"); +#endif + +#ifdef VERBOSE_INIT_ARM + printf("freemempos=%08lx\n", freemempos); + printf("MMU enabled. control=%08x\n", cpu_get_control()); +#endif + + /* Load memory into UVM. */ + uvm_setpagesize(); /* initialize PAGE_SIZE-dependent variables */ + for (loop = 0; loop < bootconfig.dramblocks; loop++) { + paddr_t dblk_start = (paddr_t)bootconfig.dram[loop].address; + paddr_t dblk_end = dblk_start + + (bootconfig.dram[loop].pages * PAGE_SIZE); + + if (dblk_start < physical_freestart) + dblk_start = physical_freestart; + if (dblk_end > physical_freeend) + dblk_end = physical_freeend; + + uvm_page_physload(atop(dblk_start), atop(dblk_end), + atop(dblk_start), atop(dblk_end), VM_FREELIST_DEFAULT); + } + + /* Boot strap pmap telling it where the kernel page table is */ + pmap_bootstrap(KERNEL_VM_BASE, KERNEL_VM_BASE + KERNEL_VM_SIZE); + +#ifdef BOOT_DUMP + dumppages((char *)kernel_l1pt.pv_va, 16); +#endif + +#ifdef DDB + db_machine_init(); +#endif +#if NKSYMS || defined(DDB) || defined(MODULAR) + ksyms_addsyms_elf(symbolsize, ((int *)&end), ((char *)&end) + symbolsize); +#endif + + printf("kernsize=0x%x", kerneldatasize); + printf(" (including 0x%x symbols)\n", symbolsize); + +#ifdef DDB + if (boothowto & RB_KDB) + Debugger(); +#endif /* DDB */ + + /* We return the new stack pointer address */ + return (kernelstack.pv_va + USPACE_SVC_STACK_TOP); +} + +#if (NCOM > 0) && defined(COM_PXA2X0) +#ifndef CONSPEED +#define CONSPEED 9600 +#endif +#ifndef CONMODE +#define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */ +#endif + +int comcnspeed = CONSPEED; +int comcnmode = CONMODE; + +#if defined(HWUARTCONSOLE) +#define CONADDR PXA2X0_HWUART_BASE +#elsif defined(BTUARTCONSOLE) +#define CONADDR PXA2X0_BTUART_BASE +#elsif defined(STUARTCONSOLE) +#define CONADDR PXA2X0_STUART_BASE +#else +#define CONADDR PXA2X0_FFUART_BASE +#endif + +bus_addr_t comcnaddr = CONADDR; +#endif /* NCOM > 0 && COM_PXA2X0 */ + +void +consinit(void) +{ + static int consinit_called = 0; + + if (consinit_called != 0) + return; + + consinit_called = 1; + if (bootinfo->bi_cnuse == BI_CNUSE_SERIAL) { +#if (NCOM > 0) && defined(COM_PXA2X0) + comcnattach(&pxa2x0_a4x_bs_tag, comcnaddr, comcnspeed, + PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comcnmode); +#endif + } else { +#if (NLCD > 0) +#if NWZERO3LCD > 0 + if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS003SH) + || platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS004SH) + || platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS007SH) + || platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS011SH) + || platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS020SH)) { + extern void wzero3lcd_cnattach(void); + wzero3lcd_cnattach(); + } +#endif +#endif + } +} + +#ifdef DEBUG_BEFOREMMU +static void +fakecninit(void) +{ +#if (NCOM > 0) && defined(COM_PXA2X0) + comcnattach(&pxa2x0_a4x_bs_tag, comcnaddr, comcnspeed, + PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comcnmode); +#endif +} +#endif diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/arch/hpcarm/hpcarm/sa11x0_hpc_machdep.c src/sys/arch/hpcarm/hpcarm/sa11x0_hpc_machdep.c --- src.orig/sys/arch/hpcarm/hpcarm/sa11x0_hpc_machdep.c 1970-01-01 09:00:00.000000000 +0900 +++ src/sys/arch/hpcarm/hpcarm/sa11x0_hpc_machdep.c 2010-03-06 06:24:51.000000000 +0900 @@ -0,0 +1,690 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 1994-1998 Mark Brinicombe. + * Copyright (c) 1994 Brini. + * All rights reserved. + * + * This code is derived from software written for Brini by Mark Brinicombe + * + * 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 Brini. + * 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 BRINI ``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 BRINI 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 dependent functions for kernel setup. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD$"); + +#include "opt_ddb.h" +#include "opt_dram_pages.h" +#include "opt_modular.h" +#include "opt_pmap_debug.h" +#include "ksyms.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* XXX for consinit related hacks */ +#include +#include + +#if NKSYMS || defined(DDB) || defined(MODULAR) +#include +#include +#include +#ifndef DB_ELFSIZE +#error Must define DB_ELFSIZE! +#endif +#define ELFSIZE DB_ELFSIZE +#include +#endif + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +/* Kernel text starts 256K in from the bottom of the kernel address space. */ +#define KERNEL_TEXT_BASE (KERNEL_BASE + 0x00040000) +#define KERNEL_VM_BASE (KERNEL_BASE + 0x00C00000) +#define KERNEL_VM_SIZE 0x05000000 + +/* + * Address to call from cpu_reset() to reset the machine. + * This is machine architecture dependent 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 + +extern BootConfig bootconfig; /* Boot config storage */ +extern struct bootinfo *bootinfo, bootinfo_storage; +extern char booted_kernel_storage[80]; +extern char *booted_kernel; + +extern paddr_t physical_start; +extern paddr_t physical_freestart; +extern paddr_t physical_freeend; +extern paddr_t physical_end; +extern int physmem; + +/* Physical and virtual addresses for some global pages */ +extern pv_addr_t irqstack; +extern pv_addr_t undstack; +extern pv_addr_t abtstack; +extern pv_addr_t kernelstack; + +extern char *boot_args; +extern char boot_file[16]; + +extern vaddr_t msgbufphys; + +extern u_int data_abort_handler_address; +extern u_int prefetch_abort_handler_address; +extern u_int undefined_handler_address; +extern int end; + +#ifdef PMAP_DEBUG +extern int pmap_debug_level; +#endif /* PMAP_DEBUG */ + +#define KERNEL_PT_VMEM 0 /* Page table for mapping video memory */ +#define KERNEL_PT_SYS 1 /* Page table for mapping proc0 zero page */ +#define KERNEL_PT_IO 2 /* Page table for mapping IO */ +#define KERNEL_PT_KERNEL 3 /* 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]; + +#define CPU_SA110_CACHE_CLEAN_SIZE (0x4000 * 2) +extern unsigned int sa1_cache_clean_addr; +extern unsigned int sa1_cache_clean_size; +static vaddr_t sa1_cc_base; + +/* Non-buffered non-cacheable memory needed to enter idle mode */ +extern vaddr_t sa11x0_idle_mem; + +/* Prototypes */ +void data_abort_handler(trapframe_t *); +void prefetch_abort_handler(trapframe_t *); +void undefinedinstruction_bounce(trapframe_t *); +u_int cpu_get_control(void); + +u_int initarm(int, char **, struct bootinfo *); + +/* Mode dependent sleep function holder */ +extern void (*__sleep_func)(void *); +extern void *__sleep_ctx; + +/* Number of DRAM pages which are installed */ +/* Units are 4K pages, so 8192 is 32 MB of memory */ +#ifndef DRAM_PAGES +#define DRAM_PAGES 8192 +#endif + +/* + * 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. + */ +static const struct pmap_devmap sa11x0_devmap[] = { + /* Physical/virtual address for UART #3. */ + { + SACOM3_VBASE, + SACOM3_BASE, + 0x24, + VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE + }, + { 0, 0, 0, 0, 0 } +}; + +/* + * 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. + * Initializing the physical console so characters can be printed. + * Setting up page tables for the kernel. + */ +u_int +initarm(int argc, char **argv, struct bootinfo *bi) +{ + u_int kerneldatasize, symbolsize; + u_int l1pagetable; + vaddr_t freemempos; + vsize_t pt_size; + int loop, i; +#if NKSYMS || defined(DDB) || defined(MODULAR) + Elf_Shdr *sh; +#endif + + __sleep_func = NULL; + __sleep_ctx = NULL; + + /* parse kernel args */ + boothowto = 0; + boot_file[0] = '\0'; + strncpy(booted_kernel_storage, argv[0], sizeof(booted_kernel_storage)); + for (i = 1; i < argc; i++) { + char *cp = argv[i]; + + switch (*cp) { + case 'b': + /* boot device: -b=sd0 etc. */ + cp = cp + 2; + if (strcmp(cp, MOUNT_NFS) == 0) + rootfstype = MOUNT_NFS; + else + strncpy(boot_file, cp, sizeof(boot_file)); + break; + default: + BOOT_FLAG(*cp, boothowto); + break; + } + } + + /* copy bootinfo into known kernel space */ + bootinfo_storage = *bi; + bootinfo = &bootinfo_storage; + +#ifdef BOOTINFO_FB_WIDTH + bootinfo->fb_line_bytes = BOOTINFO_FB_LINE_BYTES; + bootinfo->fb_width = BOOTINFO_FB_WIDTH; + bootinfo->fb_height = BOOTINFO_FB_HEIGHT; + bootinfo->fb_type = BOOTINFO_FB_TYPE; +#endif + + if (bootinfo->magic == BOOTINFO_MAGIC) { + platid.dw.dw0 = bootinfo->platid_cpu; + platid.dw.dw1 = bootinfo->platid_machine; + } + + /* + * Heads up ... Setup the CPU / MMU / TLB functions. + */ + set_cpufuncs(); + IRQdisable; + +#ifdef DEBUG_BEFOREMMU + /* + * At this point, we cannot call real consinit(). + * Just call a faked up version of consinit(), which does the thing + * with MMU disabled. + */ + fakecninit(); +#endif + + /* + * XXX for now, overwrite bootconfig to hardcoded values. + * XXX kill bootconfig and directly call uvm_physload + */ + bootconfig.dram[0].address = 0xc0000000; + bootconfig.dram[0].pages = DRAM_PAGES; + bootconfig.dramblocks = 1; + + kerneldatasize = (uint32_t)&end - (uint32_t)KERNEL_TEXT_BASE; + symbolsize = 0; +#if NKSYMS || defined(DDB) || defined(MODULAR) + if (!memcmp(&end, "\177ELF", 4)) { + 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; + } +#endif + + printf("kernsize=0x%x\n", kerneldatasize); + kerneldatasize += symbolsize; + kerneldatasize = ((kerneldatasize - 1) & ~(PAGE_SIZE * 4 - 1)) + + PAGE_SIZE * 8; + + /* + * hpcboot has loaded me with MMU disabled. + * So create kernel page tables and enable MMU. + */ + + /* + * Set up the variables that define the availability of physcial + * memory. + */ + physical_start = bootconfig.dram[0].address; + physical_freestart = physical_start + + (KERNEL_TEXT_BASE - KERNEL_BASE) + kerneldatasize; + physical_end = bootconfig.dram[bootconfig.dramblocks - 1].address + + bootconfig.dram[bootconfig.dramblocks - 1].pages * PAGE_SIZE; + physical_freeend = physical_end; + + for (loop = 0; loop < bootconfig.dramblocks; ++loop) + physmem += bootconfig.dram[loop].pages; + + /* XXX handle UMA framebuffer memory */ + + /* Use the first 256kB to allocate things */ + freemempos = KERNEL_BASE; + memset((void *)KERNEL_BASE, 0, KERNEL_TEXT_BASE - KERNEL_BASE); + + /* + * Right. We have the bottom meg of memory mapped to 0x00000000 + * so was can get at it. The kernel will occupy the start of it. + * After the kernel/args we allocate some of the fixed page tables + * we need to get the system going. + * We allocate one page directory and NUM_KERNEL_PTS page tables + * and store the physical addresses in the kernel_pt_table array. + * Must remember that neither the page L1 or L2 page tables are the + * same size as a page ! + * + * Ok, the next bit of physical allocate may look complex but it is + * simple really. I have done it like this so that no memory gets + * wasted during the allocate of various pages and tables that are + * all different sizes. + * The start address will be page aligned. + * We allocate the kernel page directory on the first free 16KB + * boundary we find. + * We allocate the kernel page tables on the first 1KB boundary we + * find. We allocate at least 9 PT's (12 currently). This means + * that in the process we KNOW that we will encounter at least one + * 16KB boundary. + * + * Eventually if the top end of the memory gets used for process L1 + * page tables the kernel L1 page table may be moved up there. + */ + +#ifdef VERBOSE_INIT_ARM + printf("Allocating page tables\n"); +#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) \ + (var) = freemempos; \ + freemempos += (np) * PAGE_SIZE; + + valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE); + for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) { + alloc_pages(kernel_pt_table[loop].pv_pa, + L2_TABLE_SIZE / PAGE_SIZE); + kernel_pt_table[loop].pv_va = kernel_pt_table[loop].pv_pa; + } + + /* 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"); + + /* + * 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. + */ + valloc_pages(systempage, 1); + + pt_size = round_page(freemempos) - physical_start; + + /* 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); + + /* + * XXX Actually, we only need virtual space and don't need + * XXX physical memory for sa110_cc_base and sa11x0_idle_mem. + */ + /* + * XXX totally stuffed hack to work round problems introduced + * in recent versions of the pmap code. Due to the calls used there + * we cannot allocate virtual memory during bootstrap. + */ + for (;;) { + alloc_pages(sa1_cc_base, 1); + if (!(sa1_cc_base & (CPU_SA110_CACHE_CLEAN_SIZE - 1))) + break; + } + { + vaddr_t dummy; + alloc_pages(dummy, CPU_SA110_CACHE_CLEAN_SIZE / PAGE_SIZE - 1); + } + sa1_cache_clean_addr = sa1_cc_base; + sa1_cache_clean_size = CPU_SA110_CACHE_CLEAN_SIZE / 2; + + alloc_pages(sa11x0_idle_mem, 1); + + /* + * Ok, we have allocated physical pages for the primary kernel + * page tables. + */ + +#ifdef VERBOSE_INIT_ARM + printf("Creating L1 page table\n"); +#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]); +#define SAIPIO_BASE 0xd0000000 /* XXX XXX */ + pmap_link_l2pt(l1pagetable, SAIPIO_BASE, + &kernel_pt_table[KERNEL_PT_IO]); + 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 code/data */ + + /* + * XXX there is no ELF header to find RO region. + * XXX What should we do? + */ +#if 0 + if (N_GETMAGIC(kernexec[0]) == ZMAGIC) { + logical = pmap_map_chunk(l1pagetable, KERNEL_TEXT_BASE, + physical_start, kernexec->a_text, + VM_PROT_READ, PTE_CACHE); + logical += pmap_map_chunk(l1pagetable, + KERNEL_TEXT_BASE + logical, physical_start + logical, + kerneldatasize - kernexec->a_text, + VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); + } else +#endif + pmap_map_chunk(l1pagetable, KERNEL_TEXT_BASE, + KERNEL_TEXT_BASE - KERNEL_BASE + physical_start, + kerneldatasize, 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); + + /* Map page tables */ + pmap_map_chunk(l1pagetable, KERNEL_BASE, physical_start, pt_size, + VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE); + + /* Map a page for entering idle mode */ + pmap_map_entry(l1pagetable, sa11x0_idle_mem, sa11x0_idle_mem, + VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE); + + /* Map the vector page. */ + pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa, + VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); + + /* Map the statically mapped devices. */ + pmap_devmap_bootstrap(l1pagetable, sa11x0_devmap); + + pmap_map_chunk(l1pagetable, sa1_cache_clean_addr, 0xe0000000, + CPU_SA110_CACHE_CLEAN_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); + + /* + * 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. + */ + +#ifdef VERBOSE_INIT_ARM + printf("done.\n"); +#endif + + /* + * 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); +#ifdef PMAP_DEBUG + if (pmap_debug_level >= 0) + printf("kstack V%08lx P%08lx\n", kernelstack.pv_va, + kernelstack.pv_pa); +#endif /* PMAP_DEBUG */ + + /* + * 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. + * Initialization 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; +#ifdef DEBUG + printf("%08x %08x %08x\n", data_abort_handler_address, + prefetch_abort_handler_address, undefined_handler_address); +#endif + + /* Initialize the undefined instruction handlers */ +#ifdef VERBOSE_INIT_ARM + printf("undefined\n"); +#endif + undefined_init(); + + /* Set the page table address. */ +#ifdef VERBOSE_INIT_ARM + printf("switching to new L1 page table @%#lx...\n", kernel_l1pt.pv_pa); +#endif + cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT); + cpu_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. + */ + uvm_lwp_setuarea(&lwp0, kernelstack.pv_va); + +#ifdef BOOT_DUMP + dumppages((char *)0xc0000000, 16 * PAGE_SIZE); + dumppages((char *)0xb0100000, 64); /* XXX */ +#endif + /* Enable MMU, I-cache, D-cache, write buffer. */ + cpufunc_control(0x337f, 0x107d); + + arm32_vector_init(ARM_VECTORS_LOW, ARM_VEC_ALL); + + consinit(); + +#ifdef VERBOSE_INIT_ARM + printf("bootstrap done.\n"); +#endif + +#ifdef VERBOSE_INIT_ARM + printf("freemempos=%08lx\n", freemempos); + printf("MMU enabled. control=%08x\n", cpu_get_control()); +#endif + + /* Load memory into UVM. */ + uvm_setpagesize(); /* initialize PAGE_SIZE-dependent variables */ + for (loop = 0; loop < bootconfig.dramblocks; loop++) { + paddr_t dblk_start = (paddr_t)bootconfig.dram[loop].address; + paddr_t dblk_end = dblk_start + + (bootconfig.dram[loop].pages * PAGE_SIZE); + + if (dblk_start < physical_freestart) + dblk_start = physical_freestart; + if (dblk_end > physical_freeend) + dblk_end = physical_freeend; + + uvm_page_physload(atop(dblk_start), atop(dblk_end), + atop(dblk_start), atop(dblk_end), VM_FREELIST_DEFAULT); + } + + /* Boot strap pmap telling it where the kernel page table is */ + pmap_bootstrap(KERNEL_VM_BASE, KERNEL_VM_BASE + KERNEL_VM_SIZE); + +#ifdef BOOT_DUMP + dumppages((char *)kernel_l1pt.pv_va, 16); +#endif + +#ifdef DDB + db_machine_init(); +#endif +#if NKSYMS || defined(DDB) || defined(MODULAR) + ksyms_addsyms_elf(symbolsize, ((int *)&end), ((char *)&end) + symbolsize); +#endif + + printf("kernsize=0x%x", kerneldatasize); + printf(" (including 0x%x symbols)\n", symbolsize); + +#ifdef DDB + if (boothowto & RB_KDB) + Debugger(); +#endif /* DDB */ + + /* We return the new stack pointer address */ + return (kernelstack.pv_va + USPACE_SVC_STACK_TOP); +} + +void +consinit(void) +{ + static int consinit_called = 0; + + if (consinit_called != 0) + return; + + consinit_called = 1; + if (bootinfo->bi_cnuse == BI_CNUSE_SERIAL) { + cninit(); + } +} + +#ifdef DEBUG_BEFOREMMU +cons_decl(sacom); + +static void +fakecninit(void) +{ + static struct consdev fakecntab = cons_init(sacom); + cn_tab = &fakecntab; + + (*cn_tab->cn_init)(0); + cn_tab->cn_pri = CN_REMOTE; +} +#endif diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/arch/hpcarm/include/intr.h src/sys/arch/hpcarm/include/intr.h --- src.orig/sys/arch/hpcarm/include/intr.h 2008-04-29 11:38:35.000000000 +0900 +++ src/sys/arch/hpcarm/include/intr.h 2009-01-30 06:08:20.000000000 +0900 @@ -36,6 +36,8 @@ #ifndef _HPCARM_INTR_H_ #define _HPCARM_INTR_H_ +#ifdef _KERNEL + #ifdef __HAVE_FAST_SOFTINTS #define IPL_NONE 0 #define IPL_SOFTCLOCK 1 @@ -66,7 +68,110 @@ #define IST_EDGE 2 /* edge-triggered */ #define IST_LEVEL 3 /* level-triggered */ +#define IST_LEVEL_LOW IST_LEVEL +#define IST_LEVEL_HIGH 4 +#define IST_EDGE_FALLING IST_EDGE +#define IST_EDGE_RISING 5 +#define IST_EDGE_BOTH 6 + +#ifdef __OLD_INTERRUPT_CODE /* XXX XXX XXX */ + #include #include +#else /* !__OLD_INTERRUPT_CODE */ + +#define __NEWINTR /* enables new hooks in cpu_fork()/cpu_switch() */ + +#ifndef _LOCORE + +#include +#include + +#if defined(_LKM) + +int _splraise(int); +int _spllower(int); +void splx(int); +void _setsoftintr(int); + +#else /* _LKM */ + +#include "opt_arm_intr_impl.h" + +#if defined(ARM_INTR_IMPL) + +/* + * Each board needs to define the following functions: + * + * int _splraise(int); + * int _spllower(int); + * void splx(int); + * void _setsoftintr(int); + * + * These may be defined as functions, static inline functions, or macros, + * but there must be a _spllower() and splx() defined as functions callable + * from assembly language (for cpu_switch()). However, since it's quite + * useful to be able to inline splx(), you could do something like the + * following: + * + * in _intr.h: + * static inline int + * boardtype_splx(int spl) + * {...} + * + * #define splx(nspl) boardtype_splx(nspl) + * ... + * and in boardtype's machdep code: + * + * ... + * #undef splx + * int + * splx(int spl) + * { + * return boardtype_splx(spl); + * } + */ + +#include ARM_INTR_IMPL + +#else /* ARM_INTR_IMPL */ + +#error ARM_INTR_IMPL not defined. + +#endif /* ARM_INTR_IMPL */ + +#endif /* _LKM */ + +#define splsoft() _splraise(IPL_SOFT) + +typedef uint8_t ipl_t; +typedef struct { + ipl_t _ipl; +} ipl_cookie_t; + +static inline ipl_cookie_t +makeiplcookie(ipl_t ipl) +{ + + return (ipl_cookie_t){._ipl = ipl}; +} + +static inline int +splraiseipl(ipl_cookie_t icookie) +{ + + return _splraise(icookie._ipl); +} + +#define spl0() _spllower(IPL_NONE) + +#include + +#endif /* ! _LOCORE */ + +#endif /* __OLD_INTERRUPT_CODE */ + +#endif /* _KERNEL */ + #endif /* _HPCARM_INTR_H */ diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/sys/dev/hpc/hpckbdkeymap.h src/sys/dev/hpc/hpckbdkeymap.h --- src.orig/sys/dev/hpc/hpckbdkeymap.h 2008-04-29 11:40:15.000000000 +0900 +++ src/sys/dev/hpc/hpckbdkeymap.h 2009-04-23 08:59:36.000000000 +0900 @@ -831,6 +831,157 @@ [KEY_SPECIAL_OFF] = 127, [KEY_SPECIAL_LIGHT] = -1 }; + +/* + * Sharp W-ZERO3 series + */ +/* + * WS003SH/WS004SH/WS007SH keyscan map + CTRL (none) TAB (none) CALL MAIL IE + 1 2 q w a z MOJI + 3 4 e s d x (none) + 5 r t f c - OK + 6 y g v b SPACE ACTION + 7 8 u h n / , + 9 i j m . (none) LEFT + 0 o k l (none) UP DOWN + BS p (none) (none) ENTER (none) RIGHT + (none) (none) (none) (none) (none) (none) (none) + ROTATE VOL- (none) SHIFT WIN LSOFT RSOFT + CAMERA VOL+ (none) (none) (none) FN (none) +*/ +/* Japanese */ +const uint8_t ws003sh_jp_keytrans[] = { +/* row#0, row#1, row#2, row#3, row#4, row#5, row#6, */ +/*00*/ 29, UNK, 15, UNK, IGN, IGN, IGN, +/*01*/ 2, 3, 16, 17, 30, 44, 1, +/*02*/ 4, 5, 18, 31, 32, 45, UNK, +/*03*/ 6, 19, 20, 33, 46, 12, 28, +/*04*/ 7, 21, 34, 47, 48, 57, 28, +/*05*/ 8, 9, 22, 35, 49, 53, 51, +/*06*/ 10, 23, 36, 50, 52, UNK, 203, +/*07*/ 11, 24, 37, 38, UNK, 200, 208, +/*08*/ 14, 25, UNK, UNK, 28, UNK, 205, +/*09*/ UNK, UNK, UNK, UNK, UNK, UNK, UNK, +/*10*/ IGN, 174, UNK, 42, IGN, IGN, IGN, +/*11*/ IGN, 176, UNK, UNK, UNK, 184, SPL, +}; + +const int ws003sh_special_keymap[] = { + [KEY_SPECIAL_OFF] = 83, + [KEY_SPECIAL_LIGHT] = -1 +}; + +static const keysym_t ws003sh_jp_keydesc[] = { +/* pos normal shifted altgr */ + KC(4), KS_3, KS_numbersign, KS_Cmd_BrightnessDown, + KC(5), KS_4, KS_dollar, KS_Cmd_BrightnessUp, + KC(8), KS_7, KS_apostrophe, KS_grave, + KC(9), KS_8, KS_parenleft, KS_braceleft, + KC(10), KS_9, KS_parenright, KS_braceright, + KC(12), KS_minus, KS_equal, KS_backslash, + KC(14), KS_Delete, KS_Delete, KS_BackSpace, + KC(15), KS_Tab, KS_Tab, KS_Escape, + KC(17), KS_w, KS_W, KS_asciicircum, + KC(18), KS_e, KS_E, KS_asciitilde, + KC(19), KS_r, KS_R, KS_bar, + KC(22), KS_u, KS_U, KS_bracketleft, + KC(23), KS_i, KS_I, KS_bracketright, + KC(24), KS_o, KS_O, KS_underscore, + KC(25), KS_p, KS_P, KS_at, + KC(37), KS_k, KS_K, KS_plus, + KC(38), KS_l, KS_L, KS_asterisk, + KC(42), KS_Shift_L, KS_Shift_L, KS_Shift_Lock, + KC(51), KS_comma, KS_semicolon, KS_less, + KC(52), KS_period, KS_colon, KS_greater, + KC(184), KS_Mode_switch, KS_Multi_key, + KC(200), KS_Up, KS_Up, KS_Prior, + KC(203), KS_Left, KS_Left, KS_Home, + KC(205), KS_Right, KS_Right, KS_End, + KC(208), KS_Down, KS_Down, KS_Next, +}; + +/* + * WS011SH/WS020SH keyscan map + Ctrl (none) Tab (none) (none) (none) (none) + (none) (none) Q W A Z MOJI + (none) (none) E S D X HAN/ZEN + (none) R T F C - OK + (none) Y G V B Space (none) + (none) (none) U H N / , + (none) I J M . (none) LEFT + (none) O K L (none) UP DOWN + Del (none) (none) (none) Enter (none) RIGHT + (none) (none) (none) (none) (none) (none) (none) + ROTATE (none) (none) SHIFT (none) (none) (none) + (none) (none) (none) (none) (none) FN (none) +*/ +/* Japanese */ +const uint8_t ws011sh_jp_keytrans[] = { +/* row#0, row#1, row#2, row#3, row#4, row#5, row#6, */ +/*00*/ 29, UNK, 15, UNK, UNK, UNK, UNK, +/*01*/ UNK, UNK, 16, 17, 30, 44, 1, +/*02*/ UNK, UNK, 18, 31, 32, 45, 41, +/*03*/ UNK, 19, 20, 33, 46, 12, 3, +/*04*/ UNK, 21, 34, 47, 48, 57, UNK, +/*05*/ UNK, UNK, 22, 35, 49, 53, 51, +/*06*/ UNK, 23, 36, 50, 52, UNK, 203, +/*07*/ UNK, 24, 37, 38, UNK, 200, 208, +/*08*/ 14, 25, UNK, UNK, 28, UNK, 205, +/*09*/ UNK, UNK, UNK, UNK, UNK, UNK, UNK, +/*10*/ IGN, UNK, UNK, 42, UNK, UNK, UNK, +/*11*/ UNK, UNK, UNK, UNK, UNK, 184, SPL, +}; + +const int ws011sh_special_keymap[] = { + [KEY_SPECIAL_OFF] = 83, + [KEY_SPECIAL_LIGHT] = -1 +}; + +static const keysym_t ws011sh_jp_keydesc[] = { +/* pos normal shifted altgr */ + KC(3), KS_grave, KS_braceleft, KS_braceright, + KC(12), KS_minus, KS_equal, KS_backslash, + KC(14), KS_Delete, KS_Delete, KS_BackSpace, + KC(15), KS_Tab, KS_Tab, KS_Escape, + KC(16), KS_q, KS_Q, KS_quotedbl, + KC(17), KS_w, KS_W, KS_numbersign, + KC(18), KS_e, KS_E, KS_dollar, + KC(19), KS_r, KS_R, KS_percent, + KC(20), KS_t, KS_T, KS_ampersand, + KC(21), KS_y, KS_Y, KS_1, + KC(22), KS_u, KS_U, KS_2, + KC(23), KS_i, KS_I, KS_3, + KC(24), KS_o, KS_O, KS_underscore, + KC(25), KS_p, KS_P, KS_at, + KC(30), KS_a, KS_A, KS_bracketleft, + KC(31), KS_s, KS_S, KS_apostrophe, + KC(32), KS_d, KS_D, KS_parenleft, + KC(33), KS_f, KS_F, KS_parenright, + KC(34), KS_g, KS_G, KS_asterisk, + KC(35), KS_h, KS_H, KS_4, + KC(36), KS_j, KS_J, KS_5, + KC(37), KS_k, KS_K, KS_6, + KC(38), KS_l, KS_L, KS_plus, + KC(41), KS_Zenkaku_Hankaku, KS_Zenkaku_Hankaku, KS_exclam, + KC(42), KS_Shift_L, KS_Shift_L, KS_Shift_Lock, + KC(44), KS_z, KS_Z, KS_bracketright, + KC(45), KS_x, KS_X, KS_asciicircum, + KC(46), KS_c, KS_C, KS_asciitilde, + KC(47), KS_v, KS_V, KS_bar, + KC(48), KS_b, KS_B, KS_7, + KC(49), KS_n, KS_N, KS_8, + KC(50), KS_m, KS_M, KS_9, + KC(51), KS_comma, KS_less, KS_semicolon, + KC(52), KS_period, KS_greater, KS_colon, + KC(53), KS_slash, KS_question, KS_0, + KC(57), KS_space, + KC(184), KS_Mode_switch, KS_Multi_key, + KC(200), KS_Up, KS_Up, KS_Prior, + KC(203), KS_Left, KS_Left, KS_Home, + KC(205), KS_Right, KS_Right, KS_End, + KC(208), KS_Down, KS_Down, KS_Next, +}; #endif /* hpcarm */ #if defined(hpcarm) || defined(hpcsh) @@ -1227,6 +1378,9 @@ #endif /* hpcsh */ #ifdef hpcarm + /* + * HP Jornada 710/720/728 + */ /* US (ABA), UK (ABU) */ { &platid_mask_MACH_HP_JORNADA_720, jornada7xx_us_keytrans, @@ -1269,6 +1423,39 @@ jornada7xx_special_keymap, CMDMAP(jornada_es_keydesc), KB_ES }, + /* + * Sharp W-ZERO3 + */ + /* WS003SH */ + { &platid_mask_MACH_SHARP_WZERO3_WS003SH, + ws003sh_jp_keytrans, + ws003sh_special_keymap, + CMDMAP(ws003sh_jp_keydesc), + KB_JP }, + /* WS004SH */ + { &platid_mask_MACH_SHARP_WZERO3_WS004SH, + ws003sh_jp_keytrans, + ws003sh_special_keymap, + CMDMAP(ws003sh_jp_keydesc), + KB_JP }, + /* WS007SH */ + { &platid_mask_MACH_SHARP_WZERO3_WS007SH, + ws003sh_jp_keytrans, + ws003sh_special_keymap, + CMDMAP(ws003sh_jp_keydesc), + KB_JP }, + /* WS011SH */ + { &platid_mask_MACH_SHARP_WZERO3_WS011SH, + ws011sh_jp_keytrans, + ws011sh_special_keymap, + CMDMAP(ws011sh_jp_keydesc), + KB_JP }, + /* WS020SH */ + { &platid_mask_MACH_SHARP_WZERO3_WS020SH, + ws011sh_jp_keytrans, + ws011sh_special_keymap, + CMDMAP(ws011sh_jp_keydesc), + KB_JP }, #endif /* hpcarm */ { .ht_platform = NULL } /* end mark */ diff --exclude=CVS --exclude='obj.*' --exclude=compile -uNr src.orig/distrib/hpcarm/instkernel/Makefile src/distrib/hpcarm/instkernel/Makefile --- src.orig/distrib/hpcarm/instkernel/Makefile 2008-04-27 11:39:04.000000000 +0900 +++ src/distrib/hpcarm/instkernel/Makefile 2009-01-30 06:47:30.000000000 +0900 @@ -8,7 +8,8 @@ MINIROOTOBJ!= cd ${DISTRIBDIR}/miniroot && ${PRINTOBJDIR} MINIROOT= ${MINIROOTOBJ}/miniroot.fs -MDSETTARGETS= INSTALL_IPAQ ${MINIROOT} netbsd-IPAQ +MDSETTARGETS= INSTALL_IPAQ ${MINIROOT} netbsd-IPAQ \ + INSTALL_WZERO3 ${MINIROOT} netbsd-WZERO3 MDSET_RELEASEDIR= installation .include "${DISTRIBDIR}/common/Makefile.mdset"