summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/hppa64/Makefile34
-rw-r--r--sys/arch/hppa64/compile/.cvsignore2
-rw-r--r--sys/arch/hppa64/conf/GENERIC176
-rw-r--r--sys/arch/hppa64/conf/Makefile.hppa64191
-rw-r--r--sys/arch/hppa64/conf/RAMDISK199
-rw-r--r--sys/arch/hppa64/conf/files.hppa64133
-rw-r--r--sys/arch/hppa64/conf/ld.script88
-rw-r--r--sys/arch/hppa64/dev/apic.c132
-rw-r--r--sys/arch/hppa64/dev/clock.c43
-rw-r--r--sys/arch/hppa64/dev/cpu.c139
-rw-r--r--sys/arch/hppa64/dev/elroy.c1181
-rw-r--r--sys/arch/hppa64/dev/elroyreg.h146
-rw-r--r--sys/arch/hppa64/dev/elroyvar.h50
-rw-r--r--sys/arch/hppa64/dev/mem.c268
-rw-r--r--sys/arch/hppa64/dev/pdc.c469
-rw-r--r--sys/arch/hppa64/dev/pluto.c145
-rw-r--r--sys/arch/hppa64/dev/power.c142
-rw-r--r--sys/arch/hppa64/hppa64/autoconf.c843
-rw-r--r--sys/arch/hppa64/hppa64/conf.c284
-rw-r--r--sys/arch/hppa64/hppa64/db_disasm.c2353
-rw-r--r--sys/arch/hppa64/hppa64/db_interface.c320
-rw-r--r--sys/arch/hppa64/hppa64/disksubr.c986
-rw-r--r--sys/arch/hppa64/hppa64/genassym.cf142
-rw-r--r--sys/arch/hppa64/hppa64/in_cksum.c125
-rw-r--r--sys/arch/hppa64/hppa64/locore.S1879
-rw-r--r--sys/arch/hppa64/hppa64/machdep.c1200
-rw-r--r--sys/arch/hppa64/hppa64/mainbus.c661
-rw-r--r--sys/arch/hppa64/hppa64/pmap.c1216
-rw-r--r--sys/arch/hppa64/hppa64/process_machdep.c116
-rw-r--r--sys/arch/hppa64/hppa64/sys_machdep.c58
-rw-r--r--sys/arch/hppa64/hppa64/trap.c723
-rw-r--r--sys/arch/hppa64/hppa64/vm_machdep.c307
-rw-r--r--sys/arch/hppa64/hppa64/wscons_machdep.c81
-rw-r--r--sys/arch/hppa64/include/ansi.h79
-rw-r--r--sys/arch/hppa64/include/asm.h70
-rw-r--r--sys/arch/hppa64/include/autoconf.h53
-rw-r--r--sys/arch/hppa64/include/bus.h410
-rw-r--r--sys/arch/hppa64/include/cdefs.h39
-rw-r--r--sys/arch/hppa64/include/conf.h38
-rw-r--r--sys/arch/hppa64/include/cpu.h303
-rw-r--r--sys/arch/hppa64/include/db_machdep.h107
-rw-r--r--sys/arch/hppa64/include/disklabel.h375
-rw-r--r--sys/arch/hppa64/include/endian.h28
-rw-r--r--sys/arch/hppa64/include/exec.h113
-rw-r--r--sys/arch/hppa64/include/float.h76
-rw-r--r--sys/arch/hppa64/include/frame.h113
-rw-r--r--sys/arch/hppa64/include/ieee.h137
-rw-r--r--sys/arch/hppa64/include/ieeefp.h24
-rw-r--r--sys/arch/hppa64/include/internal_types.h7
-rw-r--r--sys/arch/hppa64/include/iomod.h3
-rw-r--r--sys/arch/hppa64/include/kcore.h28
-rw-r--r--sys/arch/hppa64/include/limits.h55
-rw-r--r--sys/arch/hppa64/include/loadfile_machdep.h83
-rw-r--r--sys/arch/hppa64/include/nvm.h74
-rw-r--r--sys/arch/hppa64/include/param.h131
-rw-r--r--sys/arch/hppa64/include/pcb.h44
-rw-r--r--sys/arch/hppa64/include/pci_machdep.h82
-rw-r--r--sys/arch/hppa64/include/pdc.h3
-rw-r--r--sys/arch/hppa64/include/pmap.h117
-rw-r--r--sys/arch/hppa64/include/proc.h43
-rw-r--r--sys/arch/hppa64/include/profile.h45
-rw-r--r--sys/arch/hppa64/include/psl.h94
-rw-r--r--sys/arch/hppa64/include/pte.h68
-rw-r--r--sys/arch/hppa64/include/ptrace.h27
-rw-r--r--sys/arch/hppa64/include/rbus_machdep.h34
-rw-r--r--sys/arch/hppa64/include/reg.h93
-rw-r--r--sys/arch/hppa64/include/reloc.h123
-rw-r--r--sys/arch/hppa64/include/setjmp.h7
-rw-r--r--sys/arch/hppa64/include/signal.h57
-rw-r--r--sys/arch/hppa64/include/spinlock.h10
-rw-r--r--sys/arch/hppa64/include/stdarg.h62
-rw-r--r--sys/arch/hppa64/include/trap.h91
-rw-r--r--sys/arch/hppa64/include/types.h81
-rw-r--r--sys/arch/hppa64/include/varargs.h17
-rw-r--r--sys/arch/hppa64/include/vmparam.h105
-rw-r--r--sys/arch/hppa64/stand/Makefile11
-rw-r--r--sys/arch/hppa64/stand/Makefile.inc44
-rw-r--r--sys/arch/hppa64/stand/boot/Makefile60
-rw-r--r--sys/arch/hppa64/stand/boot/boot.8342
-rw-r--r--sys/arch/hppa64/stand/boot/conf.c51
-rw-r--r--sys/arch/hppa64/stand/boot/exec.c42
-rw-r--r--sys/arch/hppa64/stand/boot/ld.script61
-rw-r--r--sys/arch/hppa64/stand/boot/srt0.S181
-rw-r--r--sys/arch/hppa64/stand/cdboot/Makefile55
-rw-r--r--sys/arch/hppa64/stand/cdboot/cdboot.c82
-rw-r--r--sys/arch/hppa64/stand/cdboot/ld.script49
-rw-r--r--sys/arch/hppa64/stand/libkern/Makefile29
-rw-r--r--sys/arch/hppa64/stand/libsa/Makefile43
-rw-r--r--sys/arch/hppa64/stand/libsa/cmd_hppa64.c819
-rw-r--r--sys/arch/hppa64/stand/libsa/ct.c71
-rw-r--r--sys/arch/hppa64/stand/libsa/dev_hppa64.c228
-rw-r--r--sys/arch/hppa64/stand/libsa/dev_hppa64.h43
-rw-r--r--sys/arch/hppa64/stand/libsa/dk.c101
-rw-r--r--sys/arch/hppa64/stand/libsa/itecons.c212
-rw-r--r--sys/arch/hppa64/stand/libsa/lf.c44
-rw-r--r--sys/arch/hppa64/stand/libsa/libsa.h72
-rw-r--r--sys/arch/hppa64/stand/libsa/lif.c261
-rw-r--r--sys/arch/hppa64/stand/libsa/machdep.c75
-rw-r--r--sys/arch/hppa64/stand/libsa/pdc.c448
-rw-r--r--sys/arch/hppa64/stand/libsa/time.c47
-rw-r--r--sys/arch/hppa64/stand/libz/Makefile10
-rw-r--r--sys/arch/hppa64/stand/mkboot/Makefile14
-rw-r--r--sys/arch/hppa64/stand/mkboot/mkboot.858
-rw-r--r--sys/arch/hppa64/stand/mkboot/mkboot.c430
104 files changed, 22364 insertions, 0 deletions
diff --git a/sys/arch/hppa64/Makefile b/sys/arch/hppa64/Makefile
new file mode 100644
index 00000000000..bb151360666
--- /dev/null
+++ b/sys/arch/hppa64/Makefile
@@ -0,0 +1,34 @@
+# $OpenBSD: Makefile,v 1.1 2005/04/01 10:40:46 mickey Exp $
+
+# Makefile for hppa64 tags file and boot blocks
+
+S=${.CURDIR}/../..
+.include "$S/kern/Make.tags.inc"
+
+NOPROG= noprog
+NOMAN= noman
+
+SUBDIR= stand
+
+THPPA= $S/arch/hppa64/tags
+SHPPA= $S/arch/hppa64/hppa64/*.[ch] $S/arch/hppa64/include/*.h \
+ $S/arch/hppa64/dev/*.[ch]
+AHPPA= $S/arch/hppa64/hppa64/*.S $S/lib/libkern/arch/hppa64/*.[sS]
+
+# Directories in which to place hppa64 tags links
+DHPPA= conf dev hppa64 include
+
+tags:
+ -ctags -wdtf ${THPPA} ${COMM} ${SHPPA}
+ egrep "^ENTRY(.*)|^ALTENTRY(.*)" ${AHPPA} | \
+ sed "s;\([^:]*\):\([^(]*\)(\([^, )]*\)\(.*\);\3 \1 /^\2(\3\4$$/;" \
+ >> ${THPPA}
+ sort -o ${THPPA} ${THPPA}
+
+links:
+ -for i in ${DHPPA}; do \
+ cd $$i && rm -f tags; ln -s ${THPPA} tags; done
+
+obj: _SUBDIRUSE
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/hppa64/compile/.cvsignore b/sys/arch/hppa64/compile/.cvsignore
new file mode 100644
index 00000000000..b72af3039e6
--- /dev/null
+++ b/sys/arch/hppa64/compile/.cvsignore
@@ -0,0 +1,2 @@
+GENERIC
+RAMDISK
diff --git a/sys/arch/hppa64/conf/GENERIC b/sys/arch/hppa64/conf/GENERIC
new file mode 100644
index 00000000000..db3760bcc32
--- /dev/null
+++ b/sys/arch/hppa64/conf/GENERIC
@@ -0,0 +1,176 @@
+# $OpenBSD: GENERIC,v 1.1 2005/04/01 10:40:47 mickey Exp $
+
+# Machine architecture; required by config(8)
+machine hppa64
+
+include "../../../conf/GENERIC"
+option DEBUG
+
+option USER_PCICONF # user-space PCI configuration
+
+# Need to set locally
+maxusers 32
+
+option TIMEZONE=0 # time zone to adjust RTC time by
+option DST=0 # daylight saving time used by RTC
+
+#option COMPAT_HPUX
+#option COMPAT_LINUX
+
+config bsd swap generic
+
+mainbus0 at root # root bus
+
+mem* at mainbus0 flags 0x00 # /dev/*mem and memory controller
+pdc0 at mainbus0 # PDC/IODC wrapper for boot console
+#power0 at mainbus0 # power/fail manager (iv 30)
+cpu* at mainbus0 # HP PA-RISC cpu
+plut0 at mainbus0 # Astro Runway-Ropes, MIOC and IOA
+
+elroy* at plut0
+pci* at elroy?
+option PCIVERBOSE
+
+ppb* at pci?
+pci* at ppb?
+
+#goofy* at pci? # NS87560UBD
+#com* at goofy?
+#lpt* at goofy?
+#fdc* at goofy?
+
+# CardBus bus support
+#cbb* at pci?
+#cardslot* at cbb?
+#option CARDBUS_DEBUG,CARDSLOT_DEBUG,CARDBUS_MAP_DEBUG
+#cardbus* at cardslot?
+#option PCMCIADEBUG,PCMCIAVERBOSE
+#pcmcia* at cardslot?
+
+# PCI USB Controllers
+#ehci* at pci? # Enhanced Host Controller
+#uhci* at pci? # Universal Host Controller (Intel)
+#ohci* at pci? # Open Host Controller
+
+# USB bus support
+#usb* at ehci?
+#usb* at uhci?
+#usb* at ohci?
+
+# USB devices
+#uhub* at usb? # USB Hubs
+#uhub* at uhub? # USB Hubs
+#umodem* at uhub? # USB Modems/Serial
+#ucom* at umodem?
+#uvisor* at uhub? # Handspring Visor
+#ucom* at uvisor?
+#uvscom* at uhub? # SUNTAC Slipper U VS-10U serial
+#ucom* at uvscom?
+#ubsa* at uhub? # Belkin serial adapter
+#ucom* at ubsa?
+#uftdi* at uhub? # FTDI FT8U100AX serial adapter
+#ucom* at uftdi?
+#uplcom* at uhub? # I/O DATA USB-RSAQ2 serial adapter
+#ucom* at uplcom?
+#umct* at uhub? # MCT USB-RS232 serial adapter
+#ucom* at umct?
+#uaudio* at uhub? # USB Audio
+#audio* at uaudio?
+#umidi* at uhub? # USB MIDI
+#midi* at umidi?
+#ulpt* at uhub? # USB Printers
+#umass* at uhub? # USB Mass Storage devices
+#scsibus* at umass?
+#uhidev* at uhub? # Human Interface Devices
+#ums* at uhidev? # USB mouse
+#wsmouse* at ums? mux 0
+#ukbd* at uhidev? # USB keyboard
+#wskbd* at ukbd? mux 1
+#uhid* at uhidev? # USB generic HID support
+#aue* at uhub? # ADMtek AN986 Pegasus Ethernet
+#axe* at uhub? # ASIX Electronics AX88172 USB Ethernet
+#cue* at uhub? # CATC USB-EL1201A based Ethernet
+#kue* at uhub? # Kawasaki KL5KUSB101B based Ethernet
+#cdce* at uhub? # CDC Ethernet
+#udav* at uhub? # Davicom DM9601 based Ethernet
+#upl* at uhub? # Prolific PL2301/PL2302 host-to-host `network'
+#url* at uhub? # Realtek RTL8150L based adapters
+#wi* at uhub? # WaveLAN IEEE 802.11DS
+#urio* at uhub? # Diamond Multimedia Rio 500
+#uscanner* at uhub? # USB Scanners
+#usscanner* at uhub? # USB SCSI scanners, e.g., HP5300
+#scsibus* at usscanner?
+#uyap* at uhub? # Y@P firmware loader
+#udsbr* at uhub? # D-Link DSB-R100 radio
+#radio* at udsbr? # USB radio
+#ugen* at uhub? # USB Generic driver
+
+#sti* at pci? # EG-PCI, FX*
+#wsdisplay* at sti?
+
+#com* at pcmcia? # PCMCIA modems
+
+#ie* at pci?
+
+#siop* at pci? # NCR 538XX SCSI controllers(new)
+#scsibus* at siop?
+#ahd* at pci? # Adaptec 79?? SCSI controllers
+#scsibus* at ahd?
+
+#em* at pci? # Intel Pro/1000 ethernet
+#ti* at pci? # Alteon Tigon 1Gb ethernet
+#txp* at pci? # 3com 3CR990
+#fpa* at pci? # DEC DEFPA FDDI
+dc* at pci? # 21143, "tulip" clone ethernet
+#dc* at cardbus?
+#rl* at pci? # RealTek 81[23]9 ethernet
+#rl* at cardbus?
+#ep* at pci? # 3c59x
+#ep* at cardbus?
+#xl* at pci? # 3C9xx ethernet
+#xl* at cardbus?
+#fxp* at pci? # EtherExpress 10/100B ethernet
+#fxp* at cardbus?
+#ne* at pci? # NE2000-compatible Ethernet
+#ne* at pcmcia?
+#an* at pci? # Cisco/Aironet 802.11DS
+#an* at pcmcia?
+#wi* at pci? # WaveLAN IEEE 802.11DS
+#wi* at pcmcia?
+
+dcphy* at mii? # Digital Clone PHYs
+#amphy* at mii? # AMD 79C873 PHYs
+#exphy* at mii? # 3Com internal PHYs
+#inphy* at mii? # Intel 82555 PHYs
+#iophy* at mii? # Intel 82553 PHYs
+#icsphy* at mii? # ICS1890 PHYs
+lxtphy* at mii? # Level One LXT-970 PHYs
+nsphy* at mii? # NS83840 PHYs
+#nsphyter* at mii? # NS83843 PHYs
+#mtdphy* at mii? # Myson MTD972 PHYs
+#qsphy* at mii? # Quality Semi QS6612 PHYs
+#sqphy* at mii? # Seeq 8022[013] PHYs
+#tlphy* at mii? # ThunderLAN PHYs
+#tqphy* at mii? # TDK Semiconductor PHYs
+#brgphy* at mii? # Broadcom 10/100/1000 PHYs
+#bmtphy* at mii? # Broadcom 10/100 PHYs
+#eephy* at mii? # Marvell 88E1000 Gigabit PHYs
+ukphy* at mii? # generic unknown PHYs
+
+#pciide* at pci? flags 0x0000
+#wdc* at pcmcia?
+#wd* at wdc? flags 0x0000
+#wd* at pciide? flags 0x0000
+#atapiscsi* at pciide?
+#scsibus* at atapiscsi?
+
+# These entries find devices on all SCSI busses and assign
+# unit numers dynamically.
+#sd* at scsibus?
+#st* at scsibus?
+#cd* at scsibus?
+#ch* at scsibus?
+#ss* at scsibus?
+#uk* at scsibus?
+
+#pseudo-device wsmux 2 # mouse and keyboard multiplexor
diff --git a/sys/arch/hppa64/conf/Makefile.hppa64 b/sys/arch/hppa64/conf/Makefile.hppa64
new file mode 100644
index 00000000000..8091bba9c26
--- /dev/null
+++ b/sys/arch/hppa64/conf/Makefile.hppa64
@@ -0,0 +1,191 @@
+# $OpenBSD: Makefile.hppa64,v 1.1 2005/04/01 10:40:47 mickey Exp $
+
+# Makefile for OpenBSD
+#
+# This makefile is constructed from a machine description:
+# config machineid
+# Most changes should be made in the machine description
+# /sys/arch/hppa64/conf/``machineid''
+# after which you should do
+# config machineid
+# Machine generic makefile changes should be made in
+# /sys/arch/hppa64/conf/Makefile.hppa64
+# after which config should be rerun for all machines of that type.
+#
+# N.B.: NO DEPENDENCIES ON FOLLOWING FLAGS ARE VISIBLE TO MAKEFILE
+# IF YOU CHANGE THE DEFINITION OF ANY OF THESE RECOMPILE EVERYTHING
+#
+# -DTRACE compile in kernel tracing hooks
+# -DQUOTA compile in file system quotas
+
+# DEBUG is set to -g if debugging.
+# PROF is set to -pg if profiling.
+
+.include <bsd.own.mk>
+
+MKDEP?= mkdep
+SIZE?= size
+STRIP?= strip
+
+# source tree is located via $S relative to the compilation directory
+.ifndef S
+S!= cd ../../../..; pwd
+.endif
+HPPA= $S/arch/hppa64
+
+INCLUDES= -I. -I$S/arch -I$S -nostdinc
+CPPFLAGS= ${INCLUDES} ${IDENT} ${PARAM} -D_KERNEL \
+ -Dhppa64
+CWARNFLAGS= -Werror -Wall -Wstrict-prototypes -Wno-uninitialized \
+ -Wno-format -Wno-main
+CMACHFLAGS= -fno-stack-protector -fno-builtin-log -fno-builtin-printf \
+ -fno-builtin-snprintf -fno-builtin-vsnprintf
+COPTS?= -Os -mpa-risc-2-0 -mno-space-regs -mdisable-fpregs
+CFLAGS= ${DEBUG} ${COPTS} ${CWARNFLAGS} ${CMACHFLAGS} ${PIPE}
+AFLAGS= -x assembler-with-cpp -traditional-cpp -D_LOCORE
+LINKFLAGS= -X -T ${HPPA}/conf/ld.script -Ttext 80000 --warn-common
+STRIPFLAGS= -g -x
+
+.if ${IDENT:M-DDDB} != ""
+CFLAGS+= -fno-omit-frame-pointer
+.endif
+
+HOSTCC?= ${CC}
+HOSTED_CPPFLAGS=${CPPFLAGS:S/^-nostdinc$//}
+HOSTED_CFLAGS= ${CFLAGS}
+
+# this line must be there because libkern needs assym.h generated early
+depend:: .NOTMAIN .depend
+
+### find out what to use for libkern
+.include "$S/lib/libkern/Makefile.inc"
+.ifndef PROF
+LIBKERN= ${KERNLIB}
+.else
+LIBKERN= ${KERNLIB_PROF}
+.endif
+
+### find out what to use for libcompat
+.include "$S/compat/common/Makefile.inc"
+.ifndef PROF
+LIBCOMPAT= ${COMPATLIB}
+.else
+LIBCOMPAT= ${COMPATLIB_PROF}
+.endif
+
+# compile rules: rules are named ${TYPE}_${SUFFIX} where TYPE is NORMAL or
+# HOSTED}, and SUFFIX is the file suffix, capitalized (e.g. C for a .c file).
+
+NORMAL_C= ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c $<
+NORMAL_S= ${CC} ${AFLAGS} ${CPPFLAGS} -c $<
+
+HOSTED_C= ${HOSTCC} ${HOSTED_CFLAGS} ${HOSTED_CPPFLAGS} -c $<
+
+%OBJS
+
+%CFILES
+
+%SFILES
+
+SYSTEM_OBJ= locore.o param.o ioconf.o ${OBJS} \
+ ${LIBKERN} ${LIBCOMPAT} ${LIBSPMATH}
+SYSTEM_DEP= Makefile ${SYSTEM_OBJ}
+SYSTEM_LD_HEAD= @rm -f $@
+SYSTEM_LD= @echo ${LD} ${LINKFLAGS} -o $@ '$${SYSTEM_OBJ}' vers.o; \
+ ${LD} ${LINKFLAGS} -o $@ ${SYSTEM_OBJ} vers.o
+SYSTEM_LD_TAIL= @${SIZE} $@; chmod 755 $@
+
+DEBUG?=
+.if ${DEBUG} == "-g"
+SYSTEM_LD_TAIL+=; \
+ echo cp $@ $@.gdb; rm -f $@.gdb; cp $@ $@.gdb; \
+ echo ${STRIP} ${STRIPFLAGS} $@; ${STRIP} ${STRIPFLAGS} $@
+.else
+LINKFLAGS+= -S
+.endif
+
+%LOAD
+
+assym.h: $S/kern/genassym.sh ${HPPA}/hppa64/genassym.cf Makefile
+ sh $S/kern/genassym.sh ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} \
+ < ${HPPA}/hppa64/genassym.cf > assym.h.tmp && \
+ mv -f assym.h.tmp assym.h
+
+param.c: $S/conf/param.c
+ rm -f param.c
+ cp $S/conf/param.c .
+
+param.o: param.c Makefile
+ ${NORMAL_C}
+
+ioconf.o: ioconf.c
+ ${NORMAL_C}
+
+newvers: ${SYSTEM_DEP} ${SYSTEM_SWAP_DEP}
+ sh $S/conf/newvers.sh
+ ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c vers.c
+
+
+clean::
+ rm -f eddep *bsd bsd.map bsd.gdb tags *.[io] [a-z]*.s \
+ [Ee]rrs linterrs makelinks assym.h
+
+lint:
+ @lint -hbxncez -DGENERIC -Dvolatile= ${CPPFLAGS} -UKGDB \
+ ${CFILES} ioconf.c param.c | \
+ grep -v 'static function .* unused'
+
+tags:
+ @echo "see $S/kern/Makefile for tags"
+
+links:
+ egrep '#if' ${CFILES} | sed -f $S/conf/defines | \
+ sed -e 's/:.*//' -e 's/\.c/.o/' | sort -u > dontlink
+ echo ${CFILES} | tr -s ' ' '\12' | sed 's/\.c/.o/' | \
+ sort -u | comm -23 - dontlink | \
+ sed 's,../.*/\(.*.o\),rm -f \1; ln -s ../GENERIC/\1 \1,' > makelinks
+ sh makelinks && rm -f dontlink
+
+SRCS= ${HPPA}/hppa64/locore.S \
+ param.c ioconf.c ${CFILES} ${SFILES}
+.depend: ${SRCS} assym.h param.c
+ ${MKDEP} ${AFLAGS} ${CPPFLAGS} ${HPPA}/hppa64/locore.S
+ ${MKDEP} -a ${CFLAGS} ${CPPFLAGS} param.c ioconf.c ${CFILES}
+ -if test -n "${SFILES}"; then \
+ ${MKDEP} -a ${AFLAGS} ${CPPFLAGS} ${SFILES}; \
+ fi
+ sh $S/kern/genassym.sh ${MKDEP} -f assym.dep ${CFLAGS} \
+ ${CPPFLAGS} < ${HPPA}/hppa64/genassym.cf
+ @sed -e 's/.*\.o:.* /assym.h: /' < assym.dep >> .depend
+ @rm -f assym.dep
+
+# depend on root or device configuration
+autoconf.o conf.o: Makefile
+
+# depend on network or filesystem configuration
+uipc_proto.o vfs_conf.o: Makefile
+
+# depend on maxusers
+assym.h machdep.o: Makefile
+
+# depend on CPU configuration
+locore.o machdep.o trap.o: Makefile
+
+
+locore.o: ${HPPA}/hppa64/locore.S assym.h
+ ${NORMAL_S}
+fpemu.o: assym.h
+
+# The install target can be redefined by putting a
+# install-kernel-${MACHINE_NAME} target into /etc/mk.conf
+MACHINE_NAME!= uname -n
+install: install-kernel-${MACHINE_NAME}
+.if !target(install-kernel-${MACHINE_NAME}})
+install-kernel-${MACHINE_NAME}:
+ rm -f /obsd
+ ln /bsd /obsd
+ cp bsd /nbsd
+ mv /nbsd /bsd
+.endif
+
+%RULES
diff --git a/sys/arch/hppa64/conf/RAMDISK b/sys/arch/hppa64/conf/RAMDISK
new file mode 100644
index 00000000000..5db92686d5f
--- /dev/null
+++ b/sys/arch/hppa64/conf/RAMDISK
@@ -0,0 +1,199 @@
+# $OpenBSD: RAMDISK,v 1.1 2005/04/01 10:40:47 mickey Exp $
+#
+# Diskless kernel config
+#
+
+# Machine architecture; required by config(8)
+machine hppa
+
+option DDB # in-kernel debugger
+option DIAGNOSTIC # internal consistency checks
+
+option FFS # UFS
+option NFSCLIENT # Network File System client
+option CD9660 # ISO 9660 + Rock Ridge file system
+option FDESC # /dev/fd
+option FIFO # FIFOs; RECOMMENDED
+option INET # IP + ICMP + TCP + UDP
+option INET6 # IPv6 (needs INET)
+
+#option USER_PCICONF # user-space PCI configuration
+option BOOT_CONFIG # add support for boot -c
+
+# Need to set locally
+maxusers 32
+
+option TIMEZONE=0 # time zone to adjust RTC time by
+option DST=0 # daylight saving time used by RTC
+
+option RAMDISK_HOOKS
+option MINIROOTSIZE=5120
+config bsd root on rd0a swap on rd0b # and sd0b
+
+mainbus0 at root # root bus
+
+mem* at mainbus0 flags 0x00 # /dev/*mem and memory controller
+pdc0 at mainbus0 # PDC/IODC wrapper for boot console
+power0 at mainbus0 # power/fail manager (iv 30)
+cpu* at mainbus0 # HP PA-RISC cpu
+plut0 at mainbus0 # Astro Runway-Ropes, MIOC and IOA
+
+option PCIVERBOSE
+elroy* at plut0
+pci* at elroy?
+
+ppb* at pci?
+pci* at ppb?
+
+#goofy* at pci? # NS87560UBD
+#com* at goofy?
+#lpt* at goofy?
+#fdc* at goofy?
+
+# CardBus bus support
+cbb* at pci?
+cardslot* at cbb?
+option CARDBUS_DEBUG,CARDSLOT_DEBUG,CARDBUS_MAP_DEBUG
+cardbus* at cardslot?
+option PCMCIADEBUG,PCMCIAVERBOSE
+pcmcia* at cardslot?
+
+# PCI USB Controllers
+#ehci* at pci? # Enhanced Host Controller
+#uhci* at pci? # Universal Host Controller (Intel)
+#ohci* at pci? # Open Host Controller
+
+# USB bus support
+#usb* at ehci?
+#usb* at uhci?
+#usb* at ohci?
+
+# USB devices
+#uhub* at usb? # USB Hubs
+#uhub* at uhub? # USB Hubs
+#umodem* at uhub? # USB Modems/Serial
+#ucom* at umodem?
+#uvisor* at uhub? # Handspring Visor
+#ucom* at uvisor?
+#uvscom* at uhub? # SUNTAC Slipper U VS-10U serial
+#ucom* at uvscom?
+#ubsa* at uhub? # Belkin serial adapter
+#ucom* at ubsa?
+#uftdi* at uhub? # FTDI FT8U100AX serial adapter
+#ucom* at uftdi?
+#uplcom* at uhub? # I/O DATA USB-RSAQ2 serial adapter
+#ucom* at uplcom?
+#umct* at uhub? # MCT USB-RS232 serial adapter
+#ucom* at umct?
+#uaudio* at uhub? # USB Audio
+#audio* at uaudio?
+#umidi* at uhub? # USB MIDI
+#midi* at umidi?
+#ulpt* at uhub? # USB Printers
+#umass* at uhub? # USB Mass Storage devices
+#scsibus* at umass?
+#uhidev* at uhub? # Human Interface Devices
+#ums* at uhidev? # USB mouse
+#wsmouse* at ums? mux 0
+#ukbd* at uhidev? # USB keyboard
+#wskbd* at ukbd? mux 1
+#uhid* at uhidev? # USB generic HID support
+#aue* at uhub? # ADMtek AN986 Pegasus Ethernet
+#axe* at uhub? # ASIX Electronics AX88172 USB Ethernet
+#cue* at uhub? # CATC USB-EL1201A based Ethernet
+#kue* at uhub? # Kawasaki KL5KUSB101B based Ethernet
+#cdce* at uhub? # CDC Ethernet
+#udav* at uhub? # Davicom DM9601 based Ethernet
+#upl* at uhub? # Prolific PL2301/PL2302 host-to-host `network'
+#url* at uhub? # Realtek RTL8150L based adapters
+#wi* at uhub? # WaveLAN IEEE 802.11DS
+#urio* at uhub? # Diamond Multimedia Rio 500
+#uscanner* at uhub? # USB Scanners
+#usscanner* at uhub? # USB SCSI scanners, e.g., HP5300
+#scsibus* at usscanner?
+#uyap* at uhub? # Y@P firmware loader
+#udsbr* at uhub? # D-Link DSB-R100 radio
+#radio* at udsbr? # USB radio
+#ugen* at uhub? # USB Generic driver
+
+#sti* at pci? # EG-PCI, FX*
+wsdisplay* at sti?
+
+#com* at pcmcia? # PCMCIA modems
+
+#ie* at pci?
+
+#ep* at pci? # 3c59x ethernets
+ahc* at pci? # Adaptec 2940 SCSI controllers
+scsibus* at ahc?
+#option BHADEBUG
+#bha* at pci?
+#scsibus* at bha?
+
+siop* at pci? # NCR 538XX SCSI controllers(new)
+scsibus* at siop?
+#ahd* at pci? # Adaptec 79?? SCSI controllers
+#scsibus* at ahd?
+
+#em* at pci? # Intel Pro/1000 ethernet
+#ti* at pci? # Alteon Tigon 1Gb ethernet
+#txp* at pci? # 3com 3CR990
+#fpa* at pci? # DEC DEFPA FDDI
+dc* at pci? # 21143, "tulip" clone ethernet
+#dc* at cardbus?
+#rl* at pci? # RealTek 81[23]9 ethernet
+#rl* at cardbus?
+#ep* at pci? # 3c59x
+#ep* at cardbus?
+#xl* at pci? # 3C9xx ethernet
+#xl* at cardbus?
+fxp* at pci? # EtherExpress 10/100B ethernet
+#fxp* at cardbus?
+ne* at pci? # NE2000-compatible Ethernet
+ne* at pcmcia?
+#an* at pci? # Cisco/Aironet 802.11DS
+an* at pcmcia?
+#wi* at pci? # WaveLAN IEEE 802.11DS
+wi* at pcmcia?
+
+dcphy* at mii? # Digital Clone PHYs
+amphy* at mii? # AMD 79C873 PHYs
+#exphy* at mii? # 3Com internal PHYs
+inphy* at mii? # Intel 82555 PHYs
+#iophy* at mii? # Intel 82553 PHYs
+icsphy* at mii? # ICS1890 PHYs
+lxtphy* at mii? # Level One LXT-970 PHYs
+nsphy* at mii? # NS83840 PHYs
+nsphyter* at mii? # NS83843 PHYs
+#mtdphy* at mii? # Myson MTD972 PHYs
+#qsphy* at mii? # Quality Semi QS6612 PHYs
+#sqphy* at mii? # Seeq 8022[013] PHYs
+#tlphy* at mii? # ThunderLAN PHYs
+#tqphy* at mii? # TDK Semiconductor PHYs
+#brgphy* at mii? # Broadcom 10/100/1000 PHYs
+bmtphy* at mii? # Broadcom 10/100 PHYs
+#eephy* at mii? # Marvell 88E1000 Gigabit PHYs
+ukphy* at mii? # generic unknown PHYs
+
+#pciide* at pci? flags 0x0000
+#wdc* at pcmcia?
+#wd* at wdc? flags 0x0000
+#wd* at pciide? flags 0x0000
+#atapiscsi* at pciide?
+#scsibus* at atapiscsi?
+
+# These entries find devices on all SCSI busses and assign
+# unit numers dynamically.
+sd* at scsibus?
+st* at scsibus?
+cd* at scsibus?
+ch* at scsibus?
+ss* at scsibus?
+uk* at scsibus?
+
+pseudo-device rd 1 # ramdisk
+pseudo-device loop 1 # network loopback
+pseudo-device bpfilter 1 # packet filter
+pseudo-device pty 16 # pseudo-terminals
+pseudo-device ksyms 1 # kernel symbols device
+pseudo-device ccd 4 # concatenated disk devices
diff --git a/sys/arch/hppa64/conf/files.hppa64 b/sys/arch/hppa64/conf/files.hppa64
new file mode 100644
index 00000000000..ec650e77a5c
--- /dev/null
+++ b/sys/arch/hppa64/conf/files.hppa64
@@ -0,0 +1,133 @@
+# $OpenBSD: files.hppa64,v 1.1 2005/04/01 10:40:47 mickey Exp $
+#
+# hppa64-specific configuration info
+
+# maxpartitions must be the first item in files.${ARCH}
+maxpartitions 16
+
+maxusers 2 8 64
+
+#
+# "workstation console" routines
+#
+include "dev/wscons/files.wscons"
+file arch/hppa64/hppa64/wscons_machdep.c wsdisplay
+
+#
+# Media Independent Interface (mii)
+#
+include "dev/mii/files.mii"
+
+#
+# Machine-independent SCSI drivers
+#
+include "scsi/files.scsi"
+major { sd = 4 }
+major { st = 5 }
+major { cd = 6 }
+
+# I2O
+include "dev/i2o/files.i2o"
+
+#
+# MI ATAPI drivers
+#
+include "dev/atapiscsi/files.atapiscsi"
+include "dev/ata/files.ata"
+
+#
+# PCI Bus support
+#
+include "dev/pci/files.pci"
+
+#
+# CardBus support
+#
+include "dev/cardbus/files.cardbus"
+
+#
+# Machine-independent PCMCIA drivers
+#
+include "dev/pcmcia/files.pcmcia"
+
+#
+# Machine-independent USB drivers
+#
+include "dev/usb/files.usb"
+
+#
+# Mainbus
+#
+
+define gedoens {}
+device mainbus: gedoens
+attach mainbus at root
+file arch/hppa64/hppa64/mainbus.c mainbus
+
+device pdc
+attach pdc at gedoens
+file arch/hppa64/dev/pdc.c pdc
+
+device power
+attach power at gedoens
+file arch/hppa64/dev/power.c power needs-flag
+
+device mem
+attach mem at gedoens
+file arch/hppa64/dev/mem.c mem
+
+device cpu
+attach cpu at gedoens
+file arch/hppa64/dev/cpu.c cpu
+
+# Astro/Pluto, integrated Runway-Ropes bridge, MIOC and IOA
+device plut: gedoens
+attach plut at gedoens
+file arch/hppa64/dev/pluto.c plut
+
+# Elroy, Ropes to PCI Bridge. Supports 4X PCI and dual address cycle.
+# Mercury; QuickSilver is an AGP also
+device elroy: pcibus
+attach elroy at gedoens
+file arch/hppa64/dev/elroy.c elroy
+file arch/hppa64/dev/apic.c elroy
+
+###
+
+major {ccd = 1}
+major {vnd = 2}
+major {rd = 3}
+
+# PS/2 mouse
+include "dev/pckbc/files.pckbc"
+
+#
+# Compatibility
+#
+#include "compat/hpux/hppa64/files.hpux"
+#file arch/hppa64/hppa64/hpux_machdep.c compat_hpux
+#include "compat/osf1/files.osf1"
+#file arch/hppa64/hppa64/osf1_machdep.c compat_osf1
+#include "compat/linux/files.linux"
+#include "compat/ossaudio/files.ossaudio"
+#file arch/hppa64/hppa64/linux_machdep.c compat_linux
+
+#
+# Non-device files
+#
+
+file arch/hppa64/hppa64/autoconf.c
+file arch/hppa64/hppa64/conf.c
+file arch/hppa64/hppa64/db_interface.c ddb
+file arch/hppa64/hppa64/db_disasm.c ddb
+file arch/hppa64/hppa64/disksubr.c disk
+file arch/hppa64/hppa64/machdep.c
+file arch/hppa64/hppa64/pmap.c
+file arch/hppa64/hppa64/process_machdep.c
+file arch/hppa64/hppa64/sys_machdep.c
+file arch/hppa64/hppa64/trap.c
+file arch/hppa64/hppa64/vm_machdep.c
+file arch/hppa64/hppa64/in_cksum.c inet
+file arch/hppa64/dev/clock.c
+
+file dev/cninit.c
diff --git a/sys/arch/hppa64/conf/ld.script b/sys/arch/hppa64/conf/ld.script
new file mode 100644
index 00000000000..7df2c2c79d2
--- /dev/null
+++ b/sys/arch/hppa64/conf/ld.script
@@ -0,0 +1,88 @@
+/* $OpenBSD: ld.script,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+OUTPUT_FORMAT("elf64-hppa")
+OUTPUT_ARCH(hppa2.0w)
+ENTRY($start)
+SECTIONS
+{
+ . = + SIZEOF_HEADERS;
+ .text :
+ {
+ kernel_text = . ;
+ *(.text) *(.text.*)
+ *(.reginfo)
+ *(.init)
+ *(.stub)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ . = ALIGN(4096);
+ etext = ABSOLUTE(.);
+ } = 0x08000240 /* nop filled */
+ . = 0x400000;
+
+ .rodata :
+ {
+ __rodata_start = .;
+ *(.rodata) *(.rodata1)
+ __unwind_start = .;
+ *(.PARISC.unwind)
+ __unwind_end = .;
+ __rodata_end = .;
+ } = 0
+ __data_start = ABSOLUTE(.);
+
+ .data :
+ {
+ *(.data)
+ CONSTRUCTORS
+ . = ALIGN(4096);
+ edata = ABSOLUTE(.);
+ } = 0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+
+ .opd : { *(.opd) }
+ PROVIDE(__gp = .);
+ .plt : { *(.plt) }
+ .dlt : { *(.dlt) }
+
+ . = ALIGN(4096);
+
+ __bss_start = .;
+ /* .sbss : { *(.sbss) *(.scommon) } */
+ .bss :
+ {
+ *(.dynbss) *(.bss)
+ *(COMMON) *($COMMON$)
+ . = ALIGN(4096);
+ __kernel_pagedir = ABSOLUTE(.);
+ . += 5*4096; /* PIT + 4*PIE */
+ }
+ end = ABSOLUTE(.);
+
+ /DISCARD/ : {
+ *(.exitcall.exit)
+ *(.interp)
+ *(.dynsym)
+ *(.dynstr)
+ *(.dynamic)
+ *(.hash)
+ }
+}
diff --git a/sys/arch/hppa64/dev/apic.c b/sys/arch/hppa64/dev/apic.c
new file mode 100644
index 00000000000..d4a94787853
--- /dev/null
+++ b/sys/arch/hppa64/dev/apic.c
@@ -0,0 +1,132 @@
+/* $OpenBSD: apic.c,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define APIC_DEBUG
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+
+#include <hppa64/dev/elroyreg.h>
+#include <hppa64/dev/elroyvar.h>
+
+
+void
+apic_write(volatile struct elroy_regs *r, u_int32_t reg, u_int32_t val)
+{
+ elroy_write32(&r->apic_addr, htole32(reg));
+ elroy_write32(&r->apic_data, htole32(val));
+}
+
+u_int32_t
+apic_read(volatile struct elroy_regs *r, u_int32_t reg)
+{
+ elroy_write32(&r->apic_addr, htole32(reg));
+ return letoh32(elroy_read32(&r->apic_data));
+}
+
+void
+apic_attach(struct elroy_softc *sc)
+{
+ volatile struct elroy_regs *r = sc->sc_regs;
+ u_int32_t data;
+
+ data = apic_read(r, APIC_VERSION);
+ sc->sc_nints = (data & APIC_VERSION_NENT) >> APIC_VERSION_NENT_SHIFT;
+ printf("APIC ver 0x%x %d ents\n",
+ data & APIC_VERSION_MASK, sc->sc_nints);
+}
+
+int
+apic_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
+{
+ pci_chipset_tag_t pc = pa->pa_pc;
+ struct elroy_softc *sc = pc->_cookie;
+ pcitag_t tag = pa->pa_tag;
+ hppa_hpa_t hpa = cpu_gethpa(0);
+ pcireg_t reg;
+
+ reg = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
+printf(" pin=%d line=%d ", PCI_INTERRUPT_PIN(reg), PCI_INTERRUPT_LINE(reg));
+ apic_write(sc->sc_regs, APIC_ENT0(PCI_INTERRUPT_PIN(reg)),
+ PCI_INTERRUPT_LINE(reg));
+ apic_write(sc->sc_regs, APIC_ENT1(PCI_INTERRUPT_PIN(reg)),
+ ((hpa & 0x0ff00000) >> 4) | ((hpa & 0x000ff000) << 12));
+ *ihp = PCI_INTERRUPT_LINE(reg) + 1;
+ return (*ihp == 0);
+}
+
+const char *
+apic_intr_string(void *v, pci_intr_handle_t ih)
+{
+ static char buf[32];
+
+ snprintf(buf, 32, "irq %ld", ih);
+
+ return (buf);
+}
+
+void *
+apic_intr_establish(void *v, pci_intr_handle_t ih,
+ int pri, int (*handler)(void *), void *arg, char *name)
+{
+ /* struct elroy_softc *sc = v; */
+ /* volatile struct elroy_regs *r = sc->sc_regs; */
+ /* void *iv = NULL; */
+
+ /* no mapping or bogus */
+ if (ih <= 0 || ih > 63)
+ return (NULL);
+
+#if 0
+TODO
+ if ((iv = cpu_intr_map(sc->sc_ih, pri, ih - 1, handler, arg, name))) {
+ if (cold)
+ sc->sc_imr |= (1 << (ih - 1));
+ else
+ /* r->imr = sc->sc_imr |= (1 << (ih - 1)) */;
+ }
+#endif
+
+ return (arg);
+}
+
+void
+apic_intr_disestablish(void *v, void *cookie)
+{
+#if 0
+ struct elroy_softc *sc = v;
+ volatile struct elroy_regs *r = sc->sc_regs;
+
+ r->imr &= ~(1 << (ih - 1));
+
+ TODO cpu_intr_unmap(sc->sc_ih, cookie);
+#endif
+}
+
+int
+apic_intr(void *v)
+{
+
+ return (0);
+}
diff --git a/sys/arch/hppa64/dev/clock.c b/sys/arch/hppa64/dev/clock.c
new file mode 100644
index 00000000000..2c68f463ca2
--- /dev/null
+++ b/sys/arch/hppa64/dev/clock.c
@@ -0,0 +1,43 @@
+/* $OpenBSD: clock.c,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/time.h>
+
+#include <dev/clock_subr.h>
+
+void
+cpu_initclocks()
+{
+
+}
+
+void
+setstatclockrate(int newhz)
+{
+
+}
+
+void
+microtime(struct timeval *tv)
+{
+
+}
diff --git a/sys/arch/hppa64/dev/cpu.c b/sys/arch/hppa64/dev/cpu.c
new file mode 100644
index 00000000000..a4ce15560e2
--- /dev/null
+++ b/sys/arch/hppa64/dev/cpu.c
@@ -0,0 +1,139 @@
+/* $OpenBSD: cpu.c,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/reboot.h>
+
+#include <machine/pdc.h>
+#include <machine/reg.h>
+#include <machine/iomod.h>
+#include <machine/autoconf.h>
+
+#include <arch/hppa/dev/cpudevs.h>
+
+struct cpu_softc {
+ struct device sc_dev;
+
+ hppa_hpa_t sc_hpa;
+ void *sc_ih;
+};
+
+int cpumatch(struct device *, void *, void *);
+void cpuattach(struct device *, struct device *, void *);
+
+struct cfattach cpu_ca = {
+ sizeof(struct cpu_softc), cpumatch, cpuattach
+};
+
+struct cfdriver cpu_cd = {
+ NULL, "cpu", DV_DULL
+};
+
+int
+cpumatch(parent, cfdata, aux)
+ struct device *parent;
+ void *cfdata;
+ void *aux;
+{
+ struct confargs *ca = aux;
+ /* struct cfdata *cf = cfdata; */
+
+ if (strcmp(ca->ca_name, "cpu"))
+ return 0;
+
+ return 1;
+}
+
+int
+cpu_hardclock(void *v)
+{
+ hardclock(v);
+ return (1);
+}
+
+void
+cpuattach(parent, self, aux)
+ struct device *parent;
+ struct device *self;
+ void *aux;
+{
+ /* machdep.c */
+ extern struct pdc_model pdc_model;
+ extern struct pdc_cache pdc_cache;
+ extern u_int cpu_ticksnum, cpu_ticksdenom;
+ extern u_int fpu_enable;
+
+ /* struct cpu_softc *sc = (struct cpu_softc *)self; */
+ /* struct confargs *ca = aux; */
+ u_int mhz = 100 * cpu_ticksnum / cpu_ticksdenom;
+ const char *p;
+
+ printf (": %s ", cpu_typename);
+ if (pdc_model.hvers) {
+ static const char lvls[4][4] = { "0", "1", "1.5", "2" };
+
+ printf("L%s-%c ", lvls[pdc_model.pa_lvl], "AB"[pdc_model.mc]);
+ }
+
+ printf ("%d", mhz / 100);
+ if (mhz % 100 > 9)
+ printf(".%02d", mhz % 100);
+ printf("MHz");
+
+ if (fpu_enable) {
+ extern u_int fpu_version;
+ u_int32_t ver[2];
+
+ mtctl(fpu_enable, CR_CCR);
+ __asm volatile(
+ "fstds %%fr0,0(%0)\n\t"
+ "copr,0,0\n\t"
+ "fstds %%fr0,0(%0)"
+ :: "r" (&ver) : "memory");
+ mtctl(0, CR_CCR);
+ fpu_version = HPPA_FPUVER(ver[0]);
+ printf(", FPU %s rev %d",
+ hppa_mod_info(HPPA_TYPE_FPU, fpu_version >> 5),
+ fpu_version & 0x1f);
+ }
+
+ printf("\n%s: ", self->dv_xname);
+ p = "";
+ if (!pdc_cache.dc_conf.cc_sh) {
+ printf("%uK(%db/l) Icache, ",
+ pdc_cache.ic_size / 1024, pdc_cache.ic_conf.cc_line * 16);
+ p = "D";
+ }
+ printf("%uK(%db/l) wr-%s %scoherent %scache, ",
+ pdc_cache.dc_size / 1024, pdc_cache.dc_conf.cc_line * 16,
+ pdc_cache.dc_conf.cc_wt? "thru" : "back",
+ pdc_cache.dc_conf.cc_cst? "" : "in", p);
+
+ p = "";
+ if (!pdc_cache.dt_conf.tc_sh) {
+ printf("%u ITLB, ", pdc_cache.it_size);
+ p = "D";
+ }
+ printf("%u %scoherent %sTLB\n",
+ pdc_cache.dt_size, pdc_cache.dt_conf.tc_cst? "" : "in", p);
+
+/* TODO spin up others */
+}
diff --git a/sys/arch/hppa64/dev/elroy.c b/sys/arch/hppa64/dev/elroy.c
new file mode 100644
index 00000000000..9f7d3f6b6b4
--- /dev/null
+++ b/sys/arch/hppa64/dev/elroy.c
@@ -0,0 +1,1181 @@
+/* $OpenBSD: elroy.c,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "cardbus.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/reboot.h>
+#include <sys/malloc.h>
+#include <sys/extent.h>
+
+#include <machine/iomod.h>
+#include <machine/autoconf.h>
+
+#if NCARDBUS > 0
+#include <dev/cardbus/rbus.h>
+#endif
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+
+#include <hppa64/dev/elroyreg.h>
+#include <hppa64/dev/elroyvar.h>
+
+#define ELROY_MEM_CHUNK 0x800000
+#define ELROY_MEM_WINDOW (2 * ELROY_MEM_CHUNK)
+
+/* global interrupt masks */
+u_int64_t cpu_maskfree;
+volatile u_int64_t imask[NIPL];
+
+int elroymatch(struct device *, void *, void *);
+void elroyattach(struct device *, struct device *, void *);
+int elroy_intr(void *);
+
+struct cfattach elroy_ca = {
+ sizeof(struct elroy_softc), elroymatch, elroyattach
+};
+
+struct cfdriver elroy_cd = {
+ NULL, "elroy", DV_DULL
+};
+
+int
+elroymatch(parent, cfdata, aux)
+ struct device *parent;
+ void *cfdata;
+ void *aux;
+{
+ struct confargs *ca = aux;
+ /* struct cfdata *cf = cfdata; */
+
+ if (strcmp(ca->ca_name, "lba"))
+ return (0);
+
+ return (1);
+}
+
+void
+elroy_write32(volatile u_int32_t *p, u_int32_t v)
+{
+ *p = v;
+}
+
+u_int32_t
+elroy_read32(volatile u_int32_t *p)
+{
+ return *p;
+}
+
+void
+elroy_attach_hook(struct device *parent, struct device *self,
+ struct pcibus_attach_args *pba)
+{
+
+}
+
+int
+elroy_maxdevs(void *v, int bus)
+{
+ return (32);
+}
+
+pcitag_t
+elroy_make_tag(void *v, int bus, int dev, int func)
+{
+ if (bus > 255 || dev > 31 || func > 7)
+ panic("elroy_make_tag: bad request");
+
+ return ((bus << 16) | (dev << 11) | (func << 8));
+}
+
+void
+elroy_decompose_tag(void *v, pcitag_t tag, int *bus, int *dev, int *func)
+{
+ *bus = (tag >> 16) & 0xff;
+ *dev = (tag >> 11) & 0x1f;
+ *func= (tag >> 8) & 0x07;
+}
+
+pcireg_t
+elroy_conf_read(void *v, pcitag_t tag, int reg)
+{
+ struct elroy_softc *sc = v;
+ volatile struct elroy_regs *r = sc->sc_regs;
+ u_int32_t arb_mask, err_cfg, control;
+ pcireg_t data, data1;
+
+/* printf("elroy_conf_read(%p, 0x%08x, 0x%x)", v, tag, reg); */
+ arb_mask = elroy_read32(&r->arb_mask);
+ err_cfg = elroy_read32(&r->err_cfg);
+ control = elroy_read32(&r->control);
+ if (!arb_mask)
+ elroy_write32(&r->arb_mask, htole64(ELROY_ARB_ENABLE));
+ elroy_write32(&r->err_cfg, err_cfg |
+ htole32(ELROY_ERRCFG_SMART | ELROY_ERRCFG_CM));
+ elroy_write32(&r->control, (control | htole32(ELROY_CONTROL_CE)) &
+ ~htole32(ELROY_CONTROL_HF));
+
+ elroy_write32(&r->pci_conf_addr, htole32(tag | reg));
+ data1 = elroy_read32(&r->pci_conf_addr);
+ data = elroy_read32(&r->pci_conf_data);
+
+ elroy_write32(&r->control, control |
+ htole32(ELROY_CONTROL_CE|ELROY_CONTROL_CL));
+ elroy_write32(&r->control, control);
+ elroy_write32(&r->err_cfg, err_cfg);
+ if (!arb_mask)
+ elroy_write32(&r->arb_mask, arb_mask);
+
+ data = letoh32(data);
+/* printf("=0x%08x (@ 0x%08x)\n", data, letoh32(data1)); */
+ return (data);
+}
+
+void
+elroy_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
+{
+ struct elroy_softc *sc = v;
+ volatile struct elroy_regs *r = sc->sc_regs;
+ u_int32_t arb_mask, err_cfg, control;
+ pcireg_t data1;
+
+/* printf("elroy_conf_write(%p, 0x%08x, 0x%x, 0x%x)\n", v, tag, reg, data); */
+ arb_mask = elroy_read32(&r->arb_mask);
+ err_cfg = elroy_read32(&r->err_cfg);
+ control = elroy_read32(&r->control);
+ if (!arb_mask)
+ elroy_write32(&r->arb_mask, htole64(ELROY_ARB_ENABLE));
+ elroy_write32(&r->err_cfg, err_cfg |
+ htole32(ELROY_ERRCFG_SMART | ELROY_ERRCFG_CM));
+ elroy_write32(&r->control, (control | htole32(ELROY_CONTROL_CE)) &
+ ~htole32(ELROY_CONTROL_HF));
+
+ /* fix coalescing config writes errata by interleaving w/ a read */
+ elroy_write32(&r->pci_conf_addr, htole32(tag | PCI_ID_REG));
+ data1 = elroy_read32(&r->pci_conf_addr);
+ data1 = elroy_read32(&r->pci_conf_data);
+
+ elroy_write32(&r->pci_conf_addr, htole32(tag | reg));
+ data1 = elroy_read32(&r->pci_conf_addr);
+ elroy_write32(&r->pci_conf_data, htole32(data));
+ data1 = elroy_read32(&r->pci_conf_addr);
+
+ elroy_write32(&r->control, control |
+ htole32(ELROY_CONTROL_CE|ELROY_CONTROL_CL));
+ elroy_write32(&r->control, control);
+ elroy_write32(&r->err_cfg, err_cfg);
+ if (!arb_mask)
+ elroy_write32(&r->arb_mask, arb_mask);
+}
+
+int
+elroy_iomap(void *v, bus_addr_t bpa, bus_size_t size,
+ int flags, bus_space_handle_t *bshp)
+{
+ struct elroy_softc *sc = v;
+ /* volatile struct elroy_regs *r = sc->sc_regs; */
+ int error;
+
+ if ((error = bus_space_map(sc->sc_bt, bpa + sc->sc_iobase, size,
+ flags, bshp)))
+ return (error);
+
+ return (0);
+}
+
+int
+elroy_memmap(void *v, bus_addr_t bpa, bus_size_t size,
+ int flags, bus_space_handle_t *bshp)
+{
+ struct elroy_softc *sc = v;
+ /* volatile struct elroy_regs *r = sc->sc_regs; */
+ int error;
+
+ bpa |= 0xffffffff00000000ULL;
+ if ((error = bus_space_map(sc->sc_bt, bpa, size, flags, bshp)))
+ return (error);
+
+ return (0);
+}
+
+int
+elroy_subregion(void *v, bus_space_handle_t bsh, bus_size_t offset,
+ bus_size_t size, bus_space_handle_t *nbshp)
+{
+ *nbshp = bsh + offset;
+ return (0);
+}
+
+int
+elroy_ioalloc(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size,
+ bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp,
+ bus_space_handle_t *bshp)
+{
+ struct elroy_softc *sc = v;
+ volatile struct elroy_regs *r = sc->sc_regs;
+ bus_addr_t iostart, ioend;
+
+ iostart = r->io_base & ~htole32(ELROY_BASE_RE);
+ ioend = iostart + ~htole32(r->io_mask) + 1;
+ if (rstart < iostart || rend > ioend)
+ panic("elroy_ioalloc: bad region start/end");
+
+ rstart += sc->sc_iobase;
+ rend += sc->sc_iobase;
+ if (bus_space_alloc(sc->sc_bt, rstart, rend, size,
+ align, boundary, flags, addrp, bshp))
+ return (ENOMEM);
+
+ return (0);
+}
+
+int
+elroy_memalloc(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size,
+ bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp,
+ bus_space_handle_t *bshp)
+{
+ struct elroy_softc *sc = v;
+ /* volatile struct elroy_regs *r = sc->sc_regs; */
+
+ if (bus_space_alloc(sc->sc_bt, rstart, rend, size,
+ align, boundary, flags, addrp, bshp))
+ return (ENOMEM);
+
+ return (0);
+}
+
+void
+elroy_unmap(void *v, bus_space_handle_t bsh, bus_size_t size)
+{
+ struct elroy_softc *sc = v;
+
+ bus_space_free(sc->sc_bt, bsh, size);
+}
+
+void
+elroy_free(void *v, bus_space_handle_t bh, bus_size_t size)
+{
+ /* should be enough */
+ elroy_unmap(v, bh, size);
+}
+
+void
+elroy_barrier(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int op)
+{
+ struct elroy_softc *sc = v;
+ volatile struct elroy_regs *r = sc->sc_regs;
+ u_int32_t data;
+
+ sync_caches();
+ if (op & BUS_SPACE_BARRIER_WRITE) {
+ data = r->pci_id; /* flush write fifo */
+ sync_caches();
+ }
+}
+
+#if NCARDBUS > 0
+void *
+elroy_alloc_parent(struct device *self, struct pci_attach_args *pa, int io)
+{
+#if 0 /* TODO */
+
+ struct elroy_softc *sc = pa->pa_pc->_cookie;
+ struct extent *ex;
+ bus_space_tag_t tag;
+ bus_addr_t start;
+ bus_size_t size;
+
+ if (io) {
+ ex = sc->sc_ioex;
+ tag = pa->pa_iot;
+ start = 0xa000;
+ size = 0x1000;
+ } else {
+ if (!sc->sc_memex) {
+ bus_space_handle_t memh;
+ bus_addr_t mem_start;
+
+ if (elroy_memalloc(sc, 0xf0800000, 0xff7fffff,
+ ELROY_MEM_WINDOW, ELROY_MEM_WINDOW, EX_NOBOUNDARY,
+ 0, &mem_start, &memh))
+ return (NULL);
+
+ snprintf(sc->sc_memexname, sizeof(sc->sc_memexname),
+ "%s_mem", sc->sc_dv.dv_xname);
+ if ((sc->sc_memex = extent_create(sc->sc_memexname,
+ mem_start, mem_start + ELROY_MEM_WINDOW, M_DEVBUF,
+ NULL, 0, EX_NOWAIT | EX_MALLOCOK)) == NULL) {
+ extent_destroy(sc->sc_ioex);
+ bus_space_free(sc->sc_bt, memh,
+ ELROY_MEM_WINDOW);
+ return (NULL);
+ }
+ }
+ ex = sc->sc_memex;
+ tag = pa->pa_memt;
+ start = ex->ex_start;
+ size = ELROY_MEM_CHUNK;
+ }
+
+ if (extent_alloc_subregion(ex, start, ex->ex_end, size, size, 0,
+ EX_NOBOUNDARY, EX_NOWAIT, &start))
+ return (NULL);
+
+ extent_free(ex, start, size, EX_NOWAIT);
+ return rbus_new_root_share(tag, ex, start, size, 0);
+#else
+ return (NULL);
+#endif
+}
+#endif
+
+u_int8_t
+elroy_r1(void *v, bus_space_handle_t h, bus_size_t o)
+{
+ h += o;
+ return *(volatile u_int8_t *)h;
+}
+
+u_int16_t
+elroy_r2(void *v, bus_space_handle_t h, bus_size_t o)
+{
+ volatile u_int16_t *p;
+
+ h += o;
+ p = (volatile u_int16_t *)h;
+ return (letoh16(*p));
+}
+
+u_int32_t
+elroy_r4(void *v, bus_space_handle_t h, bus_size_t o)
+{
+ u_int32_t data;
+
+ h += o;
+ data = *(volatile u_int32_t *)h;
+ return (letoh32(data));
+}
+
+u_int64_t
+elroy_r8(void *v, bus_space_handle_t h, bus_size_t o)
+{
+ u_int64_t data;
+
+ h += o;
+ data = *(volatile u_int64_t *)h;
+ return (letoh64(data));
+}
+
+void
+elroy_w1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t vv)
+{
+ h += o;
+ *(volatile u_int8_t *)h = vv;
+}
+
+void
+elroy_w2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv)
+{
+ volatile u_int16_t *p;
+
+ h += o;
+ p = (volatile u_int16_t *)h;
+ *p = htole16(vv);
+}
+
+void
+elroy_w4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv)
+{
+ h += o;
+ vv = htole32(vv);
+ *(volatile u_int32_t *)h = vv;
+}
+
+void
+elroy_w8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t vv)
+{
+ h += o;
+ *(volatile u_int64_t *)h = htole64(vv);
+}
+
+
+void
+elroy_rm_1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t *a, bus_size_t c)
+{
+ volatile u_int8_t *p;
+
+ h += o;
+ p = (volatile u_int8_t *)h;
+ while (c--)
+ *a++ = *p;
+}
+
+void
+elroy_rm_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c)
+{
+ volatile u_int16_t *p;
+
+ h += o;
+ p = (volatile u_int16_t *)h;
+ while (c--)
+ *a++ = letoh16(*p);
+}
+
+void
+elroy_rm_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c)
+{
+ volatile u_int32_t *p;
+
+ h += o;
+ p = (volatile u_int32_t *)h;
+ while (c--)
+ *a++ = letoh32(*p);
+}
+
+void
+elroy_rm_8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t *a, bus_size_t c)
+{
+ volatile u_int64_t *p;
+
+ h += o;
+ p = (volatile u_int64_t *)h;
+ while (c--)
+ *a++ = letoh64(*p);
+}
+
+void
+elroy_wm_1(void *v, bus_space_handle_t h, bus_size_t o, const u_int8_t *a, bus_size_t c)
+{
+ volatile u_int8_t *p;
+
+ h += o;
+ p = (volatile u_int8_t *)h;
+ while (c--)
+ *p = *a++;
+}
+
+void
+elroy_wm_2(void *v, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c)
+{
+ volatile u_int16_t *p;
+
+ h += o;
+ p = (volatile u_int16_t *)h;
+ while (c--)
+ *p = htole16(*a++);
+}
+
+void
+elroy_wm_4(void *v, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c)
+{
+ volatile u_int32_t *p;
+
+ h += o;
+ p = (volatile u_int32_t *)h;
+ while (c--)
+ *p = htole32(*a++);
+}
+
+void
+elroy_wm_8(void *v, bus_space_handle_t h, bus_size_t o, const u_int64_t *a, bus_size_t c)
+{
+ volatile u_int64_t *p;
+
+ h += o;
+ p = (volatile u_int64_t *)h;
+ while (c--)
+ *p = htole64(*a++);
+}
+
+void
+elroy_sm_1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t vv, bus_size_t c)
+{
+ volatile u_int8_t *p;
+
+ h += o;
+ p = (volatile u_int8_t *)h;
+ while (c--)
+ *p = vv;
+}
+
+void
+elroy_sm_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv, bus_size_t c)
+{
+ volatile u_int16_t *p;
+
+ h += o;
+ p = (volatile u_int16_t *)h;
+ vv = htole16(vv);
+ while (c--)
+ *p = vv;
+}
+
+void
+elroy_sm_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv, bus_size_t c)
+{
+ volatile u_int32_t *p;
+
+ h += o;
+ p = (volatile u_int32_t *)h;
+ vv = htole32(vv);
+ while (c--)
+ *p = vv;
+}
+
+void
+elroy_sm_8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t vv, bus_size_t c)
+{
+ volatile u_int64_t *p;
+
+ h += o;
+ p = (volatile u_int64_t *)h;
+ vv = htole64(vv);
+ while (c--)
+ *p = vv;
+}
+
+void
+elroy_rrm_2(void *v, bus_space_handle_t h, bus_size_t o,
+ u_int8_t *a, bus_size_t c)
+{
+ volatile u_int16_t *p, *q = (u_int16_t *)a;
+
+ h += o;
+ p = (volatile u_int16_t *)h;
+ c /= 2;
+ while (c--)
+ *q++ = *p;
+}
+
+void
+elroy_rrm_4(void *v, bus_space_handle_t h, bus_size_t o,
+ u_int8_t *a, bus_size_t c)
+{
+ volatile u_int32_t *p, *q = (u_int32_t *)a;
+
+ h += o;
+ p = (volatile u_int32_t *)h;
+ c /= 4;
+ while (c--)
+ *q++ = *p;
+}
+
+void
+elroy_rrm_8(void *v, bus_space_handle_t h, bus_size_t o,
+ u_int8_t *a, bus_size_t c)
+{
+ volatile u_int64_t *p, *q = (u_int64_t *)a;
+
+ h += o;
+ p = (volatile u_int64_t *)h;
+ c /= 8;
+ while (c--)
+ *q++ = *p;
+}
+
+void
+elroy_wrm_2(void *v, bus_space_handle_t h, bus_size_t o,
+ const u_int8_t *a, bus_size_t c)
+{
+ volatile u_int16_t *p;
+ const u_int16_t *q = (const u_int16_t *)a;
+
+ h += o;
+ p = (volatile u_int16_t *)h;
+ c /= 2;
+ while (c--)
+ *p = *q++;
+}
+
+void
+elroy_wrm_4(void *v, bus_space_handle_t h, bus_size_t o,
+ const u_int8_t *a, bus_size_t c)
+{
+ volatile u_int32_t *p;
+ const u_int32_t *q = (const u_int32_t *)a;
+
+ h += o;
+ p = (volatile u_int32_t *)h;
+ c /= 4;
+ while (c--)
+ *p = *q++;
+}
+
+void
+elroy_wrm_8(void *v, bus_space_handle_t h, bus_size_t o,
+ const u_int8_t *a, bus_size_t c)
+{
+ volatile u_int64_t *p;
+ const u_int64_t *q = (const u_int64_t *)a;
+
+ h += o;
+ p = (volatile u_int64_t *)h;
+ c /= 8;
+ while (c--)
+ *p = *q++;
+}
+
+void
+elroy_rr_1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t *a, bus_size_t c)
+{
+ volatile u_int8_t *p;
+
+ h += o;
+ p = (volatile u_int8_t *)h;
+ while (c--)
+ *a++ = *p++;
+}
+
+void
+elroy_rr_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c)
+{
+ volatile u_int16_t *p, data;
+
+ h += o;
+ p = (volatile u_int16_t *)h;
+ while (c--) {
+ data = *p++;
+ *a++ = letoh16(data);
+ }
+}
+
+void
+elroy_rr_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c)
+{
+ volatile u_int32_t *p, data;
+
+ h += o;
+ p = (volatile u_int32_t *)h;
+ while (c--) {
+ data = *p++;
+ *a++ = letoh32(data);
+ }
+}
+
+void
+elroy_rr_8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t *a, bus_size_t c)
+{
+ volatile u_int64_t *p, data;
+
+ h += o;
+ p = (volatile u_int64_t *)h;
+ while (c--) {
+ data = *p++;
+ *a++ = letoh64(data);
+ }
+}
+
+void
+elroy_wr_1(void *v, bus_space_handle_t h, bus_size_t o, const u_int8_t *a, bus_size_t c)
+{
+ volatile u_int8_t *p;
+
+ h += o;
+ p = (volatile u_int8_t *)h;
+ while (c--)
+ *p++ = *a++;
+}
+
+void
+elroy_wr_2(void *v, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c)
+{
+ volatile u_int16_t *p, data;
+
+ h += o;
+ p = (volatile u_int16_t *)h;
+ while (c--) {
+ data = *a++;
+ *p++ = htole16(data);
+ }
+}
+
+void
+elroy_wr_4(void *v, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c)
+{
+ volatile u_int32_t *p, data;
+
+ h += o;
+ p = (volatile u_int32_t *)h;
+ while (c--) {
+ data = *a++;
+ *p++ = htole32(data);
+ }
+}
+
+void
+elroy_wr_8(void *v, bus_space_handle_t h, bus_size_t o, const u_int64_t *a, bus_size_t c)
+{
+ volatile u_int64_t *p, data;
+
+ h += o;
+ p = (volatile u_int64_t *)h;
+ while (c--) {
+ data = *a++;
+ *p++ = htole64(data);
+ }
+}
+
+void
+elroy_rrr_2(void *v, bus_space_handle_t h, bus_size_t o,
+ u_int8_t *a, bus_size_t c)
+{
+ volatile u_int16_t *p, *q = (u_int16_t *)a;
+
+ c /= 2;
+ h += o;
+ p = (volatile u_int16_t *)h;
+ while (c--)
+ *q++ = *p++;
+}
+
+void
+elroy_rrr_4(void *v, bus_space_handle_t h, bus_size_t o,
+ u_int8_t *a, bus_size_t c)
+{
+ volatile u_int32_t *p, *q = (u_int32_t *)a;
+
+ c /= 4;
+ h += o;
+ p = (volatile u_int32_t *)h;
+ while (c--)
+ *q++ = *p++;
+}
+
+void
+elroy_rrr_8(void *v, bus_space_handle_t h, bus_size_t o,
+ u_int8_t *a, bus_size_t c)
+{
+ volatile u_int64_t *p, *q = (u_int64_t *)a;
+
+ c /= 8;
+ h += o;
+ p = (volatile u_int64_t *)h;
+ while (c--)
+ *q++ = *p++;
+}
+
+void
+elroy_wrr_2(void *v, bus_space_handle_t h, bus_size_t o,
+ const u_int8_t *a, bus_size_t c)
+{
+ volatile u_int16_t *p;
+ const u_int16_t *q = (u_int16_t *)a;
+
+ c /= 2;
+ h += o;
+ p = (volatile u_int16_t *)h;
+ while (c--)
+ *p++ = *q++;
+}
+
+void
+elroy_wrr_4(void *v, bus_space_handle_t h, bus_size_t o,
+ const u_int8_t *a, bus_size_t c)
+{
+ volatile u_int32_t *p;
+ const u_int32_t *q = (u_int32_t *)a;
+
+ c /= 4;
+ h += o;
+ p = (volatile u_int32_t *)h;
+ while (c--)
+ *p++ = *q++;
+}
+
+void
+elroy_wrr_8(void *v, bus_space_handle_t h, bus_size_t o,
+ const u_int8_t *a, bus_size_t c)
+{
+ volatile u_int64_t *p;
+ const u_int64_t *q = (u_int64_t *)a;
+
+ c /= 8;
+ h += o;
+ p = (volatile u_int64_t *)h;
+ while (c--)
+ *p++ = *q++;
+}
+
+void
+elroy_sr_1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t vv, bus_size_t c)
+{
+ volatile u_int8_t *p;
+
+ h += o;
+ p = (volatile u_int8_t *)h;
+ while (c--)
+ *p++ = vv;
+}
+
+void
+elroy_sr_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv, bus_size_t c)
+{
+ volatile u_int16_t *p;
+
+ h += o;
+ vv = htole16(vv);
+ p = (volatile u_int16_t *)h;
+ while (c--)
+ *p++ = vv;
+}
+
+void
+elroy_sr_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv, bus_size_t c)
+{
+ volatile u_int32_t *p;
+
+ h += o;
+ vv = htole32(vv);
+ p = (volatile u_int32_t *)h;
+ while (c--)
+ *p++ = vv;
+}
+
+void
+elroy_sr_8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t vv, bus_size_t c)
+{
+ volatile u_int64_t *p;
+
+ h += o;
+ vv = htole64(vv);
+ p = (volatile u_int64_t *)h;
+ while (c--)
+ *p++ = vv;
+}
+
+void
+elroy_cp_1(void *v, bus_space_handle_t h1, bus_size_t o1,
+ bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
+{
+ while (c--)
+ elroy_w1(v, h1, o1++, elroy_r1(v, h2, o2++));
+}
+
+void
+elroy_cp_2(void *v, bus_space_handle_t h1, bus_size_t o1,
+ bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
+{
+ while (c--) {
+ elroy_w2(v, h1, o1, elroy_r2(v, h2, o2));
+ o1 += 2;
+ o2 += 2;
+ }
+}
+
+void
+elroy_cp_4(void *v, bus_space_handle_t h1, bus_size_t o1,
+ bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
+{
+ while (c--) {
+ elroy_w4(v, h1, o1, elroy_r4(v, h2, o2));
+ o1 += 4;
+ o2 += 4;
+ }
+}
+
+void
+elroy_cp_8(void *v, bus_space_handle_t h1, bus_size_t o1,
+ bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
+{
+ while (c--) {
+ elroy_w8(v, h1, o1, elroy_r8(v, h2, o2));
+ o1 += 8;
+ o2 += 8;
+ }
+}
+
+const struct hppa64_bus_space_tag elroy_iomemt = {
+ NULL,
+
+ NULL, elroy_unmap, elroy_subregion, NULL, elroy_free,
+ elroy_barrier,
+ elroy_r1, elroy_r2, elroy_r4, elroy_r8,
+ elroy_w1, elroy_w2, elroy_w4, elroy_w8,
+ elroy_rm_1, elroy_rm_2, elroy_rm_4, elroy_rm_8,
+ elroy_wm_1, elroy_wm_2, elroy_wm_4, elroy_wm_8,
+ elroy_sm_1, elroy_sm_2, elroy_sm_4, elroy_sm_8,
+ elroy_rrm_2, elroy_rrm_4, elroy_rrm_8,
+ elroy_wrm_2, elroy_wrm_4, elroy_wrm_8,
+ elroy_rr_1, elroy_rr_2, elroy_rr_4, elroy_rr_8,
+ elroy_wr_1, elroy_wr_2, elroy_wr_4, elroy_wr_8,
+ elroy_rrr_2, elroy_rrr_4, elroy_rrr_8,
+ elroy_wrr_2, elroy_wrr_4, elroy_wrr_8,
+ elroy_sr_1, elroy_sr_2, elroy_sr_4, elroy_sr_8,
+ elroy_cp_1, elroy_cp_2, elroy_cp_4, elroy_cp_8
+};
+
+int
+elroy_dmamap_create(void *v, bus_size_t size, int nsegments,
+ bus_size_t maxsegsz, bus_size_t boundary, int flags, bus_dmamap_t *dmamp)
+{
+ struct elroy_softc *sc = v;
+
+ /* TODO check the addresses, boundary, enable dma */
+
+ return (bus_dmamap_create(sc->sc_dmat, size, nsegments,
+ maxsegsz, boundary, flags, dmamp));
+}
+
+void
+elroy_dmamap_destroy(void *v, bus_dmamap_t map)
+{
+ struct elroy_softc *sc = v;
+
+ bus_dmamap_destroy(sc->sc_dmat, map);
+}
+
+int
+elroy_dmamap_load(void *v, bus_dmamap_t map, void *addr, bus_size_t size,
+ struct proc *p, int flags)
+{
+ struct elroy_softc *sc = v;
+
+ return (bus_dmamap_load(sc->sc_dmat, map, addr, size, p, flags));
+}
+
+int
+elroy_dmamap_load_mbuf(void *v, bus_dmamap_t map, struct mbuf *m, int flags)
+{
+ struct elroy_softc *sc = v;
+
+ return (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, flags));
+}
+
+int
+elroy_dmamap_load_uio(void *v, bus_dmamap_t map, struct uio *uio, int flags)
+{
+ struct elroy_softc *sc = v;
+
+ return (bus_dmamap_load_uio(sc->sc_dmat, map, uio, flags));
+}
+
+int
+elroy_dmamap_load_raw(void *v, bus_dmamap_t map, bus_dma_segment_t *segs,
+ int nsegs, bus_size_t size, int flags)
+{
+ struct elroy_softc *sc = v;
+
+ return (bus_dmamap_load_raw(sc->sc_dmat, map, segs, nsegs, size, flags));
+}
+
+void
+elroy_dmamap_unload(void *v, bus_dmamap_t map)
+{
+ struct elroy_softc *sc = v;
+
+ bus_dmamap_unload(sc->sc_dmat, map);
+}
+
+void
+elroy_dmamap_sync(void *v, bus_dmamap_t map, bus_addr_t off,
+ bus_size_t len, int ops)
+{
+ struct elroy_softc *sc = v;
+
+ return (bus_dmamap_sync(sc->sc_dmat, map, off, len, ops));
+}
+
+int
+elroy_dmamem_alloc(void *v, bus_size_t size, bus_size_t alignment,
+ bus_size_t boundary, bus_dma_segment_t *segs,
+ int nsegs, int *rsegs, int flags)
+{
+ struct elroy_softc *sc = v;
+
+ return (bus_dmamem_alloc(sc->sc_dmat, size, alignment, boundary,
+ segs, nsegs, rsegs, flags));
+}
+
+void
+elroy_dmamem_free(void *v, bus_dma_segment_t *segs, int nsegs)
+{
+ struct elroy_softc *sc = v;
+
+ bus_dmamem_free(sc->sc_dmat, segs, nsegs);
+}
+
+int
+elroy_dmamem_map(void *v, bus_dma_segment_t *segs, int nsegs, size_t size,
+ caddr_t *kvap, int flags)
+{
+ struct elroy_softc *sc = v;
+
+ return (bus_dmamem_map(sc->sc_dmat, segs, nsegs, size, kvap, flags));
+}
+
+void
+elroy_dmamem_unmap(void *v, caddr_t kva, size_t size)
+{
+ struct elroy_softc *sc = v;
+
+ bus_dmamem_unmap(sc->sc_dmat, kva, size);
+}
+
+paddr_t
+elroy_dmamem_mmap(void *v, bus_dma_segment_t *segs, int nsegs, off_t off,
+ int prot, int flags)
+{
+ struct elroy_softc *sc = v;
+
+ return (bus_dmamem_mmap(sc->sc_dmat, segs, nsegs, off, prot, flags));
+}
+
+const struct hppa64_bus_dma_tag elroy_dmat = {
+ NULL,
+ elroy_dmamap_create, elroy_dmamap_destroy,
+ elroy_dmamap_load, elroy_dmamap_load_mbuf,
+ elroy_dmamap_load_uio, elroy_dmamap_load_raw,
+ elroy_dmamap_unload, elroy_dmamap_sync,
+
+ elroy_dmamem_alloc, elroy_dmamem_free, elroy_dmamem_map,
+ elroy_dmamem_unmap, elroy_dmamem_mmap
+};
+
+const struct hppa64_pci_chipset_tag elroy_pc = {
+ NULL,
+ elroy_attach_hook, elroy_maxdevs, elroy_make_tag, elroy_decompose_tag,
+ elroy_conf_read, elroy_conf_write,
+ apic_intr_map, apic_intr_string,
+ apic_intr_establish, apic_intr_disestablish,
+#if NCARDBUS > 0
+ elroy_alloc_parent
+#else
+ NULL
+#endif
+};
+
+int
+elroyprint(void *aux, const char *pnp)
+{
+ struct pcibus_attach_args *pba = aux;
+
+ if (pnp)
+ printf("%s at %s\n", pba->pba_busname, pnp);
+ return (UNCONF);
+}
+
+void
+elroyattach(parent, self, aux)
+ struct device *parent;
+ struct device *self;
+ void *aux;
+{
+ struct elroy_softc *sc = (struct elroy_softc *)self;
+ struct confargs *ca = (struct confargs *)aux;
+ struct pcibus_attach_args pba;
+ volatile struct elroy_regs *r;
+ const char *p = NULL, *q;
+ int i;
+
+ sc->sc_bt = ca->ca_iot;
+ sc->sc_dmat = ca->ca_dmatag;
+ if (bus_space_map(sc->sc_bt, ca->ca_hpa, ca->ca_hpasz, 0, &sc->sc_bh)) {
+ printf(": can't map space\n");
+ return;
+ }
+
+ sc->sc_regs = r = (void *)bus_space_vaddr(sc->sc_bt, sc->sc_bh);
+ elroy_write32(&r->pci_cmdstat, htole32(PCI_COMMAND_IO_ENABLE |
+ PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE));
+
+ elroy_write32(&r->control, elroy_read32(&r->control) &
+ ~htole32(ELROY_CONTROL_RF));
+ for (i = 5000; i-- &&
+ elroy_read32(&r->status) & htole32(ELROY_STATUS_RC); DELAY(10));
+ if (i < 0) {
+ printf(": reset failed; status %b\n",
+ ELROY_STATUS_BITS, htole32(r->status));
+ return;
+ }
+
+ q = "";
+ sc->sc_ver = PCI_REVISION(letoh32(elroy_read32(&r->pci_class)));
+ switch ((ca->ca_type.iodc_model << 4) |
+ (ca->ca_type.iodc_revision >> 4)) {
+ case 0x782:
+ p = "Elroy";
+ switch (sc->sc_ver) {
+ default:
+ q = "+";
+ case 5: sc->sc_ver = 0x40; break;
+ case 4: sc->sc_ver = 0x30; break;
+ case 3: sc->sc_ver = 0x22; break;
+ case 2: sc->sc_ver = 0x21; break;
+ case 1: sc->sc_ver = 0x20; break;
+ case 0: sc->sc_ver = 0x10; break;
+ }
+ break;
+
+ case 0x783:
+ p = "Mercury";
+ break;
+
+ case 0x784:
+ p = "Quicksilver";
+ break;
+
+ default:
+ p = "Mojo";
+ break;
+ }
+
+ printf(": %s TR%d.%d%s", p, sc->sc_ver >> 4, sc->sc_ver & 0xf, q);
+ apic_attach(sc);
+
+ /* TODO reserve elroy's pci space ? */
+
+printf("lmm %llx/%llx gmm %llx/%llx wlm %llx/%llx wgm %llx/%llx io %llx/%llx eio %llx/%llx\n",
+letoh64(r->lmmio_base), letoh64(r->lmmio_mask),
+letoh64(r->gmmio_base), letoh64(r->gmmio_mask),
+letoh64(r->wlmmio_base), letoh64(r->wlmmio_mask),
+letoh64(r->wgmmio_base), letoh64(r->wgmmio_mask),
+letoh64(r->io_base), letoh64(r->io_mask),
+letoh64(r->eio_base), letoh64(r->eio_mask));
+
+ /* XXX evil hack! */
+ sc->sc_iobase = 0xfee00000;
+
+ sc->sc_iot = elroy_iomemt;
+ sc->sc_iot.hbt_cookie = sc;
+ sc->sc_iot.hbt_map = elroy_iomap;
+ sc->sc_iot.hbt_alloc = elroy_ioalloc;
+ sc->sc_memt = elroy_iomemt;
+ sc->sc_memt.hbt_cookie = sc;
+ sc->sc_memt.hbt_map = elroy_memmap;
+ sc->sc_memt.hbt_alloc = elroy_memalloc;
+ sc->sc_pc = elroy_pc;
+ sc->sc_pc._cookie = sc;
+ sc->sc_dmatag = elroy_dmat;
+ sc->sc_dmatag._cookie = sc;
+
+ pba.pba_busname = "pci";
+ pba.pba_iot = &sc->sc_iot;
+ pba.pba_memt = &sc->sc_memt;
+ pba.pba_dmat = &sc->sc_dmatag;
+ pba.pba_pc = &sc->sc_pc;
+ pba.pba_bus = 0; /* (letoh32(elroy_read32(&r->busnum)) & 0xff) >> 4; */
+ config_found(self, &pba, elroyprint);
+
+ /* enable interrupts now that all the devices are there */
+ /* r->imr = sc->sc_imr; */
+}
diff --git a/sys/arch/hppa64/dev/elroyreg.h b/sys/arch/hppa64/dev/elroyreg.h
new file mode 100644
index 00000000000..0ffaa3875d1
--- /dev/null
+++ b/sys/arch/hppa64/dev/elroyreg.h
@@ -0,0 +1,146 @@
+/* $OpenBSD: elroyreg.h,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+struct elroy_regs {
+ /* std PCI bridge header */
+ u_int32_t pci_id; /* 0x000 rw PCI_ID */
+ u_int32_t pci_cmdstat; /* 0x004 rw PCI_COMMAND_STATUS_REG */
+ u_int32_t pci_class; /* 0x008 ro PCI_CLASS_REG */
+ u_int32_t pci_bhlc; /* 0x00c rw PCI_BHLC_REG */
+ u_int32_t res0[0x30/4]; /* 0x010 */
+
+ /* HW Bridge registers */
+ u_int32_t pci_conf_addr; /* 0x040 rw config space address */
+ u_int32_t pad040;
+ u_int32_t pci_conf_data; /* 0x048 rw config space data */
+ u_int32_t pad048;
+ u_int64_t elroy_mtlt; /* 0x050 */
+ u_int32_t busnum; /* 0x058 bus number/scratch */
+ u_int32_t par058;
+ u_int64_t res1; /* 0x060 */
+ u_int64_t rope; /* 0x068 rope parity, loopback */
+ u_int64_t err_addr; /* 0x070 error log: address */
+ u_int64_t suspend; /* 0x078 rw suspend control */
+ u_int32_t arb_mask; /* 0x080 rw arbitration mask */
+ u_int32_t pad080;
+#define ELROY_ARB_ENABLE 0x01 /* enable arbitration */
+#define ELROY_ARB_PCIDEVA 0x02 /* PCI device A allow */
+#define ELROY_ARB_PCIDEVB 0x04 /* PCI device A allow */
+#define ELROY_ARB_PCIDEVC 0x08 /* PCI device A allow */
+#define ELROY_ARB_PCIDEVD 0x10 /* PCI device A allow */
+#define ELROY_ARB_PCIDEVE 0x20 /* PCI device A allow */
+#define ELROY_ARB_PCIDEVF 0x40 /* PCI device A allow */
+#define ELROY_ARB_PCIDEVG 0x80 /* PCI device A allow */
+ u_int64_t arb_pri; /* 0x088 arbitration priority */
+ u_int64_t arb_mode; /* 0x090 arbitration mode */
+ u_int64_t mtlt; /* 0x098 */
+ u_int64_t res2[12]; /* 0x0a0 */
+ u_int64_t mod_info; /* 0x100 */
+ u_int32_t control; /* 0x108 */
+#define ELROY_CONTROL_RF 0x01 /* reset pci */
+#define ELROY_CONTROL_VE 0x08 /* VGA enable */
+#define ELROY_CONTROL_CL 0x10 /* clear error log */
+#define ELROY_CONTROL_CE 0x20 /* clear error log enable */
+#define ELROY_CONTROL_HF 0x40 /* hard fail enable */
+ u_int32_t status; /* 0x10c */
+#define ELROY_STATUS_RC 0x01 /* reset complete */
+#define ELROY_STATUS_BITS "\020\01RC"
+ u_int64_t res3[30]; /* 0x110 */
+ u_int64_t lmmio_base; /* 0x200 */
+ u_int64_t lmmio_mask; /* 0x208 */
+ u_int64_t gmmio_base; /* 0x210 */
+ u_int64_t gmmio_mask; /* 0x218 */
+ u_int64_t wlmmio_base; /* 0x220 */
+ u_int64_t wlmmio_mask; /* 0x228 */
+ u_int64_t wgmmio_base; /* 0x230 */
+ u_int64_t wgmmio_mask; /* 0x238 */
+ u_int32_t io_base; /* 0x240 */
+ u_int32_t pad240;
+ u_int32_t io_mask; /* 0x248 */
+ u_int32_t pad248;
+ u_int32_t res4[4]; /* 0x250 */
+ u_int32_t eio_base; /* 0x260 */
+ u_int32_t pad260;
+ u_int32_t eio_mask; /* 0x268 */
+ u_int32_t pad268;
+#define ELROY_BASE_RE 0x01 /* range enable */
+ u_int64_t res5; /* 0x270 */
+ u_int64_t dmac_ctrl; /* 0x278 DMA connection control */
+ u_int64_t res6[16]; /* 0x280 */
+ u_int64_t ibase; /* 0x300 */
+ u_int64_t imask; /* 0x308 */
+ u_int64_t hint_cfg; /* 0x310 */
+ u_int64_t res7[13]; /* 0x318 */
+ u_int64_t hints[14]; /* 0x380 */
+ u_int64_t res8[2]; /* 0x3f0 */
+ u_int64_t res9[64]; /* 0x400 */
+ u_int64_t pad0; /* 0x600 */
+ u_int64_t pci_drive; /* 0x608 */
+ u_int64_t rope_cfg; /* 0x610 */
+ u_int64_t clk_ctl; /* 0x618 */
+ u_int32_t pad1; /* 0x620 */
+ u_int32_t res10[23]; /* 0x624 */
+ u_int32_t err_cfg; /* 0x680 error config */
+ u_int32_t pad680;
+#define ELROY_ERRCFG_PW 0x01 /* PIO writes parity errors */
+#define ELROY_ERRCFG_PR 0x02 /* PIO reads parity errors */
+#define ELROY_ERRCFG_DW 0x04 /* DMA writes parity errors */
+#define ELROY_ERRCFG_DR 0x08 /* DMA reads parity errors */
+#define ELROY_ERRCFG_CM 0x10 /* no fatal on config space */
+#define ELROY_ERRCFG_SMART 0x20 /* smart bus mode */
+ u_int64_t err_stat; /* 0x688 error status */
+ u_int64_t err_mid; /* 0x690 error log: master id */
+ u_int64_t rope_estat; /* 0x698 rope error status */
+ u_int64_t rope_eclr; /* 0x6a0 rope error clear */
+ u_int64_t res11[42]; /* 0x6a8 */
+ u_int64_t regbus; /* 0x7f8 reads 0x3ff */
+ u_int32_t apic_addr; /* 0x800 APIC address register */
+ u_int32_t pad800;
+ u_int64_t res12;
+ u_int32_t apic_data; /* 0x810 APIC data register */
+ u_int32_t pad808;
+ u_int64_t res13[5];
+ u_int32_t apic_eoi; /* 0x840 APIC interrupt ack */
+ u_int32_t pad840;
+ u_int32_t apic_softint; /* 0x850 write generates softint */
+ u_int32_t pad850;
+ u_int64_t res14[123]; /* 0x858 */
+ /*0x1000 */
+} __packed;
+
+/* APIC registers */
+#define APIC_VERSION 0x01
+#define APIC_VERSION_MASK 0xff
+#define APIC_VERSION_NENT 0xff0000
+#define APIC_VERSION_NENT_SHIFT 16
+#define APIC_ENT0(i) (0x10 + (i)*2)
+#define APIC_ENT0_VEC 0x000ff
+#define APIC_ENT0_MOD 0x00700 /* delivery mode */
+#define APIC_ENT0_FXD 0x00000
+#define APIC_ENT0_RDR 0x00100
+#define APIC_ENT0_PMI 0x00200
+#define APIC_ENT0_NMI 0x00400
+#define APIC_ENT0_INI 0x00500
+#define APIC_ENT0_EXT 0x00700
+#define APIC_ENT0_PEND 0x01000 /* int is pending */
+#define APIC_ENT0_LOW 0x02000 /* polarity */
+#define APIC_ENT0_LEV 0x08000 /* edge/level */
+#define APIC_ENT0_MASK 0x10000 /* mask int */
+#define APIC_ENT1(i) (0x11 + (i)*2)
+
diff --git a/sys/arch/hppa64/dev/elroyvar.h b/sys/arch/hppa64/dev/elroyvar.h
new file mode 100644
index 00000000000..921d1f0b4d5
--- /dev/null
+++ b/sys/arch/hppa64/dev/elroyvar.h
@@ -0,0 +1,50 @@
+/* $OpenBSD: elroyvar.h,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+struct elroy_softc {
+ struct device sc_dv;
+
+ int sc_ver;
+ bus_space_tag_t sc_bt;
+ bus_space_handle_t sc_bh;
+ bus_dma_tag_t sc_dmat;
+ volatile struct elroy_regs *sc_regs;
+ bus_addr_t sc_iobase;
+
+ u_int32_t sc_imr;
+ int sc_nints;
+
+ struct hppa64_pci_chipset_tag sc_pc;
+ struct hppa64_bus_space_tag sc_iot;
+ struct hppa64_bus_space_tag sc_memt;
+ char sc_memexname[20];
+ struct extent *sc_memex;
+ struct hppa64_bus_dma_tag sc_dmatag;
+};
+
+void apic_attach(struct elroy_softc *sc);
+int apic_intr(void *v);
+int apic_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp);
+const char *apic_intr_string(void *v, pci_intr_handle_t ih);
+void *apic_intr_establish(void *v, pci_intr_handle_t ih, int pri,
+ int (*handler)(void *), void *arg, char *name);
+void apic_intr_disestablish(void *v, void *cookie);
+
+void elroy_write32(volatile u_int32_t *p, u_int32_t v);
+u_int32_t elroy_read32(volatile u_int32_t *p);
diff --git a/sys/arch/hppa64/dev/mem.c b/sys/arch/hppa64/dev/mem.c
new file mode 100644
index 00000000000..4b6fcc17fe0
--- /dev/null
+++ b/sys/arch/hppa64/dev/mem.c
@@ -0,0 +1,268 @@
+/* $OpenBSD: mem.c,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * Copyright (c) 1991,1992,1994, The University of Utah and
+ * the Computer Systems Laboratory (CSL). All rights reserved.
+ *
+ * Subject to your agreements with CMU,
+ * permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
+ * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
+ * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * CSL requests users of this software to return to csl-dist@cs.utah.edu any
+ * improvements that they make and grant CSL redistribution rights.
+ *
+ * Utah $Hdr: mem.c 1.9 94/12/16$
+ */
+/*
+ * Mach Operating System
+ * Copyright (c) 1992 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/malloc.h>
+#include <sys/proc.h>
+#include <sys/uio.h>
+#include <sys/types.h>
+#include <sys/device.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#include <sys/file.h>
+
+#include <uvm/uvm.h>
+
+#include <machine/conf.h>
+#include <machine/bus.h>
+#include <machine/iomod.h>
+#include <machine/autoconf.h>
+#include <machine/pmap.h>
+
+struct mem_softc {
+ struct device sc_dev;
+};
+
+int memmatch(struct device *, void *, void *);
+void memattach(struct device *, struct device *, void *);
+
+struct cfattach mem_ca = {
+ sizeof(struct mem_softc), memmatch, memattach
+};
+
+struct cfdriver mem_cd = {
+ NULL, "mem", DV_DULL
+};
+
+caddr_t zeropage;
+
+int
+memmatch(parent, cfdata, aux)
+ struct device *parent;
+ void *cfdata;
+ void *aux;
+{
+ struct confargs *ca = aux;
+
+ if (strcmp(ca->ca_name, "memory"))
+ return 0;
+
+ return 1;
+}
+
+void
+memattach(parent, self, aux)
+ struct device *parent;
+ struct device *self;
+ void *aux;
+{
+ struct pdc_iodc_minit pdc_minit PDC_ALIGNMENT;
+ /* struct mem_softc *sc = (struct mem_softc *)self; */
+ struct confargs *ca = aux;
+ int err;
+
+/* TODO scan the memory regions list */
+
+ if ((err = pdc_call((iodcio_t)pdc, 0, PDC_IODC, PDC_IODC_NINIT,
+ &pdc_minit, ca->ca_hpa, PAGE0->imm_spa_size)) < 0)
+ pdc_minit.max_spa = PAGE0->imm_max_mem;
+
+ printf(": size %d", pdc_minit.max_spa / (1024*1024));
+ if (pdc_minit.max_spa % (1024*1024))
+ printf(".%d", pdc_minit.max_spa % (1024*1024));
+ printf("MB\n");
+}
+
+int
+mmopen(dev, flag, ioflag, p)
+ dev_t dev;
+ int flag;
+ int ioflag;
+ struct proc *p;
+{
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+mmclose(dev, flag, mode, p)
+ dev_t dev;
+ int flag, mode;
+ struct proc *p;
+{
+ return (0);
+}
+
+int
+mmrw(dev, uio, flags)
+ dev_t dev;
+ struct uio *uio;
+ int flags;
+{
+ struct iovec *iov;
+ vaddr_t v, o;
+ int error = 0;
+ u_int c;
+
+ while (uio->uio_resid > 0 && error == 0) {
+ iov = uio->uio_iov;
+ if (iov->iov_len == 0) {
+ uio->uio_iov++;
+ uio->uio_iovcnt--;
+ if (uio->uio_iovcnt < 0)
+ panic("mmrw");
+ continue;
+ }
+ switch (minor(dev)) {
+
+ case 0: /* /dev/mem */
+
+ /* If the address isn't in RAM, bail. */
+ v = uio->uio_offset;
+ if (btoc(v) > physmem) {
+ error = EFAULT;
+ /* this will break us out of the loop */
+ continue;
+ }
+ c = ctob(physmem) - v;
+ c = min(c, uio->uio_resid);
+ error = uiomove((caddr_t)v, c, uio);
+ break;
+
+ case 1: /* /dev/kmem */
+ v = uio->uio_offset;
+ o = v & PAGE_MASK;
+ c = min(uio->uio_resid, (int)(PAGE_SIZE - o));
+ if (btoc(v) > physmem && !uvm_kernacc((caddr_t)v,
+ c, (uio->uio_rw == UIO_READ) ? B_READ : B_WRITE)) {
+ error = EFAULT;
+ /* this will break us out of the loop */
+ continue;
+ }
+ error = uiomove((caddr_t)v, c, uio);
+ break;
+
+ case 2: /* /dev/null */
+ if (uio->uio_rw == UIO_WRITE)
+ uio->uio_resid = 0;
+ return (0);
+
+ case 12: /* /dev/zero */
+ /* Write to /dev/zero is ignored. */
+ if (uio->uio_rw == UIO_WRITE) {
+ uio->uio_resid = 0;
+ return (0);
+ }
+ /*
+ * On the first call, allocate and zero a page
+ * of memory for use with /dev/zero.
+ */
+ if (zeropage == NULL) {
+ zeropage = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
+ bzero(zeropage, PAGE_SIZE);
+ }
+ c = min(iov->iov_len, PAGE_SIZE);
+ error = uiomove(zeropage, c, uio);
+ break;
+
+ default:
+ return (ENXIO);
+ }
+ }
+
+ return (error);
+}
+
+paddr_t
+mmmmap(dev, off, prot)
+ dev_t dev;
+ off_t off;
+ int prot;
+{
+ if (minor(dev) != 0)
+ return (-1);
+
+ /*
+ * Allow access only in RAM.
+ */
+#if 0
+ if (off < ctob(firstusablepage) ||
+ off >= ctob(lastusablepage + 1))
+ return (-1);
+#endif
+ return (btop(off));
+}
+
+int
+mmioctl(dev, cmd, data, flags, p)
+ dev_t dev;
+ u_long cmd;
+ caddr_t data;
+ int flags;
+ struct proc *p;
+{
+ return (EOPNOTSUPP);
+}
diff --git a/sys/arch/hppa64/dev/pdc.c b/sys/arch/hppa64/dev/pdc.c
new file mode 100644
index 00000000000..2f9764f6d5c
--- /dev/null
+++ b/sys/arch/hppa64/dev/pdc.c
@@ -0,0 +1,469 @@
+/* $OpenBSD: pdc.c,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "com.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/tty.h>
+#include <sys/user.h>
+#include <sys/timeout.h>
+
+#include <dev/cons.h>
+
+#include <machine/conf.h>
+#include <machine/pdc.h>
+#include <machine/iomod.h>
+#include <machine/autoconf.h>
+
+typedef
+struct pdc_softc {
+ struct device sc_dv;
+ struct tty *sc_tty;
+ struct timeout sc_to;
+} pdcsoftc_t;
+
+pdcio_t pdc;
+int pdcret[32] PDC_ALIGNMENT;
+char pdc_consbuf[IODC_MINIOSIZ] PDC_ALIGNMENT;
+iodcio_t pdc_cniodc, pdc_kbdiodc;
+pz_device_t *pz_kbd, *pz_cons;
+hppa_hpa_t conaddr;
+int conunit;
+
+int pdcmatch(struct device *, void *, void *);
+void pdcattach(struct device *, struct device *, void *);
+
+struct cfattach pdc_ca = {
+ sizeof(pdcsoftc_t), pdcmatch, pdcattach
+};
+
+struct cfdriver pdc_cd = {
+ NULL, "pdc", DV_DULL
+};
+
+void pdcstart(struct tty *tp);
+void pdctimeout(void *v);
+int pdcparam(struct tty *tp, struct termios *);
+int pdccnlookc(dev_t dev, int *cp);
+
+#if NCOM_GSC > 0
+/* serial console speed table */
+static int pdc_speeds[] = {
+ B50,
+ B75,
+ B110,
+ B150,
+ B300,
+ B600,
+ B1200,
+ B2400,
+ B4800,
+ B7200,
+ B9600,
+ B19200,
+ B38400,
+ B57600,
+ B115200,
+ B230400,
+};
+#endif
+
+void
+pdc_init()
+{
+ static int kbd_iodc[IODC_MAXSIZE/sizeof(int)];
+ static int cn_iodc[IODC_MAXSIZE/sizeof(int)];
+ int err;
+
+ /* XXX make pdc current console */
+ cn_tab = &constab[0];
+
+ /* pdc = (pdcio_t)(long)PAGE0->mem_pdc; */
+ pz_kbd = &PAGE0->mem_kbd;
+ pz_cons = &PAGE0->mem_cons;
+
+ /* XXX should we reset the console/kbd here?
+ well, /boot did that for us anyway */
+ if ((err = pdc_call((iodcio_t)pdc, 0, PDC_IODC, PDC_IODC_READ, pdcret,
+ pz_cons->pz_hpa, IODC_IO, cn_iodc, (long)IODC_MAXSIZE)) < 0 ||
+ (err = pdc_call((iodcio_t)pdc, 0, PDC_IODC, PDC_IODC_READ, pdcret,
+ pz_kbd->pz_hpa, IODC_IO, kbd_iodc, (long)IODC_MAXSIZE)) < 0) {
+#ifdef DEBUG
+ printf("pdc_init: failed reading IODC (%d)\n", err);
+#endif
+ }
+
+ pdc_cniodc = (iodcio_t)cn_iodc;
+ pdc_kbdiodc = (iodcio_t)kbd_iodc;
+
+ /* setup the console */
+#if NCOM_GSC > 0
+ if (PAGE0->mem_cons.pz_class == PCL_DUPLEX) {
+ struct pz_device *pzd = &PAGE0->mem_cons;
+ extern int comdefaultrate;
+#ifdef DEBUG
+ printf("console: class %d flags %b ",
+ pzd->pz_class, pzd->pz_flags, PZF_BITS);
+ printf("bc %d/%d/%d/%d/%d/%d ",
+ pzd->pz_bc[0], pzd->pz_bc[1], pzd->pz_bc[2],
+ pzd->pz_bc[3], pzd->pz_bc[4], pzd->pz_bc[5]);
+ printf("mod %x layers %x/%x/%x/%x/%x/%x hpa %x\n", pzd->pz_mod,
+ pzd->pz_layers[0], pzd->pz_layers[1], pzd->pz_layers[2],
+ pzd->pz_layers[3], pzd->pz_layers[4], pzd->pz_layers[5],
+ pzd->pz_hpa);
+#endif
+ conaddr = (u_long)pzd->pz_hpa + IOMOD_DEVOFFSET;
+ conunit = 0;
+
+ /* compute correct baud rate */
+ if (PZL_SPEED(pzd->pz_layers[0]) <
+ sizeof(pdc_speeds) / sizeof(int))
+ comdefaultrate =
+ pdc_speeds[PZL_SPEED(pzd->pz_layers[0])];
+ else
+ comdefaultrate = B9600; /* XXX */
+ }
+#endif
+}
+
+int
+pdcmatch(parent, cfdata, aux)
+ struct device *parent;
+ void *cfdata;
+ void *aux;
+{
+ struct cfdata *cf = cfdata;
+ struct confargs *ca = aux;
+
+ /* there could be only one */
+ if (cf->cf_unit > 0 && !strcmp(ca->ca_name, "pdc"))
+ return 0;
+
+ return 1;
+}
+
+void
+pdcattach(parent, self, aux)
+ struct device *parent;
+ struct device *self;
+ void *aux;
+{
+ struct pdc_softc *sc = (struct pdc_softc *)self;
+
+ if (!pdc)
+ pdc_init();
+
+ printf("\n");
+
+ timeout_set(&sc->sc_to, pdctimeout, sc);
+}
+
+int
+pdcopen(dev, flag, mode, p)
+ dev_t dev;
+ int flag, mode;
+ struct proc *p;
+{
+ int unit = minor(dev);
+ struct pdc_softc *sc;
+ struct tty *tp;
+ int s;
+ int error = 0, setuptimeout = 0;
+
+ if (unit >= pdc_cd.cd_ndevs || (sc = pdc_cd.cd_devs[unit]) == NULL)
+ return ENXIO;
+
+ s = spltty();
+
+ if (sc->sc_tty)
+ tp = sc->sc_tty;
+ else {
+ tp = sc->sc_tty = ttymalloc();
+ }
+
+ tp->t_oproc = pdcstart;
+ tp->t_param = pdcparam;
+ tp->t_dev = dev;
+ if ((tp->t_state & TS_ISOPEN) == 0) {
+ ttychars(tp);
+ tp->t_iflag = TTYDEF_IFLAG;
+ tp->t_oflag = TTYDEF_OFLAG;
+ tp->t_cflag = TTYDEF_CFLAG|CLOCAL;
+ tp->t_lflag = TTYDEF_LFLAG;
+ tp->t_ispeed = tp->t_ospeed = B9600;
+ ttsetwater(tp);
+
+ setuptimeout = 1;
+ } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) {
+ splx(s);
+ return (EBUSY);
+ }
+ tp->t_state |= TS_CARR_ON;
+ splx(s);
+
+ error = (*linesw[tp->t_line].l_open)(dev, tp);
+ if (error == 0 && setuptimeout)
+ pdctimeout(sc);
+
+ return error;
+}
+
+int
+pdcclose(dev, flag, mode, p)
+ dev_t dev;
+ int flag, mode;
+ struct proc *p;
+{
+ int unit = minor(dev);
+ struct tty *tp;
+ struct pdc_softc *sc;
+
+ if (unit >= pdc_cd.cd_ndevs || (sc = pdc_cd.cd_devs[unit]) == NULL)
+ return ENXIO;
+
+ tp = sc->sc_tty;
+ timeout_del(&sc->sc_to);
+ (*linesw[tp->t_line].l_close)(tp, flag);
+ ttyclose(tp);
+ return 0;
+}
+
+int
+pdcread(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ int unit = minor(dev);
+ struct tty *tp;
+ struct pdc_softc *sc;
+
+ if (unit >= pdc_cd.cd_ndevs || (sc = pdc_cd.cd_devs[unit]) == NULL)
+ return ENXIO;
+
+ tp = sc->sc_tty;
+ return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
+}
+
+int
+pdcwrite(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ int unit = minor(dev);
+ struct tty *tp;
+ struct pdc_softc *sc;
+
+ if (unit >= pdc_cd.cd_ndevs || (sc = pdc_cd.cd_devs[unit]) == NULL)
+ return ENXIO;
+
+ tp = sc->sc_tty;
+ return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
+}
+
+int
+pdcioctl(dev, cmd, data, flag, p)
+ dev_t dev;
+ u_long cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+ int unit = minor(dev);
+ int error;
+ struct tty *tp;
+ struct pdc_softc *sc;
+
+ if (unit >= pdc_cd.cd_ndevs || (sc = pdc_cd.cd_devs[unit]) == NULL)
+ return ENXIO;
+
+ tp = sc->sc_tty;
+ error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
+ if (error >= 0)
+ return error;
+ error = ttioctl(tp, cmd, data, flag, p);
+ if (error >= 0)
+ return error;
+
+ return ENOTTY;
+}
+
+int
+pdcparam(tp, t)
+ struct tty *tp;
+ struct termios *t;
+{
+
+ return 0;
+}
+
+void
+pdcstart(tp)
+ struct tty *tp;
+{
+ int s;
+
+ s = spltty();
+ if (tp->t_state & (TS_TTSTOP | TS_BUSY)) {
+ splx(s);
+ return;
+ }
+ if (tp->t_outq.c_cc <= tp->t_lowat) {
+ if (tp->t_state & TS_ASLEEP) {
+ tp->t_state &= ~TS_ASLEEP;
+ wakeup((caddr_t)&tp->t_outq);
+ }
+ selwakeup(&tp->t_wsel);
+ }
+ tp->t_state |= TS_BUSY;
+ while (tp->t_outq.c_cc != 0)
+ pdccnputc(tp->t_dev, getc(&tp->t_outq));
+ tp->t_state &= ~TS_BUSY;
+ splx(s);
+}
+
+int
+pdcstop(tp, flag)
+ struct tty *tp;
+ int flag;
+{
+ int s;
+
+ s = spltty();
+ if (tp->t_state & TS_BUSY)
+ if ((tp->t_state & TS_TTSTOP) == 0)
+ tp->t_state |= TS_FLUSH;
+ splx(s);
+ return 0;
+}
+
+void
+pdctimeout(v)
+ void *v;
+{
+ struct pdc_softc *sc = v;
+ struct tty *tp = sc->sc_tty;
+ int c;
+
+ while (pdccnlookc(tp->t_dev, &c)) {
+ if (tp->t_state & TS_ISOPEN)
+ (*linesw[tp->t_line].l_rint)(c, tp);
+ }
+ timeout_add(&sc->sc_to, 1);
+}
+
+struct tty *
+pdctty(dev)
+ dev_t dev;
+{
+ int unit = minor(dev);
+ struct pdc_softc *sc;
+
+ if (unit >= pdc_cd.cd_ndevs || (sc = pdc_cd.cd_devs[unit]) == NULL)
+ return NULL;
+
+ return sc->sc_tty;
+}
+
+void
+pdccnprobe(cn)
+ struct consdev *cn;
+{
+ cn->cn_dev = makedev(22,0);
+ cn->cn_pri = CN_NORMAL;
+}
+
+void
+pdccninit(cn)
+ struct consdev *cn;
+{
+#ifdef DEBUG
+ printf("pdc0: console init\n");
+#endif
+}
+
+int
+pdccnlookc(dev, cp)
+ dev_t dev;
+ int *cp;
+{
+ int err, l;
+ int s = splhigh();
+
+ err = pdc_call(pdc_kbdiodc, 0, pz_kbd->pz_hpa, IODC_IO_CONSIN,
+ pz_kbd->pz_spa, pz_kbd->pz_layers, pdcret, 0, pdc_consbuf,
+ (long)1, (long)0);
+
+ l = pdcret[0];
+ *cp = pdc_consbuf[0];
+ splx(s);
+#ifdef DEBUG
+ if (err < 0)
+ printf("pdccnlookc: input error: %d\n", err);
+#endif
+
+ return l;
+}
+
+int
+pdccngetc(dev)
+ dev_t dev;
+{
+ int c;
+
+ if (!pdc)
+ return 0;
+
+ while(!pdccnlookc(dev, &c))
+ ;
+
+ return (c);
+}
+
+void
+pdccnputc(dev, c)
+ dev_t dev;
+ int c;
+{
+ register int err;
+ int s = splhigh();
+
+ *pdc_consbuf = c;
+ err = pdc_call(pdc_cniodc, 0, pz_cons->pz_hpa, IODC_IO_CONSOUT,
+ pz_cons->pz_spa, pz_cons->pz_layers, pdcret, 0, pdc_consbuf,
+ (long)1, (long)0);
+ splx(s);
+
+ if (err < 0) {
+#ifdef DEBUG
+ printf("pdccnputc: output error: %d\n", err);
+#endif
+ }
+}
+
+void
+pdccnpollc(dev, on)
+ dev_t dev;
+ int on;
+{
+
+}
diff --git a/sys/arch/hppa64/dev/pluto.c b/sys/arch/hppa64/dev/pluto.c
new file mode 100644
index 00000000000..f69dcc0d7a7
--- /dev/null
+++ b/sys/arch/hppa64/dev/pluto.c
@@ -0,0 +1,145 @@
+/* $OpenBSD: pluto.c,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* TODO IOA programming */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/reboot.h>
+
+#include <machine/iomod.h>
+#include <machine/autoconf.h>
+#include <machine/bus.h>
+
+struct pluto_regs {
+ u_int32_t version; /* 0x000: version */
+ u_int32_t pad00;
+ u_int32_t ctrl; /* 0x008: control register */
+#define PLUTO_CTRL_TOC 0x0001 /* enable toc */
+#define PLUTO_CTRL_COE 0x0002 /* enable coalescing */
+#define PLUTO_CTRL_DIE 0x0004 /* enable dillon */
+#define PLUTO_CTRL_RM 0x0010 /* real mode */
+#define PLUTO_CTRL_NCO 0x0020 /* non-coherent mode */
+ u_int32_t pad08;
+ u_int32_t resv0[(0x200-0x10)/4];
+ u_int64_t rope0; /* 0x200: */
+ u_int64_t rope1;
+ u_int64_t rope2;
+ u_int64_t rope3;
+ u_int64_t rope4;
+ u_int64_t rope5;
+ u_int64_t rope6;
+ u_int64_t rope7;
+ u_int32_t resv1[(0x100-0x40)/4];
+ u_int64_t ibase;
+ u_int64_t imask;
+ u_int64_t pcom;
+ u_int64_t tconf;
+ u_int64_t pdir;
+} __packed;
+
+struct pluto_softc {
+ struct device sc_dv;
+
+ struct pluto_regs volatile *sc_regs;
+};
+
+int plutomatch(struct device *, void *, void *);
+void plutoattach(struct device *, struct device *, void *);
+
+struct cfattach plut_ca = {
+ sizeof(struct pluto_softc), plutomatch, plutoattach
+};
+
+struct cfdriver plut_cd = {
+ NULL, "plut", DV_DULL
+};
+
+int
+plutomatch(parent, cfdata, aux)
+ struct device *parent;
+ void *cfdata;
+ void *aux;
+{
+ struct confargs *ca = aux;
+ /* struct cfdata *cf = cfdata; */
+
+ if (strcmp(ca->ca_name, "sba"))
+ return 0;
+
+ return 1;
+}
+
+void
+plutoattach(parent, self, aux)
+ struct device *parent;
+ struct device *self;
+ void *aux;
+{
+ struct confargs *ca = aux, nca;
+ struct pluto_softc *sc = (struct pluto_softc *)self;
+ struct pluto_regs volatile *r;
+ bus_space_handle_t ioh;
+ u_int32_t ver;
+ char buf[16];
+
+ if (bus_space_map(ca->ca_iot, ca->ca_hpa, ca->ca_hpasz, 0, &ioh)) {
+ printf(": can't map IO space\n");
+ return;
+ }
+ sc->sc_regs = r = (void *)bus_space_vaddr(ca->ca_iot, ioh);
+
+ /* r->ctrl = PLUTO_CTRL_RM|PLUTO_CTRL_TOC; */
+
+ ver = letoh32(r->version);
+ switch ((ca->ca_type.iodc_model << 4) |
+ (ca->ca_type.iodc_revision >> 4)) {
+ case 0x582:
+ case 0x780:
+ snprintf(buf, sizeof(buf), "Astro rev %d.%d",
+ (ver & 7) + 1, (ver >> 3) & 3);
+ break;
+
+ case 0x803:
+ case 0x781:
+ snprintf(buf, sizeof(buf), "Ike rev %d", ver & 0xff);
+ break;
+
+ case 0x804:
+ case 0x782:
+ snprintf(buf, sizeof(buf), "Reo rev %d", ver & 0xff);
+ break;
+
+ case 0x880:
+ case 0x784:
+ snprintf(buf, sizeof(buf), "Pluto rev %d.%d",
+ (ver >> 4) & 0xf, ver & 0xf);
+ break;
+
+ default:
+ snprintf(buf, sizeof(buf), "Fluffy rev 0x%x", ver);
+ break;
+ }
+
+ printf(": %s\n", buf);
+
+ nca = *ca; /* clone from us */
+ pdc_patscan(self, &nca, 0);
+}
diff --git a/sys/arch/hppa64/dev/power.c b/sys/arch/hppa64/dev/power.c
new file mode 100644
index 00000000000..ce3befc9523
--- /dev/null
+++ b/sys/arch/hppa64/dev/power.c
@@ -0,0 +1,142 @@
+/* $OpenBSD: power.c,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/reboot.h>
+#include <sys/device.h>
+#include <sys/kthread.h>
+
+#include <machine/reg.h>
+#include <machine/pdc.h>
+#include <machine/autoconf.h>
+
+struct power_softc {
+ struct device sc_dev;
+ void *sc_ih;
+
+ struct proc *sc_thread;
+ void (*sc_kicker)(void *);
+
+ int sc_dr_cnt;
+ paddr_t sc_pwr_reg;
+ volatile int sc_interrupted;
+};
+
+int powermatch(struct device *, void *, void *);
+void powerattach(struct device *, struct device *, void *);
+
+struct cfattach power_ca = {
+ sizeof(struct power_softc), powermatch, powerattach
+};
+
+struct cfdriver power_cd = {
+ NULL, "power", DV_DULL
+};
+
+void power_thread_create(void *v);
+void power_thread_reg(void *v);
+void power_cold_hook_reg(int);
+int power_intr(void *);
+
+int
+powermatch(struct device *parent, void *cfdata, void *aux)
+{
+ struct cfdata *cf = cfdata;
+ struct confargs *ca = aux;
+
+ if (cf->cf_unit > 0 && !strcmp(ca->ca_name, "power"))
+ return (0);
+
+ return (1);
+}
+
+void
+powerattach(struct device *parent, struct device *self, void *aux)
+{
+ struct power_softc *sc = (struct power_softc *)self;
+ struct confargs *ca = aux;
+
+ if (ca->ca_hpa) {
+ extern void (*cold_hook)(int);
+
+ sc->sc_pwr_reg = ca->ca_hpa;
+ cold_hook = power_cold_hook_reg;
+ sc->sc_kicker = power_thread_reg;
+ printf("\n");
+ } else
+ printf(": not available\n");
+
+ if (ca->ca_irq >= 0)
+ sc->sc_ih = cpu_intr_establish(IPL_CLOCK, ca->ca_irq,
+ power_intr, sc, sc->sc_dev.dv_xname);
+
+ if (sc->sc_kicker)
+ kthread_create_deferred(power_thread_create, sc);
+}
+
+int
+power_intr(void *v)
+{
+ struct power_softc *sc = v;
+
+ sc->sc_interrupted = 1;
+
+ return (1);
+}
+
+void
+power_thread_create(void *v)
+{
+ struct power_softc *sc = v;
+
+ if (kthread_create(sc->sc_kicker, sc, &sc->sc_thread,
+ sc->sc_dev.dv_xname))
+ printf("WARNING: failed to create kernel power thread\n");
+}
+
+void
+power_thread_reg(void *v)
+{
+ struct power_softc *sc = v;
+ u_int32_t r;
+
+ for (;;) {
+ __asm __volatile("ldwas 0(%1), %0"
+ : "=&r" (r) : "r" (sc->sc_pwr_reg));
+
+ if (!(r & 1))
+ boot(RB_POWERDOWN | RB_HALT);
+
+ tsleep(v, PWAIT, "regpower", 10);
+ }
+}
+
+void
+power_cold_hook_reg(int on)
+{
+ extern struct pdc_power_info pdc_power_info; /* machdep.c */
+ int error;
+
+ if ((error = pdc_call((iodcio_t)pdc, 0, PDC_SOFT_POWER,
+ PDC_SOFT_POWER_ENABLE, &pdc_power_info,
+ on == HPPA_COLD_HOT)))
+ printf("power_cold_hook_reg: failed (%d)\n", error);
+}
diff --git a/sys/arch/hppa64/hppa64/autoconf.c b/sys/arch/hppa64/hppa64/autoconf.c
new file mode 100644
index 00000000000..3605b9ec49b
--- /dev/null
+++ b/sys/arch/hppa64/hppa64/autoconf.c
@@ -0,0 +1,843 @@
+/* $OpenBSD: autoconf.c,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 1998-2005 Michael Shalayeff
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)autoconf.c 8.4 (Berkeley) 10/1/93
+ */
+
+#include "pci.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/disklabel.h>
+#include <sys/conf.h>
+#include <sys/reboot.h>
+#include <sys/device.h>
+#include <sys/timeout.h>
+
+#include <machine/iomod.h>
+#include <machine/autoconf.h>
+#include <machine/reg.h>
+
+#include <dev/cons.h>
+
+#include <hppa/dev/cpudevs.h>
+
+#if NPCI > 0
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+#endif
+
+void setroot(void);
+void swapconf(void);
+void dumpconf(void);
+
+int findblkmajor(struct device *dv);
+const char *findblkname(int maj);
+struct device *parsedisk(char *str, int len, int defpart, dev_t *devp);
+struct device *getdisk(char *str, int len, int defpart, dev_t *devp);
+int getstr(char *cp, int size);
+
+void (*cold_hook)(int); /* see below */
+
+/* device we booted from */
+struct device *bootdv;
+
+/*
+ * LED blinking thing
+ */
+#ifdef USELEDS
+#include <sys/dkstat.h>
+#include <sys/kernel.h>
+
+struct timeout heartbeat_tmo;
+void heartbeat(void *);
+#endif
+
+#include "cd.h"
+#include "sd.h"
+#include "st.h"
+#if NCD > 0 || NSD > 0 || NST > 0
+#include <scsi/scsi_all.h>
+#include <scsi/scsiconf.h>
+#endif
+
+/*
+ * cpu_configure:
+ * called at boot time, configure all devices on system
+ */
+void
+cpu_configure(void)
+{
+ struct confargs ca;
+
+ splhigh();
+ bzero(&ca, sizeof(ca));
+ if (config_rootfound("mainbus", &ca) == NULL)
+ panic("no mainbus found");
+
+ mtctl(0xffffffffffffffffULL, CR_EIEM);
+ spl0();
+
+ setroot();
+ swapconf();
+ dumpconf();
+ if (cold_hook)
+ (*cold_hook)(HPPA_COLD_HOT);
+
+#ifdef USELEDS
+ timeout_set(&heartbeat_tmo, heartbeat, NULL);
+ heartbeat(NULL);
+#endif
+ cold = 0;
+}
+
+#ifdef USELEDS
+/*
+ * turn the heartbeat alive.
+ * right thing would be to pass counter to each subsequent timeout
+ * as an argument to heartbeat() incrementing every turn,
+ * i.e. avoiding the static hbcnt, but doing timeout_set() on each
+ * timeout_add() sounds ugly, guts of struct timeout looks ugly
+ * to ponder in even more.
+ */
+void
+heartbeat(v)
+ void *v;
+{
+ static u_int hbcnt = 0, ocp_total, ocp_idle;
+ int toggle, cp_mask, cp_total, cp_idle;
+
+ timeout_add(&heartbeat_tmo, hz / 16);
+
+ cp_idle = cp_time[CP_IDLE];
+ cp_total = cp_time[CP_USER] + cp_time[CP_NICE] + cp_time[CP_SYS] +
+ cp_time[CP_INTR] + cp_time[CP_IDLE];
+ if (cp_total == ocp_total)
+ cp_total = ocp_total + 1;
+ if (cp_idle == ocp_idle)
+ cp_idle = ocp_idle + 1;
+ cp_mask = 0xf0 >> (cp_idle - ocp_idle) * 4 / (cp_total - ocp_total);
+ cp_mask &= 0xf0;
+ ocp_total = cp_total;
+ ocp_idle = cp_idle;
+ /*
+ * do this:
+ *
+ * |~| |~|
+ * _| |_| |_,_,_,_
+ * 0 1 2 3 4 6 7
+ */
+ toggle = 0;
+ if (hbcnt++ < 8 && hbcnt & 1)
+ toggle = PALED_HEARTBEAT;
+ hbcnt &= 15;
+ ledctl(cp_mask,
+ (~cp_mask & 0xf0) | PALED_NETRCV | PALED_NETSND | PALED_DISK,
+ toggle);
+}
+#endif
+
+/*
+ * Configure swap space and related parameters.
+ */
+void
+swapconf(void)
+{
+ struct swdevt *swp;
+ int nblks, maj;
+
+ for (swp = swdevt; swp->sw_dev != NODEV; swp++) {
+ maj = major(swp->sw_dev);
+ if (maj > nblkdev)
+ break;
+ if (bdevsw[maj].d_psize) {
+ nblks = (*bdevsw[maj].d_psize)(swp->sw_dev);
+ if (nblks != -1 &&
+ (swp->sw_nblks == 0 || swp->sw_nblks > nblks))
+ swp->sw_nblks = nblks;
+ swp->sw_nblks = ctod(dtoc(swp->sw_nblks));
+ }
+ }
+}
+
+/*
+ * This is called by configure to set dumplo and dumpsize.
+ * Dumps always skip the first CLBYTES of disk space
+ * in case there might be a disk label stored there.
+ * If there is extra space, put dump at the end to
+ * reduce the chance that swapping trashes it.
+ */
+void
+dumpconf(void)
+{
+ extern int dumpsize;
+ int nblks, dumpblks; /* size of dump area */
+ int maj;
+
+ if (dumpdev == NODEV)
+ goto bad;
+ maj = major(dumpdev);
+ if (maj < 0 || maj >= nblkdev)
+ panic("dumpconf: bad dumpdev=0x%x", dumpdev);
+ if (bdevsw[maj].d_psize == NULL)
+ goto bad;
+ nblks = (*bdevsw[maj].d_psize)(dumpdev);
+ if (nblks <= ctod(1))
+ goto bad;
+ dumpblks = cpu_dumpsize();
+ if (dumpblks < 0)
+ goto bad;
+ dumpblks += ctod(physmem);
+
+ /* If dump won't fit (incl. room for possible label), punt. */
+ if (dumpblks > (nblks - ctod(1)))
+ goto bad;
+
+ /* Put dump at end of partition */
+ dumplo = nblks - dumpblks;
+
+ /* dumpsize is in page units, and doesn't include headers. */
+ dumpsize = physmem;
+ return;
+
+bad:
+ dumpsize = 0;
+ return;
+}
+
+const struct nam2blk {
+ char name[4];
+ int maj;
+} nam2blk[] = {
+ { "rd", 3 },
+ { "sd", 4 },
+ { "st", 5 },
+ { "cd", 6 },
+#if 0
+ { "wd", ? },
+ { "fd", 7 },
+#endif
+};
+
+#ifdef RAMDISK_HOOKS
+struct device fakerdrootdev = { DV_DISK, {}, NULL, 0, "rd0", NULL };
+#endif
+
+int
+findblkmajor(dv)
+ struct device *dv;
+{
+ char *name = dv->dv_xname;
+ int i;
+
+ for (i = 0; i < sizeof(nam2blk)/sizeof(nam2blk[0]); ++i)
+ if (!strncmp(name, nam2blk[i].name, strlen(nam2blk[0].name)))
+ return (nam2blk[i].maj);
+ return (-1);
+}
+
+const char *
+findblkname(maj)
+ int maj;
+{
+ int i;
+
+ for (i = 0; i < sizeof(nam2blk) / sizeof(nam2blk[0]); ++i)
+ if (maj == nam2blk[i].maj)
+ return (nam2blk[i].name);
+ return (NULL);
+}
+
+struct device *
+getdisk(str, len, defpart, devp)
+ char *str;
+ int len, defpart;
+ dev_t *devp;
+{
+ struct device *dv;
+
+ if ((dv = parsedisk(str, len, defpart, devp)) == NULL) {
+ printf("use one of:");
+#ifdef RAMDISK_HOOKS
+ printf(" %s[a-p]", fakerdrootdev.dv_xname);
+#endif
+ for (dv = alldevs.tqh_first; dv != NULL;
+ dv = dv->dv_list.tqe_next) {
+ if (dv->dv_class == DV_DISK)
+ printf(" %s[a-p]", dv->dv_xname);
+#ifdef NFSCLIENT
+ if (dv->dv_class == DV_IFNET)
+ printf(" %s", dv->dv_xname);
+#endif
+ }
+ printf(" halt\n");
+ }
+ return (dv);
+}
+
+struct device *
+parsedisk(str, len, defpart, devp)
+ char *str;
+ int len, defpart;
+ dev_t *devp;
+{
+ struct device *dv;
+ char *cp, c;
+ int majdev, part;
+
+ if (len == 0)
+ return (NULL);
+
+ if (len == 4 && !strcmp(str, "halt"))
+ boot(RB_HALT);
+
+ cp = str + len - 1;
+ c = *cp;
+ if (c >= 'a' && c <= ('a' + MAXPARTITIONS - 1)) {
+ part = c - 'a';
+ *cp = '\0';
+ } else
+ part = defpart;
+
+#ifdef RAMDISK_HOOKS
+ if (strcmp(str, fakerdrootdev.dv_xname) == 0) {
+ dv = &fakerdrootdev;
+ goto gotdisk;
+ }
+#endif
+ for (dv = alldevs.tqh_first; dv != NULL; dv = dv->dv_list.tqe_next) {
+ if (dv->dv_class == DV_DISK &&
+ strcmp(str, dv->dv_xname) == 0) {
+#ifdef RAMDISK_HOOKS
+gotdisk:
+#endif
+ majdev = findblkmajor(dv);
+ if (majdev < 0)
+ panic("parsedisk");
+ *devp = MAKEDISKDEV(majdev, dv->dv_unit, part);
+ break;
+ }
+#ifdef NFSCLIENT
+ if (dv->dv_class == DV_IFNET &&
+ strcmp(str, dv->dv_xname) == 0) {
+ *devp = NODEV;
+ break;
+ }
+#endif
+ }
+
+ *cp = c;
+ return (dv);
+}
+
+void
+print_devpath(const char *label, struct pz_device *pz)
+{
+ int i;
+
+ printf("%s: ", label);
+
+ for (i = 0; i < 6; i++)
+ if (pz->pz_bc[i] >= 0)
+ printf("%d/", pz->pz_bc[i]);
+
+ printf("%d.%x", pz->pz_mod, pz->pz_layers[0]);
+ for (i = 1; i < 6 && pz->pz_layers[i]; i++)
+ printf(".%x", pz->pz_layers[i]);
+
+ printf(" class=%d flags=%b hpa=%p spa=%p io=%p\n", pz->pz_class,
+ pz->pz_flags, PZF_BITS, pz->pz_hpa, pz->pz_spa, pz->pz_iodc_io);
+}
+
+/*
+ * Attempt to find the device from which we were booted.
+ * If we can do so, and not instructed not to do so,
+ * change rootdev to correspond to the load device.
+ *
+ * XXX Actually, swap and root must be on the same type of device,
+ * (ie. DV_DISK or DV_IFNET) because of how (*mountroot) is written.
+ * That should be fixed.
+ */
+void
+setroot(void)
+{
+ struct swdevt *swp;
+ struct device *dv;
+ int len, majdev, part;
+ dev_t nrootdev, nswapdev = NODEV;
+ char buf[128];
+ dev_t temp;
+ const char *rootdevname;
+ struct device *rootdv, *swapdv;
+#ifdef NFSCLIENT
+ extern char *nfsbootdevname;
+#endif
+
+#ifdef RAMDISK_HOOKS
+ bootdv = &fakerdrootdev;
+#endif
+ part = 0;
+
+ print_devpath("boot path", &PAGE0->mem_boot);
+
+ /*
+ * If 'swap generic' and we couldn't determine boot device,
+ * ask the user.
+ */
+ if (mountroot == NULL && bootdv == NULL)
+ boothowto |= RB_ASKNAME;
+
+ if (boothowto & RB_ASKNAME) {
+ for (;;) {
+ printf("root device? ");
+ if (bootdv != NULL) {
+ printf(" (default %s", bootdv->dv_xname);
+ if (bootdv->dv_class == DV_DISK)
+ printf("%c", part + 'a');
+ printf(")");
+ }
+ printf(": ");
+ len = getstr(buf, sizeof(buf));
+ if (len == 0 && bootdv != NULL) {
+ strlcpy(buf, bootdv->dv_xname, sizeof buf);
+ len = strlen(buf);
+ }
+ if (len > 0 && buf[len - 1] == '*') {
+ buf[--len] = '\0';
+ dv = getdisk(buf, len, 1, &nrootdev);
+ if (dv != NULL) {
+ rootdv = swapdv = dv;
+ nswapdev = nrootdev;
+ goto gotswap;
+ }
+ }
+ dv = getdisk(buf, len, part, &nrootdev);
+ if (dv != NULL) {
+ rootdv = dv;
+ break;
+ }
+ }
+
+ /*
+ * because swap must be on same device type as root, for
+ * network devices this is easy.
+ */
+ if (rootdv->dv_class == DV_IFNET) {
+ swapdv = NULL;
+ goto gotswap;
+ }
+ for (;;) {
+ printf("swap device (default %s", rootdv->dv_xname);
+ if (rootdv->dv_class == DV_DISK)
+ printf("b");
+ printf("): ");
+ len = getstr(buf, sizeof(buf));
+ if (len == 0) {
+ switch (rootdv->dv_class) {
+ case DV_IFNET:
+ nswapdev = NODEV;
+ break;
+ case DV_DISK:
+ nswapdev = MAKEDISKDEV(major(nrootdev),
+ DISKUNIT(nrootdev), 1);
+ break;
+ case DV_TAPE:
+ case DV_TTY:
+ case DV_DULL:
+ case DV_CPU:
+ break;
+ }
+ swapdv = rootdv;
+ break;
+ }
+ dv = getdisk(buf, len, 1, &nswapdev);
+ if (dv) {
+ if (dv->dv_class == DV_IFNET)
+ nswapdev = NODEV;
+ swapdv = dv;
+ break;
+ }
+ }
+gotswap:
+ majdev = major(nrootdev);
+ rootdev = nrootdev;
+ dumpdev = nswapdev;
+ swdevt[0].sw_dev = nswapdev;
+ swdevt[1].sw_dev = NODEV;
+ } else if (mountroot == NULL) {
+
+ /*
+ * `swap generic': Use the device the ROM told us to use.
+ */
+ majdev = findblkmajor(bootdv);
+ if (majdev >= 0) {
+ /*
+ * Root and swap are on a disk.
+ * Assume swap is on partition b.
+ */
+ rootdv = swapdv = bootdv;
+ rootdev = MAKEDISKDEV(majdev, bootdv->dv_unit, part);
+ nswapdev = dumpdev =
+ MAKEDISKDEV(majdev, bootdv->dv_unit, 1);
+ } else {
+ /*
+ * Root and swap are on a net.
+ */
+ rootdv = swapdv = bootdv;
+ nswapdev = dumpdev = NODEV;
+ }
+ swdevt[0].sw_dev = nswapdev;
+ swdevt[1].sw_dev = NODEV;
+ } else {
+ /*
+ * `root DEV swap DEV': honour rootdev/swdevt.
+ * rootdev/swdevt/mountroot already properly set.
+ */
+
+ rootdevname = findblkname(major(rootdev));
+ return;
+ }
+
+ switch (rootdv->dv_class) {
+#ifdef NFSCLIENT
+ case DV_IFNET:
+ mountroot = nfs_mountroot;
+ nfsbootdevname = rootdv->dv_xname;
+ return;
+#endif
+#ifndef DISKLESS
+ case DV_DISK:
+ mountroot = dk_mountroot;
+ printf("root on %s%c", rootdv->dv_xname,
+ DISKPART(rootdev) + 'a');
+ if (nswapdev != NODEV)
+ printf(" swap on %s%c", swapdv->dv_xname,
+ DISKPART(nswapdev) + 'a');
+ printf("\n");
+ break;
+#endif
+ default:
+ printf("can't figure root, hope your kernel is right\n");
+ return;
+ }
+
+ /*
+ * Make the swap partition on the root drive the primary swap.
+ */
+ temp = NODEV;
+ for (swp = swdevt; swp->sw_dev != NODEV; swp++) {
+ if (majdev == major(swp->sw_dev) &&
+ DISKUNIT(rootdev) == DISKUNIT(swp->sw_dev)) {
+ temp = swdevt[0].sw_dev;
+ swdevt[0].sw_dev = swp->sw_dev;
+ swp->sw_dev = temp;
+ break;
+ }
+ }
+ if (swp->sw_dev == NODEV)
+ return;
+
+ /*
+ * If dumpdev was the same as the old primary swap device,
+ * move it to the new primary swap device.
+ */
+ if (temp == dumpdev)
+ dumpdev = swdevt[0].sw_dev;
+}
+
+int
+getstr(cp, size)
+ char *cp;
+ int size;
+{
+ char *lp;
+ int c;
+ int len;
+
+ lp = cp;
+ len = 0;
+ for (;;) {
+ c = cngetc();
+ switch (c) {
+ case '\n':
+ case '\r':
+ printf("\n");
+ *lp++ = '\0';
+ return (len);
+ case '\b':
+ case '\177':
+ case '#':
+ if (len) {
+ --len;
+ --lp;
+ printf("\b \b");
+ }
+ continue;
+ case '@':
+ case 'u'&037:
+ len = 0;
+ lp = cp;
+ printf("\n");
+ continue;
+ default:
+ if (len + 1 >= size || c < ' ') {
+ printf("\007");
+ continue;
+ }
+ printf("%c", c);
+ ++len;
+ *lp++ = c;
+ }
+ }
+}
+
+struct pdc_iodc_read pdc_iodc_read PDC_ALIGNMENT;
+struct pdc_pat_cell_id pdc_pat_cell_id PDC_ALIGNMENT;
+struct pdc_pat_cell_module pdc_pat_cell_module PDC_ALIGNMENT;
+const char *pat_names[] = {
+ "central",
+ "cpu",
+ "memory",
+ "sba",
+ "lba",
+ "pbc",
+ "cfc",
+ "fabric"
+};
+
+void
+pdc_patscan(struct device *self, struct confargs *ca, int mod)
+{
+ u_long rv[16];
+ int i, err;
+
+ if (pdc_call((iodcio_t)pdc, 0, PDC_PAT_CELL, PDC_PAT_CELL_GETID,
+ &pdc_pat_cell_id, 0)) {
+ printf("pat_fetch: cannot fetch cell number\n");
+ return;
+ }
+
+ i = 0;
+ for (i = 0; !pdc_call((iodcio_t)pdc, 0, PDC_PAT_CELL,
+ PDC_PAT_CELL_MODULE, rv, pdc_pat_cell_id.loc, i,
+ PDC_PAT_PAVIEW, &pdc_pat_cell_module, 0); i++) {
+ if (autoconf_verbose)
+ printf(">> chpa %lx info %lx loc %lx "
+ "dp %d/%d/%d/%d/%d/%d.%d\n",
+ pdc_pat_cell_module.chpa, pdc_pat_cell_module.info,
+ pdc_pat_cell_module.loc,
+ pdc_pat_cell_module.dp.dp_bc[0],
+ pdc_pat_cell_module.dp.dp_bc[1],
+ pdc_pat_cell_module.dp.dp_bc[2],
+ pdc_pat_cell_module.dp.dp_bc[3],
+ pdc_pat_cell_module.dp.dp_bc[4],
+ pdc_pat_cell_module.dp.dp_bc[5],
+ pdc_pat_cell_module.dp.dp_mod);
+
+ if (pdc_pat_cell_module.dp.dp_bc[5] == mod) {
+ struct confargs nca;
+ int t;
+
+ t = PDC_PAT_CELL_MODTYPE(pdc_pat_cell_module.info);
+ if (t >= sizeof(pat_names)/sizeof(pat_names[0]))
+ continue;
+
+ nca = *ca;
+ nca.ca_name = pat_names[t];
+ nca.ca_hpa = pdc_pat_cell_module.chpa &
+ ~(u_long)PAGE_MASK;
+ nca.ca_hpasz =
+ PDC_PAT_CELL_MODSIZE(pdc_pat_cell_module.info);
+
+ err = pdc_call((iodcio_t)pdc, 0, PDC_IODC,
+ PDC_IODC_READ, &pdc_iodc_read, nca.ca_hpa,
+ IODC_DATA, &nca.ca_type, sizeof(nca.ca_type));
+ if (err < 0 || pdc_iodc_read.size < 8) {
+ if (autoconf_verbose)
+ printf(">> iodc_data error %d\n", err);
+ bzero(&nca.ca_type, sizeof(nca.ca_type));
+ }
+ if (autoconf_verbose) {
+ u_int *p = (u_int *)&nca.ca_type;
+ printf(">> iodc_data 0x%08x 0x%08x\n",
+ p[0], p[1]);
+ }
+
+ config_found(self, &nca, mbprint);
+ }
+ }
+}
+
+const struct hppa_mod_info hppa_knownmods[] = {
+#include <arch/hppa/dev/cpudevs_data.h>
+};
+
+const char *
+hppa_mod_info(type, sv)
+ int type, sv;
+{
+ const struct hppa_mod_info *mi;
+ static char fakeid[32];
+
+ for (mi = hppa_knownmods; mi->mi_type >= 0 &&
+ (mi->mi_type != type || mi->mi_sv != sv); mi++);
+
+ if (mi->mi_type < 0) {
+ snprintf(fakeid, sizeof fakeid, "type %x, sv %x", type, sv);
+ return fakeid;
+ } else
+ return mi->mi_name;
+}
+
+void
+device_register(struct device *dev, void *aux)
+{
+#if NPCI > 0
+ extern struct cfdriver pci_cd;
+#endif
+ struct confargs *ca = aux;
+ char *basename;
+ static struct device *elder = NULL;
+
+ if (bootdv != NULL)
+ return; /* We already have a winner */
+
+#if NPCI > 0
+ if (dev->dv_parent &&
+ dev->dv_parent->dv_cfdata->cf_driver == &pci_cd) {
+ struct pci_attach_args *pa = aux;
+ pcireg_t addr;
+ int reg;
+
+ for (reg = PCI_MAPREG_START; reg < PCI_MAPREG_END; reg += 4) {
+ addr = pci_conf_read(pa->pa_pc, pa->pa_tag, reg);
+ if (PCI_MAPREG_TYPE(addr) == PCI_MAPREG_TYPE_IO)
+ addr = PCI_MAPREG_IO_ADDR(addr);
+ else
+ addr = PCI_MAPREG_MEM_ADDR(addr);
+
+ if (addr == (pcireg_t)(u_long)PAGE0->mem_boot.pz_hpa) {
+ elder = dev;
+ break;
+ }
+ }
+ } else
+#endif
+ if (ca->ca_hpa == (hppa_hpa_t)PAGE0->mem_boot.pz_hpa) {
+ /*
+ * If hpa matches, the only thing we know is that the
+ * booted device is either this one or one of its children.
+ * And the children will not necessarily have the correct
+ * hpa value.
+ * Save this elder for now.
+ */
+ elder = dev;
+ } else if (elder == NULL) {
+ return; /* not the device we booted from */
+ }
+
+ /*
+ * Unfortunately, we can not match on pz_class vs dv_class on
+ * older snakes netbooting using the rbootd protocol.
+ * In this case, we'll end up with pz_class == PCL_RANDOM...
+ * Instead, trust the device class from what the kernel attached
+ * now...
+ */
+ switch (dev->dv_class) {
+ case DV_IFNET:
+ /*
+ * Netboot is the top elder
+ */
+ if (elder == dev) {
+ bootdv = dev;
+ }
+ return;
+ case DV_DISK:
+ if ((PAGE0->mem_boot.pz_class & PCL_CLASS_MASK) != PCL_RANDOM)
+ return;
+ break;
+ case DV_TAPE:
+ if ((PAGE0->mem_boot.pz_class & PCL_CLASS_MASK) != PCL_SEQU)
+ return;
+ break;
+ default:
+ /* No idea what we were booted from, but better ask the user */
+ return;
+ }
+
+ /*
+ * If control goes here, we are booted from a block device and we
+ * matched a block device.
+ */
+ basename = dev->dv_cfdata->cf_driver->cd_name;
+
+ /* TODO wd detect */
+
+ /*
+ * We only grok SCSI boot currently. Match on proper device hierarchy,
+ * name and unit/lun values.
+ */
+#if NCD > 0 || NSD > 0 || NST > 0
+ if (strcmp(basename, "sd") == 0 || strcmp(basename, "cd") == 0 ||
+ strcmp(basename, "st") == 0) {
+ struct scsibus_attach_args *sa = aux;
+ struct scsi_link *sl = sa->sa_sc_link;
+
+ /*
+ * sd/st/cd is attached to scsibus which is attached to
+ * the controller. Hence the grandparent here should be
+ * the elder.
+ */
+ if (dev->dv_parent == NULL ||
+ dev->dv_parent->dv_parent != elder) {
+ return;
+ }
+
+ /*
+ * And now check for proper target and lun values
+ */
+ if (sl->target == PAGE0->mem_boot.pz_layers[0] &&
+ sl->lun == PAGE0->mem_boot.pz_layers[1]) {
+ bootdv = dev;
+ }
+ }
+#endif
+}
diff --git a/sys/arch/hppa64/hppa64/conf.c b/sys/arch/hppa64/hppa64/conf.c
new file mode 100644
index 00000000000..f58c4df177f
--- /dev/null
+++ b/sys/arch/hppa64/hppa64/conf.c
@@ -0,0 +1,284 @@
+/* $OpenBSD: conf.c,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)conf.c 7.9 (Berkeley) 5/28/91
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/ioctl.h>
+#include <sys/tty.h>
+#include <sys/vnode.h>
+
+#include <machine/conf.h>
+
+#include "ccd.h"
+#include "vnd.h"
+#include "rd.h"
+#include "sd.h"
+#include "st.h"
+#include "cd.h"
+#include "ch.h"
+#include "ss.h"
+#include "ses.h"
+#include "uk.h"
+#include "wd.h"
+bdev_decl(wd);
+cdev_decl(wd);
+#if 0
+#include "fd.h"
+#else
+#define NFD 0
+#endif
+bdev_decl(fd);
+cdev_decl(fd);
+
+struct bdevsw bdevsw[] =
+{
+ bdev_swap_init(1,sw), /* 0: swap pseudo-device */
+ bdev_disk_init(NCCD,ccd), /* 1: concatenated disk driver */
+ bdev_disk_init(NVND,vnd), /* 2: vnode disk driver */
+ bdev_disk_init(NRD,rd), /* 3: RAM disk */
+ bdev_disk_init(NSD,sd), /* 4: SCSI disk */
+ bdev_tape_init(NST,st), /* 5: SCSI tape */
+ bdev_disk_init(NCD,cd), /* 6: SCSI CD-ROM */
+ bdev_disk_init(NFD,fd), /* 7: floppy drive */
+ bdev_disk_init(NWD,wd), /* 8: ST506 drive */
+ /* 9: */
+ bdev_lkm_dummy(),
+ bdev_lkm_dummy(),
+ bdev_lkm_dummy(),
+ bdev_lkm_dummy(),
+ bdev_lkm_dummy(),
+ bdev_lkm_dummy(),
+};
+int nblkdev = sizeof(bdevsw) / sizeof(bdevsw[0]);
+
+/* open, close, read, write, ioctl, tty, mmap */
+#define cdev_wscons_init(c,n) { \
+ dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
+ dev_init(c,n,write), dev_init(c,n,ioctl), dev_init(c,n,stop), \
+ dev_init(c,n,tty), ttpoll, dev_init(c,n,mmap) }
+
+#include "audio.h"
+#include "pty.h"
+#include "wsdisplay.h"
+#include "wskbd.h"
+#include "wsmouse.h"
+#include "wsmux.h"
+#ifdef XFS
+#include <xfs/nxfs.h>
+cdev_decl(xfs_dev);
+#endif
+
+#include "inet.h"
+#include "bpfilter.h"
+#include "tun.h"
+
+#include "ksyms.h"
+
+#include "lpt.h"
+cdev_decl(lpt);
+
+#include "com.h"
+cdev_decl(com);
+
+#include "pf.h"
+
+#include "systrace.h"
+
+#ifdef USER_PCICONF
+#include "pci.h"
+cdev_decl(pci);
+#endif
+
+struct cdevsw cdevsw[] =
+{
+ cdev_cn_init(1,cn), /* 0: virtual console */
+ cdev_ctty_init(1,ctty), /* 1: controlling terminal */
+ cdev_mm_init(1,mm), /* 2: /dev/{null,mem,kmem,...} */
+ cdev_swap_init(1,sw), /* 3: /dev/drum (swap pseudo-device) */
+ cdev_tty_init(NPTY,pts), /* 4: pseudo-tty slave */
+ cdev_ptc_init(NPTY,ptc), /* 5: pseudo-tty master */
+ cdev_log_init(1,log), /* 6: /dev/klog */
+ cdev_disk_init(NCCD,ccd), /* 7: concatenated disk */
+ cdev_disk_init(NVND,vnd), /* 8: vnode disk driver */
+ cdev_disk_init(NRD,rd), /* 9: RAM disk */
+ cdev_disk_init(NSD,sd), /* 10: SCSI disk */
+ cdev_tape_init(NST,st), /* 11: SCSI tape */
+ cdev_disk_init(NCD,cd), /* 12: SCSI cd-rom */
+ cdev_ch_init(NCH,ch), /* 13: SCSI changer */
+ cdev_ss_init(NSS,ss), /* 14: SCSI scanner */
+ cdev_uk_init(NUK,uk), /* 15: SCSI unknown */
+ cdev_fd_init(1,filedesc), /* 16: file descriptor pseudo-device */
+ cdev_bpftun_init(NBPFILTER,bpf),/* 17: Berkeley packet filter */
+ cdev_bpftun_init(NTUN,tun), /* 18: network tunnel */
+ cdev_lkm_init(NLKM,lkm), /* 19: loadable module driver */
+ cdev_random_init(1,random), /* 20: random generator */
+ cdev_pf_init(NPF,pf), /* 21: packet filter */
+ cdev_tty_init(1,pdc), /* 22: PDC device */
+ cdev_tty_init(NCOM,com), /* 23: RS232 */
+ cdev_disk_init(NFD,fd), /* 24: floppy drive */
+ cdev_ksyms_init(NKSYMS,ksyms), /* 25: Kernel symbols device */
+ cdev_lpt_init(NLPT,lpt), /* 26: parallel printer */
+ cdev_wsdisplay_init(NWSDISPLAY, /* 27: workstation console */
+ wsdisplay),
+ cdev_mouse_init(NWSKBD,wskbd), /* 28: keyboards */
+ cdev_mouse_init(NWSMOUSE,wsmouse), /* 29: mice */
+ cdev_mouse_init(NWSMUX,wsmux), /* 30: mux */
+#ifdef USER_PCICONF
+ cdev_pci_init(NPCI,pci), /* 31: PCI user */
+#else
+ cdev_notdef(),
+#endif
+#ifdef XFS
+ cdev_xfs_init(NXFS,xfs_dev), /* 32: xfs communication device */
+#else
+ cdev_notdef(),
+#endif
+ cdev_notdef(), /* 33: ALTQ (deprecated) */
+ cdev_systrace_init(NSYSTRACE,systrace), /* 34: system call tracing */
+ cdev_audio_init(NAUDIO,audio), /* 35: /dev/audio */
+ cdev_crypto_init(NCRYPTO,crypto), /* 36: /dev/crypto */
+ cdev_ses_init(NSES,ses), /* 37: SCSI SES/SAF-TE */
+ cdev_ptm_init(NPTY,ptm), /* 38: pseudo-tty ptm device */
+ cdev_disk_init(NWD,wd), /* 39: ST506 disk */
+ cdev_lkm_dummy(),
+ cdev_lkm_dummy(),
+ cdev_lkm_dummy(),
+ cdev_lkm_dummy(),
+ cdev_lkm_dummy(),
+ cdev_lkm_dummy(),
+};
+int nchrdev = sizeof(cdevsw) / sizeof(cdevsw[0]);
+
+int mem_no = 2; /* major device number of memory special file */
+
+/*
+ * Swapdev is a fake device implemented
+ * in sw.c used only internally to get to swstrategy.
+ * It cannot be provided to the users, because the
+ * swstrategy routine munches the b_dev and b_blkno entries
+ * before calling the appropriate driver. This would horribly
+ * confuse, e.g. the hashing routines. Instead, /dev/drum is
+ * provided as a character (raw) device.
+ */
+dev_t swapdev = makedev(0, 0);
+
+int chrtoblktbl[] = {
+ /* XXXX This needs to be dynamic for LKMs. */
+ /*VCHR*/ /*VBLK*/
+ /* 0 */ NODEV,
+ /* 1 */ NODEV,
+ /* 2 */ NODEV,
+ /* 3 */ NODEV,
+ /* 4 */ NODEV,
+ /* 5 */ NODEV,
+ /* 6 */ NODEV,
+ /* 7 */ 1,
+ /* 8 */ 2,
+ /* 9 */ 3,
+ /* 10 */ 4,
+ /* 11 */ 5,
+ /* 12 */ 6,
+ /* 13 */ NODEV,
+ /* 14 */ NODEV,
+ /* 15 */ NODEV,
+ /* 16 */ NODEV,
+ /* 17 */ NODEV,
+ /* 18 */ NODEV,
+ /* 19 */ NODEV,
+ /* 20 */ NODEV,
+ /* 21 */ NODEV,
+ /* 22 */ NODEV,
+ /* 23 */ NODEV,
+ /* 24 */ 7,
+ /* 25 */ NODEV,
+ /* 26 */ NODEV,
+ /* 27 */ NODEV,
+ /* 28 */ NODEV,
+ /* 29 */ NODEV,
+ /* 30 */ NODEV,
+ /* 31 */ NODEV,
+ /* 32 */ NODEV,
+ /* 33 */ NODEV,
+ /* 34 */ NODEV,
+ /* 35 */ NODEV,
+ /* 36 */ NODEV,
+ /* 37 */ NODEV,
+ /* 38 */ NODEV,
+ /* 39 */ NODEV,
+};
+int nchrtoblktbl = sizeof(chrtoblktbl) / sizeof(chrtoblktbl[0]);
+
+/*
+ * Returns true if dev is /dev/zero.
+ */
+int
+iszerodev(dev)
+ dev_t dev;
+{
+ return (major(dev) == mem_no && minor(dev) == 12);
+}
+
+dev_t
+getnulldev()
+{
+ return makedev(mem_no, 2);
+}
+
+/*
+ * Returns true if dev is /dev/mem or /dev/kmem.
+ */
+int
+iskmemdev(dev)
+ dev_t dev;
+{
+ return (major(dev) == mem_no && minor(dev) < 2);
+}
+
+#include <dev/cons.h>
+
+cons_decl(pdc);
+cons_decl(ws);
+cons_decl(com);
+
+struct consdev constab[] = {
+ cons_init(pdc), /* XXX you'd better leave it here for pdc.c */
+#if NWSDISPLAY1 > 0
+ cons_init(ws),
+#endif
+#if NCOM1 > 0
+ cons_init(com),
+#endif
+ { 0 }
+};
+
diff --git a/sys/arch/hppa64/hppa64/db_disasm.c b/sys/arch/hppa64/hppa64/db_disasm.c
new file mode 100644
index 00000000000..c1e1fe3434b
--- /dev/null
+++ b/sys/arch/hppa64/hppa64/db_disasm.c
@@ -0,0 +1,2353 @@
+/* $OpenBSD: db_disasm.c,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/* TODO parse 64bit insns or rewrite */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * (c) Copyright 1992 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of Hewlett-Packard Company not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Hewlett-Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ */
+
+/*
+ * unasm.c -- HP_PA Instruction Printer
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <machine/db_machdep.h>
+#include <ddb/db_access.h>
+#include <ddb/db_sym.h>
+#include <ddb/db_output.h>
+#include <ddb/db_interface.h>
+
+
+/* IMPORTANT NOTE:
+ * All modules using this header may assume that the datatype "int" is a
+ * 32-bit (or > 32-bit) signed quantity.
+ */
+
+
+/* Spectrum Architecturally Defined Datatypes */
+struct doubleword {
+ int wd0;
+ int wd1;
+};
+
+struct quadword {
+ struct doubleword d0;
+ struct doubleword d1;
+};
+
+ /* datatypes for halfword and byte fields of a word are defined
+ * in ssBits.h */
+
+/* Memory addressing datatypes */
+typedef unsigned int SID, /* range [0..MAXSID] */
+ PGID, /* range [0..MAXPGID] */
+ OFS, /* range [0..MAXINT] */
+ REALADR; /* range [0..MAXINT] */
+
+
+/* data sizes */
+enum datasize { Byte, Halfword, Word, Doubleword, Quadword, Variable };
+
+/* Miscellaneous datatypes */
+typedef unsigned int FLAGS;
+
+/* struct for entry in unwind table */
+struct ute {
+ int word1;
+ int word2;
+ int word3;
+ int word4;
+};
+/*
+ * Header: /n/schirf/u/baford/CVS/mach4-parisc/kernel_unused/parisc/kdb/unasm.c,v 1.5 1994/07/21 22:32:05 mike Exp
+ *
+ * Spectrum Instruction Set Condition Completer Bit Assignments
+ * Dan Magenheimer - 6/14/82
+ * Terrence Miller - 6/21/82
+ * Computer Research Center, Hewlett-Packard Labs
+ *
+ * (c) copyright 1982
+ * (p) protected 1982
+ * The Hewlett-Packard Company
+ * Hewlett-Packard Laboratories
+ * Computer Research Center
+ * Palo Alto, California
+ *
+ * *** HP Company Confidential ***
+ *
+ * Log: unasm.c,v
+ * Revision 1.5 1994/07/21 22:32:05 mike
+ * official HP copyright notice
+ *
+ * Revision 1.4 1992/07/08 12:19:52 dalton
+ * Checkin before split to 1.0.4 release (by LBS).
+ *
+ * Revision 1.3 92/06/06 16:16:45 dalton
+ * *** empty log message ***
+ *
+ * Revision 1.2 92/06/06 15:42:28 dalton
+ * Changed include to be a path relative to hp800.
+ *
+ * Revision 1.1 92/06/06 14:05:33 dalton
+ * Initial revision
+ *
+ * Revision 1.2 91/04/14 20:29:49 osfrcs
+ * Initial version.
+ * [91/03/30 09:20:34 brezak]
+ *
+ * Revision 1.1.2.2 91/04/02 10:42:50 brezak
+ * Initial version.
+ * [91/03/30 09:20:34 brezak]
+ *
+ * Revision 1.1.1.2 91/03/30 09:20:34 brezak
+ * Initial version.
+ *
+ * Revision 1.1 88/07/11 14:05:15 14:05:15 ren (Bob Naas)
+ * Initial revision
+ *
+ * Revision 5.2 87/07/02 14:45:57 14:45:57 kent (Kent McMullen)
+ * added constants to support addDasm and addDCond added to ssDID.c
+ *
+ * Revision 5.1 87/02/27 11:12:08 11:12:08 kent (Kent McMullen)
+ * update all src to 5.1
+ *
+ * Revision 5.0 87/02/18 16:31:15 16:31:15 kent (Kent McMullen)
+ * update all revision numbers to 5.0 for release
+ *
+ * Revision 1.1 86/07/15 08:34:55 08:34:55 kent (Kent McMullen)
+ * Initial revision
+ *
+ * Revision 4.1 83/10/25 17:01:22 17:01:22 djm (Daniel J Magenheimer)
+ * First release for ACD v4
+ *
+ * Revision 3.0 83/06/13 10:22:59 djm (Daniel Magenheimer)
+ * First release for distribution
+ *
+ *
+ */
+
+
+/* Arithmetic/Logical Conditions */
+#define NEV 0x0
+#define EQZ 0x2
+#define LT 0x4
+#define LE 0x6
+#define LLT 0x8
+#define NUV 0x8
+#define LLE 0xA
+#define ZNV 0xA
+#define SV 0xC
+#define OD 0xE
+#define TR 0x1
+#define NEQZ 0x3
+#define GE 0x5
+#define GT 0x7
+#define LGE 0x9
+#define UV 0x9
+#define LGT 0xB
+#define VNZ 0xB
+#define NSV 0xD
+#define EV 0xF
+
+/* unit conditions */
+#define SBZ 0x4
+#define SHZ 0x6
+#define SDC 0x8
+#define SBC 0xC
+#define SHC 0xE
+#define NBZ 0x5
+#define NHZ 0x7
+#define NDC 0x9
+#define NBC 0xD
+#define NHC 0xF
+
+/*field conditions */
+#define XEQ 0x1
+#define XLT 0x2
+#define XOD 0x3
+#define XTR 0x4
+#define XNE 0x5
+#define XGE 0x6
+#define XEV 0x7
+
+
+
+/*
+ * These macros are designed to be portable to all machines that have
+ * a wordsize greater than or equal to 32 bits that support the portable
+ * C compiler and the standard C preprocessor. Wordsize (default 32)
+ * and bitfield assignment (default left-to-right, unlike VAX, PDP-11)
+ * should be predefined using the constants HOSTWDSZ and BITFRL and
+ * the C compiler "-D" flag (e.g., -DHOSTWDSZ=36 -DBITFLR for the DEC-20).
+ * Note that the macro arguments assume that the integer being referenced
+ * is a 32-bit integer (right-justified on the 20) and that bit 0 is the
+ * most significant bit.
+ */
+
+#ifndef HOSTWDSZ
+#define HOSTWDSZ 32
+#endif
+
+#ifdef vax
+#ifndef BITFLR
+#define BITFRL
+#endif
+#else
+#define BITFLR
+#endif
+
+/*########################### Macros ######################################*/
+
+/*---------------------------------------------------------------------------
+ * DeclareBitfield$Reference - Declare a structure to be used to reference
+ * a specified bitfield within an integer (using BitfR, see below).
+ * The argument "n" must be an identifier name not used elsewhere in the
+ * program , "s" and "l" must (alas!) be constants. (Suggestion: if
+ * "s" == 2 and "l" == 8, use _b28 for "n".) The name "BITFLR" should
+ * be pre-defined if the compiler assigns bitfields from left-to-right.
+ * The resultant macro expansion defines a stucture in which the bit field
+ * starting at position "s" with length "l" may be referenced by accessing
+ * member "n". [Note: The leftmost bits in a 36-bit word may be accessed
+ * by specifying -4 <= s < 0 on the DEC-20.]
+ *---------------------------------------------------------------------------*/
+
+#ifdef BITFRL
+#define DeclBitfR(s,l,n) struct n { int:(HOSTWDSZ-(s)-(l)); unsigned n:l;};
+#else
+#define DeclBitfR(s,l,n) struct n { int:((s)+(HOSTWDSZ-32)); unsigned n:l;};
+#endif
+
+/*---------------------------------------------------------------------------
+ * Bitfield$Reference - Reference a specified bitfield within an integer.
+ * The argument "i" must be an addressable variable (i.e., not a register
+ * variable or an expression... but see BitfX below), "n" must be an
+ * identifier name declared in a DeclBitfR invocation. The resultant
+ * macro expansion references the bit field in "i" described by the
+ * DeclBitfR invocation with the same name ("n"). BitfR may be used as
+ * an lvalue or an rvalue. (i.e., either side of an assignment statement)
+ * The "s" and "l" arguments are historical and are now unused. (They
+ * correspond to the "s" and "l" arguments in DeclBitfR)
+ * Translates to a single instruction on both the VAX and the DEC-20.
+ *---------------------------------------------------------------------------*/
+#define BitfR(i,s,l,n) (((struct n *)&i)->n)
+
+/*---------------------------------------------------------------------------
+ * Bitfield$eXtract - Extract the specified field from an integer. Arguments
+ * are the same as for BitfR (except no "n"), however both "s" and "l" need
+ * no longer be constants. May only be used as an rvalue. Translates to
+ * two instructions on the VAX, three on the DEC-20.
+ *---------------------------------------------------------------------------*/
+
+#define BitfX(i,s,l) (((i) >> (32-(s)-(l))) & ((1 << (l)) - 1))
+
+
+/*---------------------------------------------------------------------------
+ * Mask$32bits - Mask the low order 32 bits of passed word. No-op on 32
+ * bit machines.
+ *---------------------------------------------------------------------------*/
+
+#if HOSTWDSZ > 32
+#define Mask32(x) ((x) & 0xffffffff)
+#else
+#define Mask32(x) (x)
+#endif
+
+
+/*---------------------------------------------------------------------------
+ * SignExtend$32bits - Force the high-order bits in machines with wordsize
+ * longer than 32 to match bit 0.
+ *---------------------------------------------------------------------------*/
+
+#if HOSTWDSZ > 32
+#define SignEx32(x) (((x) & 0x80000000) ? ((x) | ((unsigned)-1 << 32)) \
+ : Mask32(x))
+#else
+#define SignEx32(x) (x)
+#endif
+
+/**************************/
+/* bit field declarations */
+/**************************/
+
+/* since the compiler complains if a structure name is declared twice, even
+ * if the declarations are identical, all DeclBitfR invocations are
+ * given here in one file. */
+
+DeclBitfR(0,1,_b01)
+DeclBitfR(0,15,_b015)
+DeclBitfR(0,16,_b016)
+DeclBitfR(0,4,_b04)
+DeclBitfR(0,6,_b06)
+DeclBitfR(0,8,_b08)
+DeclBitfR(4,1,_b41)
+DeclBitfR(4,4,_b44)
+DeclBitfR(6,1,_b61)
+DeclBitfR(6,13,_b613)
+DeclBitfR(6,15,_b615)
+DeclBitfR(6,17,_b617)
+DeclBitfR(6,26,_b626)
+DeclBitfR(6,5,_b65)
+DeclBitfR(7,1,_b71)
+DeclBitfR(8,1,_b81)
+DeclBitfR(8,4,_b84)
+DeclBitfR(8,8,_b88)
+DeclBitfR(9,1,_b91)
+DeclBitfR(10,1,_b101)
+DeclBitfR(11,1,_b111)
+DeclBitfR(11,10,_b1110)
+DeclBitfR(11,4,_b114)
+DeclBitfR(11,5,_b115)
+DeclBitfR(12,1,_b121)
+DeclBitfR(12,4,_b124)
+DeclBitfR(13,1,_b131)
+DeclBitfR(14,1,_b141)
+DeclBitfR(15,1,_b151)
+DeclBitfR(16,1,_b161)
+DeclBitfR(16,15,_b1615)
+DeclBitfR(16,16,_b1616)
+DeclBitfR(16,2,_b162)
+DeclBitfR(16,3,_b163)
+DeclBitfR(16,4,_b164)
+DeclBitfR(16,5,_b165)
+DeclBitfR(16,8,_b168)
+DeclBitfR(17,1,_b171)
+DeclBitfR(18,1,_b181)
+DeclBitfR(18,13,_b1813)
+DeclBitfR(18,2,_b182)
+DeclBitfR(18,7,_b187)
+DeclBitfR(19,1,_b191)
+DeclBitfR(19,8,_b198)
+DeclBitfR(19,10,_b1910)
+DeclBitfR(20,11,_b2011)
+DeclBitfR(20,2,_b202)
+DeclBitfR(20,4,_b204)
+DeclBitfR(21,10,_b2110)
+DeclBitfR(21,2,_b212)
+DeclBitfR(21,5,_b215)
+DeclBitfR(22,5,_b225)
+DeclBitfR(23,3,_b233)
+DeclBitfR(24,1,_b241)
+DeclBitfR(24,4,_b244)
+DeclBitfR(24,8,_b248)
+DeclBitfR(25,1,_b251)
+DeclBitfR(26,1,_b261)
+DeclBitfR(27,1,_b271)
+DeclBitfR(27,4,_b274)
+DeclBitfR(27,5,_b275)
+DeclBitfR(28,1,_b281)
+DeclBitfR(28,4,_b284)
+DeclBitfR(29,1,_b291)
+DeclBitfR(30,1,_b301)
+DeclBitfR(30,2,_b302)
+DeclBitfR(31,1,_b311)
+
+/******************/
+/* Word subfields */
+/******************/
+
+#define Sign(i) BitfR(i,0,1,_b01)
+/* halfwords */
+#define Hwd0(i) BitfR(i,0,16,_b016)
+#define Hwd1sign(i) BitfR(i,16,1,_b161)
+#define Hwd1(i) BitfR(i,16,16,_b1616)
+/* bytes */
+#define Byte0(i) BitfR(i,0,8,_b08)
+#define Byte1sign(i) BitfR(i,8,1,_b81)
+#define Byte1(i) BitfR(i,8,8,_b88)
+#define Byte2(i) BitfR(i,16,8,_b168)
+#define Byte3sign(i) BitfR(i,24,1,_b241)
+#define Byte3(i) BitfR(i,24,8,_b248)
+/* digits */
+#define Digit0(i) BitfR(i,0,4,_b04)
+#define Digit1(i) BitfR(i,4,4,_b44)
+#define Digit2(i) BitfR(i,8,4,_b84)
+#define Digit3(i) BitfR(i,12,4,_b124)
+#define Digit4(i) BitfR(i,16,4,_b164)
+#define Digit5(i) BitfR(i,20,4,_b204)
+#define Digit6(i) BitfR(i,24,4,_b244)
+#define Digit7(i) BitfR(i,28,4,_b284)
+
+/* Wordsize definitions */
+
+#define BIT_P_DW 64 /* bits/doubleword */
+#define BIT_P_WD 32 /* bits/word */
+#define BIT_P_HW 16 /* bits/halfword */
+#define BIT_P_BYT 8 /* bits/byte */
+#define BYT_P_DW 8 /* bytes/doubleword */
+#define BYT_P_WD 4 /* bytes/word */
+#define BYT_P_HW 2 /* bytes/halfword */
+
+/* Masks */
+
+#define WDMASK 0xffffffff /* 32-bit mask */
+#define OFSMASK 0xffffffff /* 32-bit mask */
+#define SIDMASK 0xffffffff /* 32-bit mask */
+#define SIGNMASK 0x80000000 /* 32 bit word sign bit */
+
+/* Alignments */
+
+#define wdalign(ofs) (ofs &= ~3)
+/*
+ * Header: /n/schirf/u/baford/CVS/mach4-parisc/kernel_unused/parisc/kdb/unasm.c,v 1.5 1994/07/21 22:32:05 mike Exp
+ *
+ * Spectrum Simulator Instruction Opcode Definitions
+ * Dan Magenheimer
+ * Computer Research Center, Hewlett-Packard Labs
+ *
+ * (c) copyright 1982
+ * (p) protected 1982
+ * The Hewlett-Packard Company
+ * Hewlett-Packard Laboratories
+ * Computer Research Center
+ * Palo Alto, California
+ *
+ * *** HP Company Confidential ***
+ *
+ * Log: unasm.c,v
+ * Revision 1.5 1994/07/21 22:32:05 mike
+ * official HP copyright notice
+ *
+ * Revision 1.4 1992/07/08 12:19:52 dalton
+ * Checkin before split to 1.0.4 release (by LBS).
+ *
+ * Revision 1.3 92/06/06 16:16:45 dalton
+ * *** empty log message ***
+ *
+ * Revision 1.2 92/06/06 15:42:28 dalton
+ * Changed include to be a path relative to hp800.
+ *
+ * Revision 1.1 92/06/06 14:05:33 dalton
+ * Initial revision
+ *
+ * Revision 1.2 91/04/14 20:29:49 osfrcs
+ * Initial version.
+ * [91/03/30 09:20:34 brezak]
+ *
+ * Revision 1.1.2.2 91/04/02 10:42:50 brezak
+ * Initial version.
+ * [91/03/30 09:20:34 brezak]
+ *
+ * Revision 1.1.1.2 91/03/30 09:20:34 brezak
+ * Initial version.
+ *
+ * Revision 6.1 89/09/06 10:39:58 burroughs
+ * Added shadow registers for gr0-gr7.
+ * gr0-7 are copied into sh0-7 whenever a trap occurs
+ * the instruction RFIR restores gr0-7 from sh0-7 and returns from
+ * interrupt.
+ * the "sh" command displays the shadow registers
+ * = sh7 0x789 works, too.
+ *
+ * Revision 6.0 89/09/01 15:46:37 15:46:37 burroughs (Greg Burroughs)
+ * baseline for pcx simple offsite
+ *
+ * Revision 5.2 87/09/02 14:30:23 14:30:23 kent
+ * separated stat gathering for indexed vs short.
+ * this will NOT work if cache hints ever get used
+ * since this field was assumed always zero
+ *
+ * Revision 5.1 87/02/27 11:12:16 11:12:16 kent (Kent McMullen)
+ * update all src to 5.1
+ *
+ * Revision 5.0 87/02/18 16:31:35 16:31:35 kent (Kent McMullen)
+ * update all revision numbers to 5.0 for release
+ *
+ * Revision 1.1 86/07/15 08:34:57 08:34:57 kent (Kent McMullen)
+ * Initial revision
+ *
+ * Revision 4.1 83/10/25 17:02:34 17:02:34 djm (Daniel J Magenheimer)
+ * First release for ACD v4
+ *
+ * Revision 3.0 83/06/13 10:24:45 djm (Daniel Magenheimer)
+ * First release for distribution
+ *
+ *
+ */
+
+/*
+ * Changes:
+ * 01/30/90 ejf Simplify SPOPn support, now only gives assist emulation trap.
+ * 01/19/90 ejf Replace linpak instructions with just FSTQ[SX].
+ * 12/19/89 ejf Add PA89 new floating point opcode 0E.
+ * 12/18/89 ejf Change 5 ops to PA89 format.
+ * 12/01/89 ejf Move additional instructions fmas, fmaa, fld2, fst2 to ssILst
+ * 09/22/89 ejf Fix unbalanced comments.
+ */
+
+
+/* ..and modified by hand to remove the load/store short references */
+/* ..and modified by hand to make memory management ops conform to the
+ * requirement that all subops of a major opcode begin in the same
+ * place and have the same length */
+
+#define LDW 0x12, 0x00, 0, 0 /* LOAD WORD */
+#define LDWM 0x13, 0x00, 0, 0 /* LOAD WORD and MODIFY */
+#define LDH 0x11, 0x00, 0, 0 /* LOAD HALFWORD */
+#define LDB 0x10, 0x00, 0, 0 /* LOAD BYTE */
+#define LDO 0x0d, 0x00, 0, 0 /* LOAD OFFSET */
+#define STW 0x1a, 0x00, 0, 0 /* STORE WORD */
+#define STWM 0x1b, 0x00, 0, 0 /* STORE WORD and MODIFY */
+#define STH 0x19, 0x00, 0, 0 /* STORE HALFWORD */
+#define STB 0x18, 0x00, 0, 0 /* STORE BYTE */
+#define LDWX 0x03, 0x02, 19, 7 /* LOAD WORD INDEXED */
+#define LDHX 0x03, 0x01, 19, 7 /* LOAD HALFWORD INDEXED */
+#define LDBX 0x03, 0x00, 19, 7 /* LOAD BYTE INDEXED */
+#define LDWAX 0x03, 0x06, 19, 7 /* LOAD WORD ABSOLUTE INDEXED */
+#define LDCWX 0x03, 0x07, 19, 7 /* LOAD and CLEAR WORD INDEXED */
+#define LDWS 0x03, 0x42, 19, 7 /* LOAD WORD SHORT DISP */
+#define LDHS 0x03, 0x41, 19, 7 /* LOAD HALFWORD SHORT DISP */
+#define LDBS 0x03, 0x40, 19, 7 /* LOAD BYTE SHORT DISP */
+#define LDWAS 0x03, 0x46, 19, 7 /* LOAD WORD ABSOLUTE SHORT DISP */
+#define LDCWS 0x03, 0x47, 19, 7 /* LOAD and CLEAR WORD SHORT DISP */
+#define STWS 0x03, 0x4a, 19, 7 /* STORE WORD SHORT DISP */
+#define STHS 0x03, 0x49, 19, 7 /* STORE HALFWORD SHORT DISP */
+#define STBS 0x03, 0x48, 19, 7 /* STORE BYTE SHORT DISP */
+#define STWAS 0x03, 0x4e, 19, 7 /* STORE WORD ABSOLUTE SHORT DISP */
+#define STBYS 0x03, 0x4c, 19, 7 /* STORE BYTES SHORT DISP */
+#define LDIL 0x08, 0x00, 0, 0 /* LOAD IMMED LEFT */
+#define ADDIL 0x0a, 0x00, 0, 0 /* ADD IMMED LEFT */
+#define BL 0x3a, 0x00, 16, 3 /* BRANCH [and LINK] */
+#define GATE 0x3a, 0x01, 16, 3 /* GATEWAY */
+#define BLR 0x3a, 0x02, 16, 3 /* BRANCH and LINK REGISTER */
+#define BV 0x3a, 0x06, 16, 3 /* BRANCH VECTORED */
+#define BE 0x38, 0x00, 0, 0 /* BRANCH EXTERNAL */
+#define BLE 0x39, 0x00, 0, 0 /* BRANCH and LINK EXTERNAL */
+#define MOVB 0x32, 0x00, 0, 0 /* MOVE and BRANCH */
+#define MOVIB 0x33, 0x00, 0, 0 /* MOVE IMMED and BRANCH */
+#define COMBT 0x20, 0x00, 0, 0 /* COMPARE and BRANCH if TRUE */
+#define COMBF 0x22, 0x00, 0, 0 /* COMPARE and BRANCH if FALSE */
+#define COMIBT 0x21, 0x00, 0, 0 /* COMPARE IMMED and BRANCH if TRUE */
+#define COMIBF 0x23, 0x00, 0, 0 /* COMPARE IMMED and BRANCH if FALSE */
+#define ADDBT 0x28, 0x00, 0, 0 /* ADD and BRANCH if TRUE */
+#define ADDBF 0x2a, 0x00, 0, 0 /* ADD and BRANCH if FALSE */
+#define ADDIBT 0x29, 0x00, 0, 0 /* ADD IMMED and BRANCH if TRUE */
+#define ADDIBF 0x2b, 0x00, 0, 0 /* ADD IMMED and BRANCH if FALSE */
+#define BVB 0x30, 0x00, 0, 0 /* BRANCH on VARIABLE BIT */
+#define BB 0x31, 0x00, 0, 0 /* BRANCH on BIT */
+#define ADD 0x02, 0x30, 20, 7 /* ADD */
+#define ADDL 0x02, 0x50, 20, 7 /* ADD LOGICAL */
+#define ADDO 0x02, 0x70, 20, 7 /* ADD and TRAP on OVFLO */
+#define SH1ADD 0x02, 0x32, 20, 7 /* SHIFT 1, ADD */
+#define SH1ADDL 0x02, 0x52, 20, 7 /* SHIFT 1, ADD LOGICAL */
+#define SH1ADDO 0x02, 0x72, 20, 7 /* SHIFT 1, ADD and TRAP on OVFLO */
+#define SH2ADD 0x02, 0x34, 20, 7 /* SHIFT 2, ADD */
+#define SH2ADDL 0x02, 0x54, 20, 7 /* SHIFT 2, ADD LOGICAL */
+#define SH2ADDO 0x02, 0x74, 20, 7 /* SHIFT 2, ADD and TRAP on OVFLO */
+#define SH3ADD 0x02, 0x36, 20, 7 /* SHIFT 3, ADD */
+#define SH3ADDL 0x02, 0x56, 20, 7 /* SHIFT 3, ADD LOGICAL */
+#define SH3ADDO 0x02, 0x76, 20, 7 /* SHIFT 3, ADD and TRAP on OVFLO */
+#define ADDC 0x02, 0x38, 20, 7 /* ADD with CARRY */
+#define ADDCO 0x02, 0x78, 20, 7 /* ADD with CARRY and TRAP on OVFLO */
+#define SUB 0x02, 0x20, 20, 7 /* SUBTRACT */
+#define SUBO 0x02, 0x60, 20, 7 /* SUBTRACT and TRAP on OVFLO */
+#define SUBB 0x02, 0x28, 20, 7 /* SUBTRACT with BORROW */
+#define SUBBO 0x02, 0x68, 20, 7 /* SUBTRACT with BORROW and TRAP on OVFLO */
+#define SUBT 0x02, 0x26, 20, 7 /* SUBTRACT and TRAP on COND */
+#define SUBTO 0x02, 0x66, 20, 7 /* SUBTRACT and TRAP on COND or OVFLO */
+#define DS 0x02, 0x22, 20, 7 /* DIVIDE STEP */
+#define COMCLR 0x02, 0x44, 20, 7 /* COMPARE and CLEAR */
+#define OR 0x02, 0x12, 20, 7 /* INCLUSIVE OR */
+#define XOR 0x02, 0x14, 20, 7 /* EXCLUSIVE OR */
+#define AND 0x02, 0x10, 20, 7 /* AND */
+#define ANDCM 0x02, 0x00, 20, 7 /* AND COMPLEMENT */
+#define UXOR 0x02, 0x1c, 20, 7 /* UNIT XOR */
+#define UADDCM 0x02, 0x4c, 20, 7 /* UNIT ADD COMPLEMENT */
+#define UADDCMT 0x02, 0x4e, 20, 7 /* UNIT ADD COMPLEMENT and TRAP on COND */
+#define DCOR 0x02, 0x5c, 20, 7 /* DECIMAL CORRECT */
+#define IDCOR 0x02, 0x5e, 20, 7 /* INTERMEDIATE DECIMAL CORRECT */
+#define ADDI 0x2d, 0x00, 20, 1 /* ADD to IMMED */
+#define ADDIO 0x2d, 0x01, 20, 1 /* ADD to IMMED and TRAP on OVFLO */
+#define ADDIT 0x2c, 0x00, 20, 1 /* ADD to IMMED and TRAP on COND */
+#define ADDITO 0x2c, 0x01, 20, 1 /* ADD to IMMED and TRAP on COND or OVFLO */
+#define SUBI 0x25, 0x00, 20, 1 /* SUBTRACT from IMMED */
+#define SUBIO 0x25, 0x01, 20, 1 /* SUBTRACT from IMMED and TRAP on OVFLO */
+#define COMICLR 0x24, 0x00, 0, 0 /* COMPARE IMMED and CLEAR */
+#define VSHD 0x34, 0x00, 19, 3 /* VARIABLE SHIFT DOUBLE */
+#define SHD 0x34, 0x02, 19, 3 /* SHIFT DOUBLE */
+#define VEXTRU 0x34, 0x04, 19, 3 /* VARIABLE EXTRACT RIGHT UNSIGNED */
+#define VEXTRS 0x34, 0x05, 19, 3 /* VARIABLE EXTRACT RIGHT SIGNED */
+#define EXTRU 0x34, 0x06, 19, 3 /* EXTRACT RIGHT UNSIGNED */
+#define EXTRS 0x34, 0x07, 19, 3 /* EXTRACT RIGHT SIGNED */
+#define VDEP 0x35, 0x01, 19, 3 /* VARIABLE DEPOSIT */
+#define DEP 0x35, 0x03, 19, 3 /* DEPOSIT */
+#define VDEPI 0x35, 0x05, 19, 3 /* VARIABLE DEPOSIT IMMED */
+#define DEPI 0x35, 0x07, 19, 3 /* DEPOSIT IMMED */
+#define ZVDEP 0x35, 0x00, 19, 3 /* ZERO and VARIABLE DEPOSIT */
+#define ZDEP 0x35, 0x02, 19, 3 /* ZERO and DEPOSIT */
+#define ZVDEPI 0x35, 0x04, 19, 3 /* ZERO and VARIABLE DEPOSIT IMMED */
+#define ZDEPI 0x35, 0x06, 19, 3 /* ZERO and DEPOSIT IMMED */
+#define BREAK 0x00, 0x00, 19, 8 /* BREAK */
+#define RFI 0x00, 0x60, 19, 8 /* RETURN FROM INTERRUPTION */
+#define RFIR 0x00, 0x65, 19, 8 /* RFI & RESTORE SHADOW REGISTERS */
+#define SSM 0x00, 0x6b, 19, 8 /* SET SYSTEM MASK */
+#define RSM 0x00, 0x73, 19, 8 /* RESET SYSTEM MASK */
+#define MTSM 0x00, 0xc3, 19, 8 /* MOVE TO SYSTEM MASK */
+#define LDSID 0x00, 0x85, 19, 8 /* LOAD SPACE IDENTIFIER */
+#define MTSP 0x00, 0xc1, 19, 8 /* MOVE TO SPACE REGISTER */
+#define MTCTL 0x00, 0xc2, 19, 8 /* MOVE TO SYSTEM CONTROL REGISTER */
+#define MFSP 0x00, 0x25, 19, 8 /* MOVE FROM SPACE REGISTER */
+#define MFCTL 0x00, 0x45, 19, 8 /* MOVE FROM SYSTEM CONTROL REGISTER */
+#define SYNC 0x00, 0x20, 19, 8 /* SYNCHRONIZE DATA CACHE */
+#define DIAG 0x05, 0x00, 0, 0 /* DIAGNOSE */
+#define SPOP 0x04, 0x00, 0, 0 /* SPECIAL FUNCTION UNIT */
+#define COPR 0x0c, 0x00, 0, 0 /* COPROCESSOR */
+#define CLDWX 0x09, 0x00, 19, 4 /* COPROCESSOR LOAD WORD INDEXED */
+#define CLDDX 0x0b, 0x00, 19, 4 /* COPROCESSOR LOAD WORD INDEXED */
+#define CSTWX 0x09, 0x01, 19, 4 /* COPROCESSOR STORE WORD INDEXED */
+#define CSTDX 0x0b, 0x01, 19, 4 /* COPROCESSOR STORE WORD INDEXED */
+#define CLDWS 0x09, 0x08, 19, 4 /* COPROCESSOR LOAD WORD SHORT */
+#define CLDDS 0x0b, 0x08, 19, 4 /* COPROCESSOR LOAD WORD SHORT */
+#define CSTWS 0x09, 0x09, 19, 4 /* COPROCESSOR STORE WORD SHORT */
+#define CSTDS 0x0b, 0x09, 19, 4 /* COPROCESSOR STORE WORD SHORT */
+#define FLOAT0 0x0e, 0x00, 21, 2 /* FLOATING POINT CLASS 0 */
+#define FLOAT1 0x0e, 0x01, 21, 2 /* FLOATING POINT CLASS 1 */
+#define FLOAT2 0x0e, 0x02, 21, 2 /* FLOATING POINT CLASS 2 */
+#define FLOAT3 0x0e, 0x03, 21, 2 /* FLOATING POINT CLASS 3 */
+#define FMPYSUB 0x26, 0x00, 0, 0 /* FP MULTIPLY AND SUBTRACT */
+#define FMPYADD 0x06, 0x00, 0, 0 /* FP MULTIPLY AND ADD/TRUNCATE */
+#define FSTQX 0x0f, 0x01, 19, 4 /* FLOATING POINT STORE QUAD INDEXED */
+#define FSTQS 0x0f, 0x09, 19, 4 /* FLOATING POINT STORE QUAD SHORT */
+/* all of the following have been pushed around to conform */
+#define PROBER 0x01, 0x46, 19, 7 /* PROBE READ ACCESS */
+#ifdef notdef
+#define PROBERI 0x01, 0xc6, 19, 7 /* PROBE READ ACCESS IMMEDIATE */
+#endif
+#define PROBEW 0x01, 0x47, 19, 7 /* PROBE WRITE ACCESS */
+#ifdef notdef
+#define PROBEWI 0x01, 0xc7, 19, 7 /* PROBE WRITE ACCESS IMMEDIATE */
+#endif
+#define LPA 0x01, 0x4d, 19, 7 /* LOAD PHYSICAL ADDRESS */
+#define LHA 0x01, 0x4c, 19, 7 /* LOAD HASH ADDRESS */
+#define PDTLB 0x01, 0x48, 19, 7 /* PURGE DATA TRANS LOOKASIDE BUFFER */
+#define PITLB 0x01, 0x08, 19, 7 /* PURGE INST TRANS LOOKASIDE BUFFER */
+#define PDTLBE 0x01, 0x49, 19, 7 /* PURGE DATA TLB ENTRY */
+#define PITLBE 0x01, 0x09, 19, 7 /* PURGE INST TLB ENTRY */
+#define IDTLBA 0x01, 0x41, 19, 7 /* INSERT DATA TLB ADDRESS */
+#define IITLBA 0x01, 0x01, 19, 7 /* INSERT INSTRUCTION TLB ADDRESS */
+#define IDTLBP 0x01, 0x40, 19, 7 /* INSERT DATA TLB PROTECTION */
+#define IITLBP 0x01, 0x00, 19, 7 /* INSERT INSTRUCTION TLB PROTECTION */
+#define PDC 0x01, 0x4e, 19, 7 /* PURGE DATA CACHE */
+#define FDC 0x01, 0x4a, 19, 7 /* FLUSH DATA CACHE */
+#define FIC 0x01, 0x0a, 19, 7 /* FLUSH INSTRUCTION CACHE */
+#define FDCE 0x01, 0x4b, 19, 7 /* FLUSH DATA CACHE ENTRY */
+#define FICE 0x01, 0x0b, 19, 7 /* FLUSH DATA CACHE ENTRY */
+
+/*
+ * Header: /n/schirf/u/baford/CVS/mach4-parisc/kernel_unused/parisc/kdb/unasm.c,v 1.5 1994/07/21 22:32:05 mike Exp
+ *
+ * Spectrum Simulator Instruction Set Constants and Datatypes
+ * Dan Magenheimer - 4/28/82
+ * Computer Research Center, Hewlett-Packard Labs
+ *
+ * (c) copyright 1982
+ * (p) protected 1982
+ * The Hewlett-Packard Company
+ * Hewlett-Packard Laboratories
+ * Computer Research Center
+ * Palo Alto, California
+ *
+ * *** HP Company Confidential ***
+ *
+ * Log: unasm.c,v
+ * Revision 1.5 1994/07/21 22:32:05 mike
+ * official HP copyright notice
+ *
+ * Revision 1.4 1992/07/08 12:19:52 dalton
+ * Checkin before split to 1.0.4 release (by LBS).
+ *
+ * Revision 1.3 92/06/06 16:16:45 dalton
+ * *** empty log message ***
+ *
+ * Revision 1.2 92/06/06 15:42:28 dalton
+ * Changed include to be a path relative to hp800.
+ *
+ * Revision 1.1 92/06/06 14:05:33 dalton
+ * Initial revision
+ *
+ * Revision 1.2 91/04/14 20:29:49 osfrcs
+ * Initial version.
+ * [91/03/30 09:20:34 brezak]
+ *
+ * Revision 1.1.2.2 91/04/02 10:42:50 brezak
+ * Initial version.
+ * [91/03/30 09:20:34 brezak]
+ *
+ * Revision 1.1.1.2 91/03/30 09:20:34 brezak
+ * Initial version.
+ *
+;Revision 1.1 88/07/11 14:05:21 14:05:21 ren (Bob Naas)
+;Initial revision
+;
+ * Revision 5.1 87/02/27 11:12:23 11:12:23 kent (Kent McMullen)
+ * update all src to 5.1
+ *
+ * Revision 5.0 87/02/18 16:31:52 16:31:52 kent (Kent McMullen)
+ * update all revision numbers to 5.0 for release
+ *
+ * Revision 1.1 86/07/15 08:35:00 08:35:00 kent (Kent McMullen)
+ * Initial revision
+ *
+ * Revision 4.3 85/11/12 09:28:44 09:28:44 viggy (Viggy Mokkarala)
+ * first mpsim version, partially stable
+ *
+ * Revision 4.2 84/07/16 17:20:57 17:20:57 djm ()
+ * Define field macros for COPR and SFU insts
+ *
+ * Revision 4.1 83/10/25 17:10:14 djm (Daniel Magenheimer)
+ * First release for ACD v4
+ *
+ * Revision 3.1 83/08/03 14:09:59 djm (Daniel Magenheimer)
+ * Sys calls, args, -S, bug fixes, etc.
+ *
+ * Revision 3.0 83/06/13 10:25:13 djm (Daniel Magenheimer)
+ * First release for distribution
+ *
+ *
+ */
+/*
+ * Changes:
+ * 12/01/89 ejf Add Rsd(), Rse(), Rtd(), Rte() for 5 ops.
+ * 11/30/89 ejf Make instruction use counters shared, not per cpu.
+ * 11/28/89 ejf Change majoropcode for quicker extension extract.
+ */
+
+
+
+/*
+ * Dependencies: std.h, ssDefs.h, bits.h
+ */
+
+
+/* Lookup/Execute structure for instructions */
+struct inst {
+ u_char majopc; /* major opcode of instruction, 0..MAXOPC */
+ u_char opcext; /* opcode extension, 0 if not applic. */
+ u_char extbs; /* starting bit pos of extension field */
+ u_char extbl; /* bit length of extension field */
+ u_int count; /* frequency counter for analysis */
+ char mnem[8]; /* ascii mnemonic */
+ /* disassembly function */
+ int (*dasmfcn)(const struct inst *, OFS, int);
+};
+
+
+#define NMAJOPCS 64
+
+struct majoropcode {
+ const struct inst **subops; /* pointer to table of subops indexed by
+ * opcode extension */
+ u_int maxsubop; /* largest opcode extension value or 0 */
+ u_int extshft; /* right shift amount for extension field */
+ u_int extmask; /* post shift mask for extension field */
+};
+
+#define OpExt(i,m) ((i >> m->extshft) & m->extmask) /* extract opcode extension */
+
+
+/*****************************/
+/* Miscellaneous definitions */
+/*****************************/
+
+/* Load/Store Indexed Opcode Extension Cache Control */
+#define NOACTION 0
+#define STACKREF 1
+#define SEQPASS 2
+#define PREFETCH 3
+
+/******************************/
+/* Fields within instructions */
+/******************************/
+
+/* opcode */
+#define Opcode(i) BitfR(i,0,6,_b06)
+/* opcode true/false bit */
+#define OpcTF(i) BitfR(i,4,1,_b41)
+/* register sources */
+#define Rsa(i) BitfR(i,11,5,_b115)
+#define Rsb(i) BitfR(i,6,5,_b65)
+#define Rsc(i) BitfR(i,27,5,_b275)
+#define Rsd(i) BitfR(i,21,5,_b215)
+#define Rse(i) BitfR(i,16,5,_b165)
+/* register targets */
+#define Rta(i) BitfR(i,11,5,_b115)
+#define Rtb(i) BitfR(i,6,5,_b65)
+#define Rtc(i) BitfR(i,27,5,_b275)
+#define Rtd(i) BitfR(i,21,5,_b215)
+#define Rte(i) BitfR(i,16,5,_b165)
+/* 5-bit immediates (Magnitude, Sign) */
+#define Imb5(i) BitfR(i,6,5,_b65)
+#define Ima5M(i) BitfR(i,11,4,_b114)
+#define Ima5S(i) BitfR(i,15,1,_b151)
+#define Ima5A(i) BitfR(i,11,5,_b115)
+#define Imd5(i) BitfR(i,22,5,_b225)
+#define Imc5M(i) BitfR(i,27,4,_b274)
+#define Imc5S(i) BitfR(i,31,1,_b311)
+#define Imc5A(i) BitfR(i,27,5,_b275)
+/* Other immediates */
+#define Im21L(i) BitfR(i,18,2,_b182)
+#define Im21H(i) BitfR(i,20,11,_b2011)
+#define Im21M1(i) BitfR(i,16,2,_b162)
+#define Im21M2(i) BitfR(i,11,5,_b115)
+#define Im21S(i) BitfR(i,31,1,_b311)
+#define Im11M(i) BitfR(i,21,10,_b2110)
+#define Im11S(i) BitfR(i,31,1,_b311)
+/* displacements/offsets */
+#define DispM(i) BitfR(i,18,13,_b1813)
+#define DispS(i) BitfR(i,31,1,_b311)
+#define Off5(i) BitfR(i,11,5,_b115)
+#define Off11H(i) BitfR(i,19,10,_b1910)
+#define Off11L(i) BitfR(i,29,1,_b291)
+#define OffS(i) BitfR(i,31,1,_b311)
+/* miscellaneous */
+#define Dss(i) BitfR(i,16,2,_b162)
+#define Cond(i) BitfR(i,16,3,_b163)
+#define Cneg(i) BitfR(i,19,1,_b191)
+#define Cond4(i) BitfR(i,16,4,_b164) /* Cond AND Cneg */
+#define Nu(i) BitfR(i,30,1,_b301)
+#define SrL(i) BitfR(i,16,2,_b162)
+#define SrH(i) BitfR(i,18,1,_b181)
+#define ShortDisp(i) BitfR(i,19,1,_b191)
+#define IndxShft(i) BitfR(i,18,1,_b181)
+#define ModBefore(i) BitfR(i,18,1,_b181)
+#define CacheCtrl(i) BitfR(i,20,2,_b202)
+#define Modify(i) BitfR(i,26,1,_b261)
+#define ProbeI(i) BitfR(i,18,1,_b181)
+#define Uid(i) BitfR(i,23,3,_b233)
+#define Sfu(i) BitfR(i,23,3,_b233)
+#define CopExt17(i) BitfR(i,6,17,_b617)
+#define CopExt5(i) BitfR(i,27,5,_b275)
+#define SpopType(i) BitfR(i,21,2,_b212)
+#define SpopExt15(i) BitfR(i,6,15,_b615)
+#define SpopExt10(i) BitfR(i,11,10,_b1110)
+#define SpopExt5L(i) BitfR(i,16,5,_b165)
+#define SpopExt5(i) BitfR(i,27,5,_b275)
+#define NoMajOpc(i) BitfR(i,6,26,_b626)
+#define Bi1(i) BitfR(i,27,5,_b275) /* fields in BREAK */
+#define Bi2(i) BitfR(i,6,13,_b613)
+
+/* fragmented field collating macros */
+#define Ima5(i) (Ima5S(i) ? Ima5M(i) | (-1<<4) : Ima5M(i))
+
+#define Imc5(i) (Imc5S(i) ? Imc5M(i) | (-1<<4) : Imc5M(i))
+
+#define Disp(i) (DispS(i) ? DispM(i) | (-1<<13) : DispM(i))
+
+#define Im21(i) (Im21S(i) << 31 | Im21H(i) << 20 | Im21M1(i) << 18 | \
+ Im21M2(i) << 13 | Im21L(i) << 11)
+
+#define Im11(i) (Im11S(i) ? Im11M(i) | (-1<<10) : Im11M(i))
+
+#define Bdisp(i) ((OffS(i) ? (Off5(i)<<11 | Off11L(i)<<10|Off11H(i)) \
+/* branch displacement (bytes) */ | (-1 << 16) \
+ : (Off5(i)<<11|Off11L(i)<<10|Off11H(i))) << 2)
+
+#define Cbdisp(i) ((OffS(i) ? (Off11L(i) << 10 | Off11H(i)) \
+ /* compare/branch disp (bytes) */ | (-1 << 11) \
+ : Off11L(i) << 10 | Off11H(i)) << 2)
+
+#define Sr(i) (SrH(i)<<2 | SrL(i))
+
+/* sfu/copr */
+#define CoprExt1(i) (CopExt17(i))
+#define CoprExt2(i) (CopExt5(i))
+#define CoprExt(i) ((CopExt17(i)<<5) | CopExt5(i))
+#define Spop0Ext(i) ((SpopExt15(i)<<5) | SpopExt5(i))
+#define Spop1Ext(i) (SpopExt15(i))
+#define Spop2Ext(i) ((SpopExt10(i)<<5) | SpopExt5(i))
+#define Spop3Ext(i) ((SpopExt5L(i)<<5) | SpopExt5(i))
+
+
+/*##################### Globals - Imports ##################################*/
+
+/* Disassembly functions */
+int fcoprDasm(int w, u_int op1, u_int);
+char *edDCond(u_int cond);
+char *unitDCond(u_int cond);
+char *addDCond(u_int cond);
+char *subDCond(u_int cond);
+int blDasm(const struct inst *i, OFS ofs, int w);
+int ldDasm(const struct inst *, OFS, int);
+int stDasm(const struct inst *i, OFS, int);
+int addDasm(const struct inst *i, OFS, int);
+int unitDasm(const struct inst *i, OFS, int);
+int iaDasm(const struct inst *i, OFS, int);
+int shdDasm(const struct inst *i, OFS, int);
+int extrDasm(const struct inst *i, OFS, int);
+int vextrDasm(const struct inst *i, OFS, int);
+int depDasm(const struct inst *i, OFS, int);
+int vdepDasm(const struct inst *i, OFS, int);
+int depiDasm(const struct inst *i, OFS, int);
+int vdepiDasm(const struct inst *i, OFS, int);
+int limmDasm(const struct inst *i, OFS, int);
+int brkDasm(const struct inst *i, OFS, int);
+int lpkDasm(const struct inst *i, OFS, int);
+int fmpyaddDasm(const struct inst *i, OFS, int);
+int fmpysubDasm(const struct inst *i, OFS, int);
+int floatDasm(const struct inst *i, OFS, int);
+int coprDasm(const struct inst *i, OFS, int);
+int diagDasm(const struct inst *i, OFS, int);
+int scDasm(const struct inst *i, OFS, int);
+int mmgtDasm(const struct inst *i, OFS, int);
+int ldxDasm(const struct inst *i, OFS, int);
+int stsDasm(const struct inst *i, OFS, int);
+int stbysDasm(const struct inst *i, OFS, int);
+int brDasm(const struct inst *i, OFS, int);
+int bvDasm(const struct inst *i, OFS, int);
+int beDasm(const struct inst *i, OFS, int);
+int cbDasm(const struct inst *i,OFS ofs, int);
+int cbiDasm(const struct inst *i,OFS ofs, int);
+int bbDasm(const struct inst *i,OFS ofs, int);
+int ariDasm(const struct inst *i, OFS, int);
+
+/*##################### Globals - Exports ##################################*/
+/*##################### Local Variables ####################################*/
+
+static const char fmtStrTbl[][5] = { "sgl", "dbl", "sgl", "quad" };
+static const char condStrTbl[][7] = {
+ "false?", "false", "?", "!<=>", "=", "=t", "?=", "!<>",
+ "!?>=", "<", "?<", "!>=", "!?>", "<=", "?<=", "!>",
+ "!?<=", ">", "?>", "!<=", "!?<", ">=", "?>=", "!<",
+ "!?=", "<>", "!=", "!=t", "!?", "<=>", "true?", "true"
+};
+static const char fsreg[][5] = {
+ "r0L", "r0R", "r1L", "r1R", "r2L", "r2R", "r3L", "r3R",
+ "r4L", "r4R", "r5L", "r5R", "r6L", "r6R", "r7L", "r7R",
+ "r8L", "r8R", "r9L", "r9R", "r10L", "r10R", "r11L", "r11R",
+ "r12L", "r12R", "r13L", "r13R", "r14L", "r14R", "r15L", "r15R",
+ "r16L", "r16R", "r17L", "r17R", "r18L", "r18R", "r19L", "r19R",
+ "r20L", "r20R", "r21L", "r21R", "r22L", "r22R", "r23L", "r23R",
+ "r24L", "r24R", "r25L", "r25R", "r26L", "r26R", "r27L", "r27R",
+ "r28L", "r28R", "r29L", "r29R", "r30L", "r30R", "r31L", "r31R"
+};
+static const char fdreg[][4] = {
+ "r0", "r0", "r1", "r1", "r2", "r2", "r3", "r3",
+ "r4", "r4", "r5", "r5", "r6", "r6", "r7", "r7",
+ "r8", "r8", "r9", "r9", "r10", "r10", "r11", "r11",
+ "r12", "r12", "r13", "r13", "r14", "r14", "r15", "r15",
+ "r16", "r16", "r17", "r17", "r18", "r18", "r19", "r19",
+ "r20", "r20", "r21", "r21", "r22", "r22", "r23", "r23",
+ "r24", "r24", "r25", "r25", "r26", "r26", "r27", "r27",
+ "r28", "r28", "r29", "r29", "r30", "r30", "r31", "r31"
+};
+
+/*##################### Macros #############################################*/
+
+#define Match(s) (strncmp(s,i->mnem,sizeof(s)-1) == 0)
+
+/* bits for assist ops */
+#define AstNu(w) Modify(w)
+#define Fpi(w) (Uid(w)>3)
+
+/* bits for 5 ops */
+#define SinglePrec(i) Modify(i)
+#define Ms1(i) ((Rsb(i)<<1)+(SinglePrec(i)?((Rsb(i)>15)?1:32):0))
+#define Ms2(i) ((Rsa(i)<<1)+(SinglePrec(i)?((Rsa(i)>15)?1:32):0))
+#define Mt(i) ((Rtc(i)<<1)+(SinglePrec(i)?((Rtc(i)>15)?1:32):0))
+#define As(i) ((Rsd(i)<<1)+(SinglePrec(i)?((Rsd(i)>15)?1:32):0))
+#define Ad(i) ((Rte(i)<<1)+(SinglePrec(i)?((Rte(i)>15)?1:32):0))
+
+/*##################### Globals - Exports ##################################*/
+
+/* To replace instr function, do the following: */
+/* a) locate the desired entry in instrs[] below */
+/* b) change the 3rd field if an alternate mneumonic is */
+/* desired for window disassembly */
+/* c) change the 4th field to the name of the function being */
+/* used for replacement (i.e. ldwRepl instead of ldw) */
+/* d) change the 5th field if an alternate disassembly routine */
+/* is desired (i.e. ldDasmRepl) */
+
+static const struct inst instrs[] = {
+ { LDW, 0, "ldw", ldDasm },
+ { LDH, 0, "ldh", ldDasm },
+ { LDB, 0, "ldb", ldDasm },
+ { LDWM, 0, "ldwm", ldDasm },
+ { LDO, 0, "ldo", ldDasm },
+ { STW, 0, "stw", stDasm },
+ { STH, 0, "sth", stDasm },
+ { STB, 0, "stb", stDasm },
+ { STWM, 0, "stwm", stDasm },
+ { LDWX, 0, "ldw", ldxDasm },
+ { LDHX, 0, "ldh", ldxDasm },
+ { LDBX, 0, "ldb", ldxDasm },
+ { LDCWX, 0, "ldcw", ldxDasm },
+ { LDWAX, 0, "ldwa", ldxDasm },
+ { LDWS, 0, "ldw", ldxDasm },
+ { LDHS, 0, "ldh", ldxDasm },
+ { LDBS, 0, "ldb", ldxDasm },
+ { LDCWS, 0, "ldcw", ldxDasm },
+ { LDWAS, 0, "ldwa", ldxDasm },
+ { STWS, 0, "stws", stsDasm },
+ { STHS, 0, "sths", stsDasm },
+ { STBS, 0, "stbs", stsDasm },
+ { STWAS, 0, "stwas", stsDasm },
+ { STBYS, 0, "stbys", stbysDasm },
+ { LDIL, 0, "ldil", limmDasm },
+ { ADDIL, 0, "addil", limmDasm },
+ { GATE, 0, "gate", blDasm },
+ { BL, 0, "b", blDasm },
+ { BLR, 0, "blr", brDasm },
+ { BV, 0, "bv", bvDasm },
+ { BE, 0, "be", beDasm },
+ { BLE, 0, "ble", beDasm },
+ { COMBT, 0, "combt", cbDasm },
+ { COMBF, 0, "combf", cbDasm },
+ { COMIBT, 0, "comibt", cbiDasm },
+ { COMIBF, 0, "comibf", cbiDasm },
+ { ADDBT, 0, "addbt", cbDasm },
+ { ADDBF, 0, "addbf", cbDasm },
+ { ADDIBT, 0, "addibt", cbiDasm },
+ { ADDIBF, 0, "addibf", cbiDasm },
+ { MOVB, 0, "movb", cbDasm },
+ { MOVIB, 0, "movib", cbiDasm },
+ { BB, 0, "bb", bbDasm },
+ { BVB, 0, "bvb", bbDasm },
+ { SUBO, 0, "subo", ariDasm },
+ { ADD, 0, "add", addDasm },
+ { ADDL, 0, "addl", addDasm },
+ { ADDO, 0, "addo", ariDasm },
+ { SH1ADD, 0, "sh1add", ariDasm },
+ { SH1ADDL,0, "sh1addl", ariDasm },
+ { SH1ADDO,0, "sh1addo", ariDasm },
+ { SH2ADD, 0, "sh2add", ariDasm },
+ { SH2ADDL,0, "sh2addl", ariDasm },
+ { SH2ADDO,0, "sh2addo", ariDasm },
+ { SH3ADD, 0, "sh3add", ariDasm },
+ { SH3ADDL,0, "sh3addl", ariDasm },
+ { SH3ADDO,0, "sh3addo", ariDasm },
+ { SUB, 0, "sub", ariDasm },
+ { ADDCO, 0, "addco", ariDasm },
+ { SUBBO, 0, "subbo", ariDasm },
+ { ADDC, 0, "addc", ariDasm },
+ { SUBB, 0, "subb", ariDasm },
+ { COMCLR, 0, "comclr", ariDasm },
+ { OR, 0, "or", ariDasm },
+ { AND, 0, "and", ariDasm },
+ { XOR, 0, "xor", ariDasm },
+ { ANDCM, 0, "andcm", ariDasm },
+ { DS, 0, "ds", ariDasm },
+ { UXOR, 0, "uxor", unitDasm },
+ { UADDCM, 0, "uaddcm", unitDasm },
+ { UADDCMT,0, "uaddcmt", unitDasm },
+ { SUBTO, 0, "subto", ariDasm },
+ { SUBT, 0, "subt", ariDasm },
+ { DCOR, 0, "dcor", unitDasm },
+ { IDCOR, 0, "idcor", unitDasm },
+ { ADDIO, 0, "addio", iaDasm },
+ { SUBIO, 0, "subio", iaDasm },
+ { ADDI, 0, "addi", iaDasm },
+ { SUBI, 0, "subi", iaDasm },
+ { COMICLR,0, "comiclr", iaDasm },
+ { ADDITO, 0, "addito", iaDasm },
+ { ADDIT, 0, "addit", iaDasm },
+ { SHD, 0, "shd", shdDasm },
+ { VSHD, 0, "vshd", shdDasm },
+ { EXTRU, 0, "extru", extrDasm },
+ { EXTRS, 0, "extrs", extrDasm },
+ { VEXTRU, 0, "vextru", vextrDasm },
+ { VEXTRS, 0, "vextrs", vextrDasm },
+ { DEP, 0, "dep", depDasm },
+ { VDEP, 0, "vdep", vdepDasm },
+ { DEPI, 0, "depi", depiDasm },
+ { VDEPI, 0, "vdepi", vdepiDasm },
+ { ZDEP, 0, "zdep", depDasm },
+ { ZVDEP, 0, "zvdep", vdepDasm },
+ { ZDEPI, 0, "zdepi", depiDasm },
+ { ZVDEPI, 0, "zvdepi", vdepiDasm },
+ { BREAK, 0, "break", brkDasm },
+ { RFI, 0, "rfi", 0 },
+ { RFIR, 0, "rfir", 0 },
+ { SSM, 0, "ssm", scDasm },
+ { RSM, 0, "rsm", scDasm },
+ { MTSM, 0, "mtsm", scDasm },
+ { PROBER, 0, "prober", mmgtDasm },
+ { PROBEW, 0, "probew", mmgtDasm },
+ { LPA, 0, "lpa", mmgtDasm },
+ { LHA, 0, "lha", mmgtDasm },
+ { LDSID, 0, "ldsid", scDasm },
+ { PDTLB, 0, "pdtlb", mmgtDasm },
+ { PDTLBE, 0, "pdtlbe", mmgtDasm },
+ { PITLB, 0, "pitlb", mmgtDasm },
+ { PITLBE, 0, "pitlbe", mmgtDasm },
+ { IDTLBA, 0, "idtlba", mmgtDasm },
+ { IITLBA, 0, "iitlba", mmgtDasm },
+ { IDTLBP, 0, "idtlbp", mmgtDasm },
+ { IITLBP, 0, "iitlbp", mmgtDasm },
+ { FIC, 0, "fic", mmgtDasm },
+ { FICE, 0, "fice", mmgtDasm },
+ { PDC, 0, "pdc", mmgtDasm },
+ { FDC, 0, "fdc", mmgtDasm },
+ { FDCE, 0, "fdce", mmgtDasm },
+ { SYNC, 0, "sync", 0 },
+ { MTSP, 0, "mtsp", scDasm },
+ { MTCTL, 0, "mtctl", scDasm },
+ { MFSP, 0, "mfsp", scDasm },
+ { MFCTL, 0, "mfctl", scDasm },
+ { DIAG, 0, "diag", diagDasm },
+ { SPOP, 0, "???", 0 },
+ { COPR, 0, "copr", coprDasm },
+ { CLDWX, 0, "cldw", coprDasm },
+ { CLDDX, 0, "cldd", coprDasm },
+ { CSTWX, 0, "cstw", coprDasm },
+ { CSTDX, 0, "cstd", coprDasm },
+ { CLDWS, 0, "cldw", coprDasm },
+ { CLDDS, 0, "cldd", coprDasm },
+ { CSTWS, 0, "cstw", coprDasm },
+ { CSTDS, 0, "cstd", coprDasm },
+ { FLOAT0, 0, "f", floatDasm },
+ { FLOAT1, 0, "fcnv", floatDasm },
+ { FLOAT2, 0, "f", floatDasm },
+ { FLOAT3, 0, "f", floatDasm },
+ { FMPYSUB,0, "fmpy", fmpysubDasm },
+ { FMPYADD,0, "fmpy", fmpyaddDasm },
+ { FSTQX, 0, "fstqx", lpkDasm },
+ { FSTQS, 0, "fstqs", lpkDasm },
+ {0}
+};
+
+
+static const struct inst illeg = { 0, 0, 0, 0, 0, "???", 0 };
+static const struct inst *so_sysop[0xd0];
+static const struct inst *so_mmuop[0x50];
+static const struct inst *so_arith[0x80];
+static const struct inst *so_loads[0x50];
+static const struct inst *so_cldw [0x0A];
+static const struct inst *so_cldd [0x0A];
+static const struct inst *so_float[0x04];
+static const struct inst *so_fstq [0x0A];
+static const struct inst *so_ebran[0x08];
+static const struct inst *so_addit[0x02];
+static const struct inst *so_addi [0x02];
+static const struct inst *so_subi [0x02];
+static const struct inst *so_shext[0x08];
+static const struct inst *so_deps [0x08];
+
+#define ILLEG (const struct inst **)&illeg
+#define NENTS(a) (sizeof(a)/sizeof(a[0])-1)
+static struct majoropcode majopcs[NMAJOPCS] = {
+ { so_sysop, NENTS(so_sysop) }, /* 00 */
+ { so_mmuop, NENTS(so_mmuop) }, /* 01 */
+ { so_arith, NENTS(so_arith) }, /* 02 */
+ { so_loads, NENTS(so_loads) }, /* 03 */
+ { ILLEG, 1 }, /* 04 */
+ { ILLEG, 1 }, /* 05 */
+ { ILLEG, 1 }, /* 06 */
+ { ILLEG, 1 }, /* 07 */
+ { ILLEG, 1 }, /* 08 */
+ { so_cldw , NENTS(so_cldw ) }, /* 09 */
+ { ILLEG, 1 }, /* 0A */
+ { so_cldd , NENTS(so_cldd ) }, /* 0B */
+ { ILLEG, 1 }, /* 0C */
+ { ILLEG, 1 }, /* 0D */
+ { so_float, NENTS(so_float) }, /* 0E */
+ { so_fstq , NENTS(so_fstq ) }, /* 0F */
+ { ILLEG, 1 }, /* 10 */
+ { ILLEG, 1 }, /* 11 */
+ { ILLEG, 1 }, /* 12 */
+ { ILLEG, 1 }, /* 13 */
+ { ILLEG, 1 }, /* 14 */
+ { ILLEG, 1 }, /* 15 */
+ { ILLEG, 1 }, /* 16 */
+ { ILLEG, 1 }, /* 17 */
+ { ILLEG, 1 }, /* 18 */
+ { ILLEG, 1 }, /* 19 */
+ { ILLEG, 1 }, /* 1A */
+ { ILLEG, 1 }, /* 1B */
+ { ILLEG, 1 }, /* 1C */
+ { ILLEG, 1 }, /* 1D */
+ { ILLEG, 1 }, /* 1E */
+ { ILLEG, 1 }, /* 1F */
+ { ILLEG, 1 }, /* 20 */
+ { ILLEG, 1 }, /* 21 */
+ { ILLEG, 1 }, /* 22 */
+ { ILLEG, 1 }, /* 23 */
+ { ILLEG, 1 }, /* 24 */
+ { so_subi , NENTS(so_subi ) }, /* 25 */
+ { ILLEG, 1 }, /* 26 */
+ { ILLEG, 1 }, /* 27 */
+ { ILLEG, 1 }, /* 28 */
+ { ILLEG, 1 }, /* 29 */
+ { ILLEG, 1 }, /* 2A */
+ { ILLEG, 1 }, /* 2B */
+ { so_addit, NENTS(so_addit) }, /* 2C */
+ { so_addi , NENTS(so_addi ) }, /* 2D */
+ { ILLEG, 1 }, /* 2E */
+ { ILLEG, 1 }, /* 2F */
+ { ILLEG, 1 }, /* 30 */
+ { ILLEG, 1 }, /* 31 */
+ { ILLEG, 1 }, /* 32 */
+ { ILLEG, 1 }, /* 33 */
+ { so_shext, NENTS(so_shext) }, /* 34 */
+ { so_deps , NENTS(so_deps ) }, /* 35 */
+ { ILLEG, 1 }, /* 36 */
+ { ILLEG, 1 }, /* 37 */
+ { ILLEG, 1 }, /* 38 */
+ { ILLEG, 1 }, /* 39 */
+ { so_ebran, NENTS(so_ebran) }, /* 3A */
+ { ILLEG, 1 }, /* 3B */
+ { ILLEG, 1 }, /* 3C */
+ { ILLEG, 1 }, /* 3D */
+ { ILLEG, 1 }, /* 3E */
+ { ILLEG, 1 }, /* 3F */
+};
+#undef NENTS
+#undef ILLEG
+
+/*--------------------------------------------------------------------------
+ * instruction$ExecutionInitialize - Initialize the instruction execution
+ * data structures.
+ *---------------------------------------------------------------------------*/
+int
+iExInit(void)
+{
+ static int unasm_initted = 0;
+ register const struct inst *i;
+ register struct majoropcode *m;
+ u_int shft, mask;
+
+ if (unasm_initted)
+ return 0;
+
+ /*
+ * Determine maxsubop for each major opcode.
+ * Also, check all instructions of a given major opcode
+ * for consistent opcode extension field definition, and
+ * save a converted form of this definition in the majopcs
+ * entry for this major opcode.
+ */
+ for (i = &instrs[0]; *i->mnem; i++) {
+ m = &majopcs[i->majopc];
+ if (m->maxsubop < i->opcext)
+ panic("iExInit not enough space for opcode %d",
+ i->majopc);
+ shft = 32 - i->extbs - i->extbl;
+ mask = (1 << i->extbl) - 1;
+ if (m->extshft || m->extmask) {
+ if (m->extshft != shft || m->extmask != mask) {
+ db_printf("%s - Bad instruction initialization!\n", i->mnem);
+ return (0);
+ }
+ } else {
+ m->extshft = shft;
+ m->extmask = mask;
+ }
+ }
+
+ /*
+ * Lastly, fill in all legal subops with the appropriate info.
+ */
+ for (i = &instrs[0]; *i->mnem; i++) {
+ m = &majopcs[i->majopc];
+ if (m->maxsubop == 1)
+ m->subops = (const struct inst **)i;
+ else
+ m->subops[i->opcext] = i;
+ }
+
+ unasm_initted++;
+ return (1);
+}
+
+
+
+/*##################### Functions and Subroutines ##########################*/
+
+/**************************************/
+/* Miscellaneous Disassembly Routines */
+/**************************************/
+
+/* Add instructions */
+int
+addDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ db_printf("%s\t%%r%d,%%r%d,%%r%d",addDCond(Cond4(w)),
+ Rsa(w),Rsb(w),Rtc(w));
+ return (1);
+}
+
+/* Unit instructions */
+int
+unitDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ db_printf(unitDCond(Cond4(w)));
+ if (Match("dcor") || Match("idcor"))
+ db_printf("\t%%r%d,%%r%d",Rsb(w),Rtc(w));
+ else
+ db_printf("\t%%r%d,%%r%d,%%r%d",Rsa(w),Rsb(w),Rtc(w));
+ return (1);
+}
+
+/* Immediate Arithmetic instructions */
+int
+iaDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ if (Match("addi"))
+ db_printf("%s\t%d,%%r%d,%%r%d",
+ addDCond(Cond4(w)),Im11(w),Rsb(w),Rta(w));
+ else
+ db_printf("%s\t%d,%%r%d,%%r%d",
+ subDCond(Cond4(w)),Im11(w),Rsb(w),Rta(w));
+ return (1);
+}
+
+/* Shift double instructions */
+int
+shdDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ if (Match("vshd"))
+ db_printf("%s\t%%r%d,%%r%d,%%r%d",
+ edDCond(Cond(w)), Rsa(w),Rsb(w),Rtc(w));
+ else
+ db_printf("%s\t%%r%d,%%r%d,%d,%%r%d",
+ edDCond(Cond(w)),Rsa(w),Rsb(w),31-Imd5(w),Rtc(w));
+ return (1);
+}
+
+/* Extract instructions */
+int
+extrDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ db_printf("%s\t%%r%d,%d,%d,%%r%d",
+ edDCond(Cond(w)),Rsb(w),Imd5(w),32 - Rsc(w),Rta(w));
+ return (1);
+}
+
+
+/* Variable extract instructions */
+int
+vextrDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ db_printf("%s\t%%r%d,%d,%%r%d",
+ edDCond(Cond(w)),Rsb(w),32 - Rsc(w),Rta(w));
+ return (1);
+}
+
+
+/* Deposit instructions */
+int
+depDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ db_printf("%s\t%%r%d,%d,%d,%%r%d",
+ edDCond(Cond(w)),Rsa(w),31 - Imd5(w),32 - Rsc(w),Rtb(w));
+ return (1);
+}
+
+
+/* Variable deposit instructions */
+int
+vdepDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ db_printf("%s\t%%r%d,%d,%%r%d",
+ edDCond(Cond(w)),Rsa(w),32 - Rsc(w),Rtb(w));
+ return (1);
+}
+
+
+/* Deposit Immediate instructions */
+int
+depiDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ db_printf("%s\t%d,%d,%d,%%r%d",
+ edDCond(Cond(w)),Ima5(w),31 - Imd5(w),32 - Imc5A(w),Rtb(w));
+ return (1);
+}
+
+/* Variable Deposit Immediate instructions */
+int
+vdepiDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ db_printf("%s\t%d,%d,%%r%d",edDCond(Cond(w)),Ima5(w),32-Imc5A(w),Rtb(w));
+ return (1);
+}
+
+/*---------------------------------------------------------------------------
+ * conditionType$DisassembleCondition - Return a string which contains the
+ * ascii description of the passed numeric condition.
+ *---------------------------------------------------------------------------*/
+
+char *
+subDCond(cond)
+ u_int cond;
+{
+ switch(cond) {
+ case EQZ: return(",=");
+ case LT: return(",<");
+ case LE: return(",<=");
+ case LLT: return(",<<");
+ case LLE: return(",<<=");
+ case SV: return(",sv");
+ case OD: return(",od");
+ case NEQZ: return(",<>");
+ case GE: return(",>=");
+ case GT: return(",>");
+ case LGE: return(",>>=");
+ case LGT: return(",>>");
+ case NSV: return(",nsv");
+ case EV: return(",ev");
+ case TR: return(",tr");
+ case NEV: return("");
+ default:
+ panic("subDCond: unknown condition");
+ }
+}
+
+
+/*---------------------------------------------------------------------------
+ * conditionType$DisassembleCondition - Return a string which contains the
+ * ascii description of the passed numeric condition.
+ *---------------------------------------------------------------------------*/
+
+char *
+addDCond(cond)
+ u_int cond;
+{
+ switch(cond) {
+ case EQZ: return(",=");
+ case LT: return(",<");
+ case LE: return(",<=");
+ case NUV: return(",nuv");
+ case ZNV: return(",znv");
+ case SV: return(",sv");
+ case OD: return(",od");
+ case NEQZ: return(",<>");
+ case GE: return(",>=");
+ case GT: return(",>");
+ case UV: return(",uv");
+ case VNZ: return(",vnz");
+ case NSV: return(",nsv");
+ case EV: return(",ev");
+ case TR: return(",tr");
+ case NEV: return("");
+ default:
+ panic("addDCond: unknown condition");
+ }
+}
+
+char *
+unitDCond(cond)
+ u_int cond;
+{
+ switch(cond) {
+ case SHC: return(",shc");
+ case SHZ: return(",shz");
+ case SBC: return(",sbc");
+ case SBZ: return(",sbz");
+ case SDC: return(",sdc");
+ case NHC: return(",nhc");
+ case NHZ: return(",nhz");
+ case NBC: return(",nbc");
+ case NBZ: return(",nbz");
+ case NDC: return(",ndc");
+ case TR: return(",tr");
+ case NEV: return("");
+ default:
+ panic("unitDCond: unknown condition");
+ }
+}
+
+char *
+edDCond(cond)
+ u_int cond;
+{
+ switch(cond) {
+ case XOD: return(",od");
+ case XTR: return(",tr");
+ case XNE: return(",<>");
+ case XLT: return(",<");
+ case XEQ: return(",=");
+ case XGE: return(",>=");
+ case XEV: return(",ev");
+ case NEV: return("");
+ default:
+ panic("edDCond: unknown condition");
+ }
+}
+
+
+
+/****************************************/
+/* Format Specific Disassembly Routines */
+/****************************************/
+
+
+/* Load [modify] instructions */
+int
+ldDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ register int d = Disp(w);
+ char s[2];
+
+ s[1] = '\0';
+ if (d < 0) {
+ d = -d;
+ s[0] = '-';
+ } else
+ s[0] = '\0';
+
+ if (Rsb(w) == 0 && Match("ldo")) {
+ db_printf("ldi\t%s%X,%%r%d",s,d,Rta(w));
+ return (1);
+ }
+ db_printf("%s\t%s%s%X",i->mnem,(d < 2048? "R'":""), s, d);
+ if (Dss(w))
+ db_printf("(%%sr%d,%%r%d),%%r%d",Dss(w),Rsb(w),Rta(w));
+ else
+ db_printf("(%%r%d),%%r%d",Rsb(w),Rta(w));
+ return (1);
+}
+
+/* Store [modify] instructions */
+int
+stDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ register int d = Disp(w);
+ char s[2];
+
+ db_printf("\t%%r%d,",Rta(w));
+
+ s[1] = '\0';
+ if (d < 0) {
+ d = -d;
+ s[0] = '-';
+ } else
+ s[0] = '\0';
+
+ db_printf("%s%s%X", (d < 2048? "R'":""), s, d);
+
+ if (Dss(w))
+ db_printf("(%%sr%d,%%r%d)",Dss(w),Rsb(w));
+ else
+ db_printf("(%%r%d)",Rsb(w));
+ return (1);
+}
+
+/* Load indexed instructions */
+int
+ldxDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ register const char *p;
+
+ if (ShortDisp(w)) {
+ db_printf("s");
+ if (Modify(w))
+ db_printf(",m%s", ModBefore(w)? "b": "a");
+ } else {
+ db_printf("x");
+ if (Modify(w))
+ db_printf(",%sm", IndxShft(w)? "s":"");
+ }
+ switch (CacheCtrl(w)) {
+ case NOACTION: p = ""; break;
+ case STACKREF: p = ",c"; break;
+ case SEQPASS: p = ",q"; break;
+ case PREFETCH: p = ",p"; break;
+ }
+ if (ShortDisp(w))
+ db_printf("%s\t%d", p, Ima5(w));
+ else
+ db_printf("%s\t%%r%d", p, Rsa(w));
+
+ if (Dss(w))
+ db_printf("(%%sr%d,%%r%d),%%r%d",Dss(w),Rsb(w),Rtc(w));
+ else
+ db_printf("(%%r%d),%%r%d",Rsb(w),Rtc(w));
+ return (1);
+}
+
+/* Store short displacement instructions */
+int
+stsDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ register const char *p;
+ if (Modify(w))
+ db_printf(",m%s", ModBefore(w)? "b":"a");
+
+ switch (CacheCtrl(w)) {
+ case NOACTION: p = ""; break;
+ case STACKREF: p = ",c"; break;
+ case SEQPASS: p = ",q"; break;
+ case PREFETCH: p = ",p"; break;
+ }
+ db_printf("%s\t%%r%d,", p, Rta(w));
+ if (Dss(w))
+ db_printf("%d(%%sr%d,%%r%d)",Imc5(w),Dss(w),Rsb(w));
+ else
+ db_printf("%d(%%r%d)",Imc5(w),Rsb(w));
+ return (1);
+}
+
+/* Store Bytes Instruction */
+int
+stbysDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ register const char *p;
+ db_printf(ModBefore(w)? ",e":",b");
+ if (Modify(w))
+ db_printf(",m");
+ switch (CacheCtrl(w)) {
+ case NOACTION: p = ""; break;
+ case STACKREF: p = ",f"; break;
+ case SEQPASS: p = ",r"; break;
+ case PREFETCH: p = ",z"; break;
+ }
+ db_printf("%s\t%%r%d,", p, Rta(w));
+ if (Dss(w))
+ db_printf("%d(%%sr%d,%%r%d)",Imc5(w),Dss(w),Rsb(w));
+ else
+ db_printf("%d(%%r%d)",Imc5(w),Rsb(w));
+ return (1);
+}
+
+/* Long Immediate instructions */
+int
+limmDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ db_printf("\tL'%X,%%r%d", Im21(w), Rtb(w));
+ return (1);
+}
+
+
+/* Branch and Link instruction(s) (Branch, too!!) */
+int
+blDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ register OFS tgtofs = ofs + 8 + Bdisp(w);
+ register u_int link = Rtb(w);
+
+ if (link && !Match("gate"))
+ db_printf("l");
+ if (Nu(w))
+ db_printf(",n");
+ db_printf("\t");
+
+ db_printsym((db_addr_t)tgtofs, DB_STGY_ANY, db_printf);
+
+ if (link || Match("gate"))
+ db_printf(",%%r%d",link);
+
+ return (1);
+}
+
+/* Branch Register instruction */
+int
+brDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ db_printf("%s\t%%r%d,%%r%d", Nu(w)?",n":"", Rsa(w), Rtb(w));
+ return (1);
+}
+
+/* Dispatch instructions */
+int
+bvDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ db_printf("%s\t%%r%d(%%r%d)", Nu(w)?",n":"", Rsa(w), Rsb(w));
+ return (1);
+}
+
+/* Branch External instructions */
+int
+beDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ register int d = Bdisp(w);
+ register const char *p;
+ char s[2];
+
+ s[1] = '\0';
+ if (d < 0) {
+ d = -d;
+ s[0] = '-';
+ } else
+ s[0] = '\0';
+
+ p = Nu(w)? ",n":"";
+ db_printf("%s\tR'%s%X(%%sr%d,%%r%d)", p, s, d, Sr(w), Rsb(w));
+ return (1);
+}
+
+
+/* Compare/Add and Branch instructions */
+int
+cbDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ register OFS tgtofs = ofs + 8 + Cbdisp(w);
+
+ if (Match("movb"))
+ db_printf(edDCond(Cond(w)));
+ else if (Match("addb"))
+ db_printf(addDCond(Cond(w) << 1));
+ else
+ db_printf(subDCond(Cond(w) << 1));
+ db_printf("%s\t%%r%d,%%r%d,", Nu(w)?",n":"", Rsa(w), Rsb(w));
+ db_printsym((db_addr_t)tgtofs, DB_STGY_ANY, db_printf);
+ return (1);
+}
+
+/* Compare/Add and Branch Immediate instructions */
+int
+cbiDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ register OFS tgtofs = ofs + 8 + Cbdisp(w);
+
+ if (Match("movib"))
+ db_printf(edDCond(Cond(w)));
+ else if (Match("addib"))
+ db_printf(addDCond(Cond(w) << 1));
+ else
+ db_printf(subDCond(Cond(w) << 1));
+ db_printf("%s\t%d,%%r%d,", Nu(w)? ",n":"", Ima5(w), Rsb(w));
+ db_printsym((db_addr_t)tgtofs, DB_STGY_ANY, db_printf);
+ return (1);
+}
+
+/* Branch on Bit instructions */
+int
+bbDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ register OFS tgtofs = ofs + 8 + Cbdisp(w);
+ register const char *p;
+
+ db_printf(edDCond(Cond(w)));
+ p = Nu(w)? ",n":"";
+ if (Match("bvb"))
+ db_printf("%s\t%%r%d,", p, Rta(w));
+ else
+ db_printf("%s\t%%r%d,%d,", p, Rsa(w), Imb5(w));
+ db_printsym((db_addr_t)tgtofs, DB_STGY_ANY, db_printf);
+ return (1);
+}
+
+/* Arithmetic instructions */
+int
+ariDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ if (Match("or") && Rsb(w) == 0 && Cond4(w) == NEV) {
+ if (Rsa(w) == 0 && Rtc(w) == 0)
+ db_printf("nop");
+ else
+ db_printf("copy\t%%r%d,%%r%d",Rsa(w),Rtc(w));
+ } else
+ db_printf("%s%s\t%%r%d,%%r%d,%%r%d", i->mnem,
+ subDCond(Cond4(w)), Rsa(w),Rsb(w),Rtc(w));
+ return(1);
+}
+
+/* System control operations */
+int
+scDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ if (Match("mtctl")) {
+ if (Rtb(w) == 11)
+ db_printf("mtsar\t%%r%d",Rsa(w));
+ else
+ db_printf("mtctl\t%%r%d,%%cr%d",Rsa(w),Rtb(w));
+ return (1);
+ }
+ db_printf(i->mnem);
+ if (Match("ssm") || Match("rsm"))
+ db_printf("\t%d,%%r%d",Ima5A(w),Rtc(w));
+ else if (Match("mtsm")) db_printf("\t%%r%d",Rsa(w));
+ else if (Match("ldprid")) db_printf("\t%%r%d",Rtc(w));
+ else if (Match("mtsp")) db_printf("\t%%r%d,%%sr%d",Rsa(w),Sr(w));
+ else if (Match("mfsp")) db_printf("\t%%sr%d,%%r%d",Sr(w),Rtc(w));
+ else if (Match("mfctl")) db_printf("\t%%cr%d,%%r%d",Rsb(w),Rtc(w));
+ else if (Match("ldsid")) {
+ if (Dss(w))
+ db_printf("\t(%%sr%d,%%r%d),%%r%d",Dss(w),Rsb(w),Rtc(w));
+ else
+ db_printf("\t(%%r%d),%%r%d",Rsb(w),Rtc(w));
+ } else
+ return (0);
+
+ return (1);
+}
+
+/* Instruction cache/tlb control instructions */
+int
+mmgtDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ if (Match("probe")) {
+ if (ProbeI(w)) {
+ if (Dss(w))
+ db_printf("i\t(%%sr%d,%%r%d),%d,%%r%d",
+ Dss(w),Rsb(w),Rsa(w),Rtc(w));
+ else
+ db_printf("i\t(%%r%d),%d,%%r%d",
+ Rsb(w),Rsa(w),Rtc(w));
+ } else {
+ if (Dss(w))
+ db_printf("\t(%%sr%d,%%r%d),%%r%d,%%r%d",
+ Dss(w),Rsb(w),Rsa(w),Rtc(w));
+ else
+ db_printf("\t(%%r%d),%%r%d,%%r%d",
+ Rsb(w),Rsa(w),Rtc(w));
+ }
+ }
+ else if (Match("lha") || Match("lpa")) {
+ if (Modify(w))
+ db_printf(",m");
+ if (Dss(w))
+ db_printf("\t%%r%d(%%sr%d,%%r%d),%%r%d",
+ Rsa(w),Dss(w),Rsb(w),Rtc(w));
+ else
+ db_printf("\t%%r%d(%%r%d),%%r%d",Rsa(w),Rsb(w),Rtc(w));
+ }
+ else if (Match("pdtlb") || Match("pdc") || Match("fdc")) {
+ if (Modify(w)) db_printf(",m");
+ if (Dss(w))
+ db_printf("\t%%r%d(%%sr%d,%%r%d)",Rsa(w),Dss(w),Rsb(w));
+ else
+ db_printf("\t%%r%d(%%r%d)",Rsa(w),Rsb(w));
+ }
+ else if (Match("pitlb") || Match("fic")) {
+ if (Modify(w))
+ db_printf(",m");
+ db_printf("\t%%r%d(%%sr%d,%%r%d)",Rsa(w),Sr(w),Rsb(w));
+ }
+ else if (Match("idtlb")) {
+ if (Dss(w))
+ db_printf("\t%%r%d,(%%sr%d,%%r%d)",Rsa(w),Dss(w),Rsb(w));
+ else
+ db_printf("\t%%r%d,(%%r%d)",Rsa(w),Rsb(w));
+ }
+ else if (Match("iitlb"))
+ db_printf("\t%%r%d,(%%sr%d,%%r%d)",Rsa(w),Sr(w),Rsb(w));
+ else
+ return (0);
+
+ return(1);
+}
+
+/* break instruction */
+int
+brkDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ db_printf("\t%d,%d",Bi1(w),Bi2(w));
+ return (1);
+}
+
+int
+floatDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ register u_int op1, r1, fmt, t;
+ u_int op2, r2, dfmt;
+ char *p;
+
+ op1 = CoprExt1(w);
+ op2 = CoprExt2(w);
+ fmt = (op1 >> 2) & 3; /* get precision of source */
+
+#define ST(r) ((fmt & 1)? fdreg[(r)]:fsreg[(r)])
+ /*
+ * get first (or only) source register
+ * (independent of class)
+ */
+ r1 = (op1 >> 11) & 0x3e;
+ if ((fmt & 1) == 0 && (Uid(w) & 2))
+ r1++;
+
+ if (op1 & 2) { /* class 2 or 3 */
+ /*
+ * get second source register
+ */
+ r2 = (op1 >> 6) & 0x3e;
+ if (fmt == 2)
+ r2++;
+
+ if ((op1 & 1) == 0) { /* class 2 */
+ /* Opclass 2: 2 sources, no destination */
+ switch((op1 >> 4) & 7) {
+ case 0:
+ p = "cmp";
+ break;
+ default:
+ return(0);
+ }
+ db_printf("%s,%s",p,fmtStrTbl[fmt]);
+ db_printf(",%s\t%%f%s,%%f%s",
+ condStrTbl[op2], ST(r1), ST(r2));
+ return (1);
+ }
+ /*
+ * get target register (class 3)
+ */
+ t = (op2 << 1);
+ if ((fmt & 1) == 0 && (Uid(w) & 1))
+ t++;
+ /* Opclass 3: 2 sources, 1 destination */
+ switch((op1 >> 4) & 7) {
+ case 0: p = "add"; break;
+ case 1: p = "sub"; break;
+ case 2: p = (Fpi(w)) ? "mpyi" : "mpy"; break;
+ case 3: p = "div"; break;
+ case 4: p = "rem"; break;
+ default: return (0);
+ }
+ db_printf("%s,%s", p, fmtStrTbl[fmt]);
+ db_printf("\t%%f%s,%%f%s,%%f%s",ST(r1),ST(r2),ST(t));
+ } else if (op1 & 1) { /* class 1 */
+ dfmt = (op1 >> 4) & 3;
+#define DT(r) ((dfmt & 1)? fdreg[(r)]:fsreg[(r)])
+
+ /*
+ * get target register
+ */
+ t = (op2 << 1);
+ if ((dfmt & 1) == 0 && (Uid(w) & 1))
+ t++;
+ /* Opclass 1: 1 source, 1 destination conversions */
+ switch((op1 >> 6) & 3) {
+ case 0: p = "ff"; break;
+ case 1: p = "xf"; break;
+ case 2: p = "fx"; break;
+ case 3: p = "fxt"; break;
+ }
+ db_printf("%s,%s", p, fmtStrTbl[fmt]);
+ db_printf(",%s\t%%f%s,%%f%s",fmtStrTbl[dfmt],ST(r1),DT(t));
+ } else { /* class 0 */
+ /*
+ * get target register
+ */
+ t = (op2 << 1);
+ if ((fmt & 1) == 0 && (Uid(w) & 1))
+ t++;
+ /* Opclass 0: 1 source, 1 destination */
+ switch((op1 >> 4) & 7) {
+ case 1: p = "rsqrt"; break;
+ case 2: p = "cpy"; break;
+ case 3: p = "abs"; break;
+ case 4: p = "sqrt"; break;
+ case 5: p = "rnd"; break;
+ default: return (0);
+ }
+ db_printf("%s,%s",p,fmtStrTbl[fmt]);
+ db_printf("\t%%f%s,%%f%s",ST(r1),ST(t));
+ }
+ return (1);
+}
+
+int
+fcoprDasm(w, op1, op2)
+ int w;
+ u_int op1, op2;
+{
+ register u_int r1, r2, t, fmt, dfmt;
+ register char *p;
+
+ if (AstNu(w) && op1 == ((1<<4) | 2)) {
+ if (op2 == 0 || op2 == 1 || op2 == 2) {
+ db_printf("ftest");
+ if (op2 == 1)
+ db_printf(",acc");
+ else if (op2 == 2)
+ db_printf(",rej");
+ return (1);
+ }
+ return (0);
+ } else if (0 == op1 && 0 == op2) {
+ db_printf("fcopr identify");
+ return (1);
+ }
+ switch(op1 & 3) {
+ case 0:
+ /* Opclass 0: 1 source, 1 destination */
+ r1 = (op1 >> 12) & 0x1f; t = op2; fmt = (op1 >> 2) & 3;
+ switch((op1 >> 4) & 7) {
+ case 1: p = "rsqrt"; break;
+ case 2: p = "cpy"; break;
+ case 3: p = "abs"; break;
+ case 4: p = "sqrt"; break;
+ case 5: p = "rnd"; break;
+ default: return(0);
+ }
+ db_printf("f%s,%s\t%%fr%d,%%fr%d", p, fmtStrTbl[fmt], r1, t);
+ break;
+ case 1:
+ /* Opclass 1: 1 source, 1 destination conversions */
+ r1 = (op1 >> 12) & 0x1f; t = op2;
+ fmt = (op1 >> 2) & 3; dfmt = (op1 >> 4) & 3;
+ switch((op1 >> 6) & 3) {
+ case 0: p = "ff"; break;
+ case 1: p = "xf"; break;
+ case 2: p = "fx"; break;
+ case 3: p = "fxt"; break;
+ }
+ db_printf("fcnv%s,%s,%s\t%%fr%d,%%fr%d",
+ p, fmtStrTbl[fmt], fmtStrTbl[dfmt], r1, t);
+ break;
+ case 2:
+ /* Opclass 2: 2 sources, no destination */
+ r1 = (op1 >> 12) & 0x1f; r2 = (op1 >> 7) & 0x1f;
+ fmt = (op1 >> 2) & 3;
+ switch((op1 >> 4) & 7) {
+ case 0: p = "fcmp"; break;
+ default: return (0);
+ }
+ db_printf("%s,%s,%s\t%%fr%d,%%fr%d",
+ p,fmtStrTbl[fmt],condStrTbl[op2],r1,r2);
+ break;
+ case 3:
+ /* Opclass 3: 2 sources, 1 destination */
+ r1 = (op1 >> 12) & 0x1f; r2 = (op1 >> 7) & 0x1f; t = op2;
+ fmt = (op1 >> 2) & 3;
+ switch((op1 >> 4) & 7) {
+ case 0: p = "add"; break;
+ case 1: p = "sub"; break;
+ case 2: p = "mpy"; break;
+ case 3: p = "div"; break;
+ case 4: p = "rem"; break;
+ default: return (0);
+ }
+ db_printf("f%s,%s\t%%fr%d,%%fr%d,%%fr%d",
+ p, fmtStrTbl[fmt], r1, r2, t);
+ break;
+ default:
+ return(0);
+ }
+ return (1);
+}
+
+int
+coprDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ register u_int uid = Uid(w);
+ register int load = 0;
+ register char *pfx = uid > 1 ? "c" : "f";
+ register int dreg = 0;
+
+ if (Match("copr")) {
+ if (uid) {
+ db_printf("copr,%d,0x%x",uid,CoprExt(w));
+ if (AstNu(w))
+ db_printf(",n");
+ return (1);
+ }
+ return fcoprDasm(w, CoprExt1(w),CoprExt2(w));
+ }
+ if (Match("cldd")) {
+ dreg = 1;
+ load = 1;
+ db_printf("%sldd",pfx);
+ } else if (Match("cldw")) {
+ load = 1;
+ db_printf("%sldw",pfx);
+ } else if (Match("cstd")) {
+ dreg = 1;
+ db_printf("%sstd",pfx);
+ } else if (Match("cstw"))
+ db_printf("%sstw",pfx);
+ else
+ return (0);
+
+ if (ShortDisp(w)) {
+ db_printf("s");
+ if (AstNu(w))
+ db_printf(",m%s", ModBefore(w)?"b":"a");
+ }
+ else {
+ db_printf("x");
+ if (AstNu(w))
+ db_printf(",%sm", IndxShft(w)?"s":"");
+ else if (IndxShft(w))
+ db_printf(",s");
+ }
+ switch (CacheCtrl(w)) {
+ case NOACTION: break;
+ case STACKREF: db_printf(",c"); break;
+ case SEQPASS: db_printf(",q"); break;
+ case PREFETCH: db_printf(",p"); break;
+ }
+ if (load) {
+ register const char *p;
+
+ if (dreg)
+ p = fdreg[(Rtc(w)<<1)+(uid&1)];
+ else
+ p = fsreg[(Rtc(w)<<1)+(uid&1)];
+
+ if (ShortDisp(w))
+ db_printf("\t%d",Ima5(w));
+ else
+ db_printf("\t%%r%d",Rsa(w));
+ if (Dss(w))
+ db_printf("(%%sr%d,%%r%d),%%f%s", Dss(w),Rsb(w), p);
+ else
+ db_printf("(%%r%d),%%f%s",Rsb(w), p);
+ } else {
+ register const char *p;
+
+ if (dreg)
+ p = fdreg[(Rsc(w)<<1)+(uid&1)];
+ else
+ p = fsreg[(Rsc(w)<<1)+(uid&1)];
+
+ if (ShortDisp(w))
+ db_printf("\t%%f%s,%d", p, Ima5(w));
+ else
+ db_printf("\t%%f%s,%%r%d", p, Rta(w));
+ if (Dss(w))
+ db_printf("(%%sr%d,%%r%d)",Dss(w),Rsb(w));
+ else
+ db_printf("(%%r%d)",Rsb(w));
+ }
+ return (1);
+}
+
+int
+lpkDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ /*
+ * Floating point STore Quad
+ * Short or Indexed
+ */
+ if (ShortDisp(w)) {
+ if (Modify(w))
+ db_printf(",m%s", ModBefore(w)?"b":"a");
+ } else {
+ if (Modify(w))
+ db_printf(",%sm", IndxShft(w)? "s":"");
+ else if (IndxShft(w))
+ db_printf(",s");
+ }
+ switch (CacheCtrl(w)) {
+ case NOACTION: break;
+ case STACKREF: db_printf(",c"); break;
+ case SEQPASS: db_printf(",q"); break;
+ case PREFETCH: db_printf(",p"); break;
+ }
+ if (ShortDisp(w))
+ db_printf("\t%%fr%d,%d",Rsc(w),Ima5(w));
+ else
+ db_printf("\t%%fr%d,%%r%d",Rsc(w),Rta(w));
+ if (Dss(w))
+ db_printf("(%%sr%d,%%r%d)",Dss(w),Rsb(w));
+ else
+ db_printf("(%%r%d)",Rsb(w));
+ return (1);
+}
+
+int
+diagDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ if (0x0b0 == BitfR(w,19,8,_b198)) /* mtcpu */
+ db_printf("mtcpu\t%%r%d,%%dr%d", Rsa(w), Rtb(w));
+ else if (0x0d0 == BitfR(w,19,8,_b198)) /* mfcpu */
+ db_printf("mfcpu\t%%dr%d,%%r%d", Rsb(w), Rta(w));
+ else {
+ db_printf(i->mnem);
+ if (Match("diag"))
+ db_printf("\t0x%X",w & 0x03ffffff);
+ else
+ return (0);
+ }
+ return (1);
+}
+
+int
+fmpysubDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ if (SinglePrec(w))
+ db_printf("SUB,SGL\t%%f%s,%%f%s,%%f%s,%%f%s,%%f%s",
+ fsreg[Ms1(w)], fsreg[Ms2(w)], fsreg[Mt(w)],
+ fsreg[As(w)], fsreg[Ad(w)]);
+ else
+ db_printf("SUB,DBL\t%%f%s,%%f%s,%%f%s,%%f%s,%%f%s",
+ fdreg[Ms1(w)], fdreg[Ms2(w)], fdreg[Mt(w)],
+ fdreg[As(w)], fdreg[Ad(w)]);
+ return (1);
+}
+
+int
+fmpyaddDasm(i, ofs, w)
+ const struct inst *i;
+ OFS ofs;
+ int w;
+{
+ register const char
+ *ms1 = SinglePrec(w) ? fsreg[Ms1(w)] : fdreg[Ms1(w)],
+ *ms2 = SinglePrec(w) ? fsreg[Ms2(w)] : fdreg[Ms2(w)],
+ *mt = SinglePrec(w) ? fsreg[Mt(w)] : fdreg[Mt(w)],
+ *as = SinglePrec(w) ? fsreg[As(w)] : fdreg[As(w)],
+ *ad = SinglePrec(w) ? fsreg[Ad(w)] : fdreg[Ad(w)];
+
+ if (Rsd(w) == 0)
+ db_printf("\t%%fcfxt,%s,%%f%s,%%f%s,%%f%s",
+ ((SinglePrec(w)) ? "sgl" : "dbl"), ms1, ms2, mt);
+ else
+ db_printf("add%s\t%%f%s,%%f%s,%%f%s,%%f%s,%%f%s",
+ ((SinglePrec(w)) ? "sgl" : "dbl"), ms1, ms2, mt, as, ad);
+
+ return (1);
+}
+
+vaddr_t
+db_disasm(loc, flag)
+ vaddr_t loc;
+ boolean_t flag;
+{
+ register const struct inst *i;
+ register const struct majoropcode *m;
+ register u_int ext;
+ int ok, instruct;
+ OFS ofs = 0;
+
+ iExInit();
+/* TODO if (loc == PC_REGS(&ddb_regs) && ddb_regs.tf_iir)
+ instruct = ddb_regs.tf_iir;
+ else */ if (USERMODE(loc)) {
+ if (copyin((caddr_t)(loc &~ HPPA_PC_PRIV_MASK),
+ &instruct, sizeof(instruct)))
+ instruct = 0;
+ } else
+ instruct = *(int *)loc;
+
+ ok = 0;
+ m = &majopcs[Opcode(instruct)];
+ ext = OpExt(instruct, m);
+ if (ext <= m->maxsubop) {
+ /* special hack for majopcs table layout */
+ if (m->maxsubop == 1)
+ i = (const struct inst *)m->subops;
+ else
+ i = m->subops[ext];
+
+ if (i && i->mnem[0] != '?') {
+ if (i->dasmfcn != coprDasm && i->dasmfcn != diagDasm &&
+ i->dasmfcn != ariDasm && i->dasmfcn != scDasm &&
+ i->dasmfcn != ldDasm)
+ db_printf(i->mnem);
+ if (i->dasmfcn)
+ ok = (*i->dasmfcn)(i, ofs, instruct);
+ }
+ }
+
+ if (!ok)
+ db_printf("<%08x>", instruct);
+
+ db_printf("\n");
+ return (loc + sizeof(instruct));
+}
diff --git a/sys/arch/hppa64/hppa64/db_interface.c b/sys/arch/hppa64/hppa64/db_interface.c
new file mode 100644
index 00000000000..8467caa93db
--- /dev/null
+++ b/sys/arch/hppa64/hppa64/db_interface.c
@@ -0,0 +1,320 @@
+/* $OpenBSD: db_interface.c,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define DDB_DEBUG
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <machine/db_machdep.h>
+#include <machine/frame.h>
+
+#include <ddb/db_access.h>
+#include <ddb/db_command.h>
+#include <ddb/db_output.h>
+#include <ddb/db_run.h>
+#include <ddb/db_sym.h>
+#include <ddb/db_var.h>
+#include <ddb/db_variables.h>
+#include <ddb/db_extern.h>
+#include <ddb/db_interface.h>
+
+#include <dev/cons.h>
+
+void kdbprinttrap(int, int);
+
+extern char *trap_type[];
+extern int trap_types;
+
+db_regs_t ddb_regs;
+struct db_variable db_regs[] = {
+ { "flags", (long *)&ddb_regs.tf_flags, FCN_NULL },
+ { "r1", (long *)&ddb_regs.tf_r1, FCN_NULL },
+ { "rp", (long *)&ddb_regs.tf_rp, FCN_NULL },
+ { "r3", (long *)&ddb_regs.tf_r3, FCN_NULL },
+ { "r4", (long *)&ddb_regs.tf_r4, FCN_NULL },
+ { "r5", (long *)&ddb_regs.tf_r5, FCN_NULL },
+ { "r6", (long *)&ddb_regs.tf_r6, FCN_NULL },
+ { "r7", (long *)&ddb_regs.tf_r7, FCN_NULL },
+ { "r8", (long *)&ddb_regs.tf_r8, FCN_NULL },
+ { "r9", (long *)&ddb_regs.tf_r9, FCN_NULL },
+ { "r10", (long *)&ddb_regs.tf_r10, FCN_NULL },
+ { "r11", (long *)&ddb_regs.tf_r11, FCN_NULL },
+ { "r12", (long *)&ddb_regs.tf_r12, FCN_NULL },
+ { "r13", (long *)&ddb_regs.tf_r13, FCN_NULL },
+ { "r14", (long *)&ddb_regs.tf_r14, FCN_NULL },
+ { "r15", (long *)&ddb_regs.tf_r15, FCN_NULL },
+ { "r16", (long *)&ddb_regs.tf_r16, FCN_NULL },
+ { "r17", (long *)&ddb_regs.tf_r17, FCN_NULL },
+ { "r18", (long *)&ddb_regs.tf_r18, FCN_NULL },
+ { "r19", (long *)&ddb_regs.tf_args[7], FCN_NULL },
+ { "r20", (long *)&ddb_regs.tf_args[6], FCN_NULL },
+ { "r21", (long *)&ddb_regs.tf_args[5], FCN_NULL },
+ { "r22", (long *)&ddb_regs.tf_args[4], FCN_NULL },
+ { "r23", (long *)&ddb_regs.tf_args[3], FCN_NULL },
+ { "r24", (long *)&ddb_regs.tf_args[2], FCN_NULL },
+ { "r25", (long *)&ddb_regs.tf_args[1], FCN_NULL },
+ { "r26", (long *)&ddb_regs.tf_args[0], FCN_NULL },
+ { "r27", (long *)&ddb_regs.tf_dp, FCN_NULL },
+ { "r28", (long *)&ddb_regs.tf_ret0, FCN_NULL },
+ { "r29", (long *)&ddb_regs.tf_ret1, FCN_NULL },
+ { "r30", (long *)&ddb_regs.tf_sp, FCN_NULL },
+ { "r31", (long *)&ddb_regs.tf_r31, FCN_NULL },
+ { "sar", (long *)&ddb_regs.tf_sar, FCN_NULL },
+
+ { "rctr", (long *)&ddb_regs.tf_rctr, FCN_NULL },
+ { "ccr", (long *)&ddb_regs.tf_ccr, FCN_NULL },
+ { "eirr", (long *)&ddb_regs.tf_eirr, FCN_NULL },
+ { "eiem", (long *)&ddb_regs.tf_eiem, FCN_NULL },
+ { "iir", (long *)&ddb_regs.tf_iir, FCN_NULL },
+ { "isr", (long *)&ddb_regs.tf_isr, FCN_NULL },
+ { "ior", (long *)&ddb_regs.tf_ior, FCN_NULL },
+ { "ipsw", (long *)&ddb_regs.tf_ipsw, FCN_NULL },
+ { "iisqh", (long *)&ddb_regs.tf_iisq[0], FCN_NULL },
+ { "iioqh", (long *)&ddb_regs.tf_iioq[0], FCN_NULL },
+ { "iisqt", (long *)&ddb_regs.tf_iisq[1], FCN_NULL },
+ { "iioqt", (long *)&ddb_regs.tf_iioq[1], FCN_NULL },
+ { "ci", (long *)&ddb_regs.tf_ci, FCN_NULL },
+ { "vtop", (long *)&ddb_regs.tf_vtop, FCN_NULL },
+ { "cr27", (long *)&ddb_regs.tf_cr27, FCN_NULL },
+ { "cr30", (long *)&ddb_regs.tf_cr30, FCN_NULL },
+
+ { "sr0", (long *)&ddb_regs.tf_sr0, FCN_NULL },
+ { "sr1", (long *)&ddb_regs.tf_sr1, FCN_NULL },
+ { "sr2", (long *)&ddb_regs.tf_sr2, FCN_NULL },
+ { "sr3", (long *)&ddb_regs.tf_sr3, FCN_NULL },
+ { "sr4", (long *)&ddb_regs.tf_sr4, FCN_NULL },
+ { "sr5", (long *)&ddb_regs.tf_sr5, FCN_NULL },
+ { "sr6", (long *)&ddb_regs.tf_sr6, FCN_NULL },
+ { "sr7", (long *)&ddb_regs.tf_sr7, FCN_NULL },
+
+ { "pidr1", (long *)&ddb_regs.tf_pidr1, FCN_NULL },
+ { "pidr2", (long *)&ddb_regs.tf_pidr2, FCN_NULL },
+};
+struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
+int db_active = 0;
+
+void
+Debugger()
+{
+ __asm __volatile ("break %0, %1"
+ :: "i" (HPPA_BREAK_KERNEL), "i" (HPPA_BREAK_KGDB));
+}
+
+void
+db_read_bytes(addr, size, data)
+ vaddr_t addr;
+ size_t size;
+ char *data;
+{
+ register char *src = (char *)addr;
+
+ while (size--)
+ *data++ = *src++;
+}
+
+void
+db_write_bytes(addr, size, data)
+ vaddr_t addr;
+ size_t size;
+ char *data;
+{
+ register char *dst = (char *)addr;
+
+ while (size--)
+ *dst++ = *data++;
+
+ /* unfortunately ddb does not provide any hooks for these */
+ ficache(HPPA_SID_KERNEL, (vaddr_t)data, size);
+ fdcache(HPPA_SID_KERNEL, (vaddr_t)data, size);
+}
+
+
+/*
+ * Print trap reason.
+ */
+void
+kdbprinttrap(type, code)
+ int type, code;
+{
+ type &= ~T_USER; /* just in case */
+ db_printf("kernel: ");
+ if (type >= trap_types || type < 0)
+ db_printf("type 0x%x", type);
+ else
+ db_printf("%s", trap_type[type]);
+ db_printf(" trap, code=0x%x\n", code);
+}
+
+/*
+ * kdb_trap - field a BPT trap
+ */
+int
+kdb_trap(type, code, regs)
+ int type, code;
+ db_regs_t *regs;
+{
+ extern label_t *db_recover;
+ int s;
+
+ switch (type) {
+ case T_IBREAK:
+ case T_DBREAK:
+ case -1:
+ break;
+ default:
+ if (!db_panic)
+ return (0);
+
+ kdbprinttrap(type, code);
+ if (db_recover != 0) {
+ db_error("Caught exception in DDB; continuing...\n");
+ /* NOT REACHED */
+ }
+ }
+
+ /* XXX Should switch to kdb`s own stack here. */
+
+ s = splhigh();
+ bcopy(regs, &ddb_regs, sizeof(ddb_regs));
+ db_active++;
+ cnpollc(TRUE);
+ db_trap(type, code);
+ cnpollc(FALSE);
+ db_active--;
+ bcopy(&ddb_regs, regs, sizeof(*regs));
+ splx(s);
+
+ return (1);
+}
+
+/*
+ * Validate an address for use as a breakpoint.
+ * Any address is allowed for now.
+ */
+int
+db_valid_breakpoint(addr)
+ db_addr_t addr;
+{
+ return (1);
+}
+
+void
+db_stack_trace_print(addr, have_addr, count, modif, pr)
+ db_expr_t addr;
+ int have_addr;
+ db_expr_t count;
+ char *modif;
+ int (*pr)(const char *, ...);
+{
+ register_t *fp, pc, rp, *argp;
+ db_sym_t sym;
+ db_expr_t off;
+ char *name;
+ char **argnp, *argnames[8];
+ int nargs;
+
+ if (count < 0)
+ count = 65536;
+
+ if (!have_addr) {
+ fp = (register_t *)ddb_regs.tf_r3;
+ pc = ddb_regs.tf_iioq[0];
+ rp = ddb_regs.tf_rp;
+ } else {
+ fp = (register_t *)addr;
+ pc = 0;
+ rp = ((register_t *)fp)[-5];
+ }
+
+#ifdef DDB_DEBUG
+ (*pr) (">> %p, 0x%lx, 0x%lx\t", fp, pc, rp);
+#endif
+ while (fp && count--) {
+
+ if (USERMODE(pc))
+ return;
+
+ sym = db_search_symbol(pc, DB_STGY_ANY, &off);
+ db_symbol_values (sym, &name, NULL);
+
+ (*pr)("%s(", name);
+
+ /* args */
+ nargs = 8;
+ argnp = NULL;
+ if (db_sym_numargs(sym, &nargs, argnames))
+ argnp = argnames;
+ else
+ nargs = 4;
+ /*
+ * XXX first eight args are passed on registers, and may not
+ * be stored on stack, dunno how to recover their values yet
+ */
+ for (argp = &fp[-9]; nargs--; argp--) {
+ if (argnp)
+ (*pr)("%s=", *argnp++);
+ (*pr)("%x%s", db_get_value((long)argp, 8, FALSE),
+ nargs? ",":"");
+ }
+ (*pr)(") at ");
+ db_printsym(pc, DB_STGY_PROC, pr);
+ (*pr)("\n");
+
+ /* TODO: print locals */
+
+ /* next frame */
+ pc = rp;
+ rp = fp[-2];
+
+ /* if a terminal frame and not a start of a page
+ * then skip the trapframe and the terminal frame */
+ if (!fp[0]) {
+ struct trapframe *tf;
+
+ tf = (struct trapframe *)((char *)fp - sizeof(*tf));
+
+ if (tf->tf_flags & TFF_SYS)
+ (*pr)("-- syscall #%d(%lx, %lx, %lx, %lx, ...)\n",
+ tf->tf_r1, tf->tf_args[0], tf->tf_args[1],
+ tf->tf_args[2], tf->tf_args[3],
+ tf->tf_args[4], tf->tf_args[5],
+ tf->tf_args[6], tf->tf_args[7]);
+ else
+ (*pr)("-- trap #%d%s\n", tf->tf_flags & 0x3f,
+ (tf->tf_flags & T_USER)? " from user" : "");
+
+ if (!(tf->tf_flags & TFF_LAST)) {
+ fp = (register_t *)tf->tf_r3;
+ pc = tf->tf_iioq[0];
+ rp = tf->tf_rp;
+ } else
+ fp = 0;
+ } else
+ fp = (register_t *)fp[0];
+#ifdef DDB_DEBUG
+ (*pr) (">> %p, 0x%lx, 0x%lx\t", fp, pc, rp);
+#endif
+ }
+
+ if (count && pc) {
+ db_printsym(pc, DB_STGY_XTRN, pr);
+ (*pr)(":\n");
+ }
+}
diff --git a/sys/arch/hppa64/hppa64/disksubr.c b/sys/arch/hppa64/hppa64/disksubr.c
new file mode 100644
index 00000000000..bddccac5a5c
--- /dev/null
+++ b/sys/arch/hppa64/hppa64/disksubr.c
@@ -0,0 +1,986 @@
+/* $OpenBSD: disksubr.c,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 1999 Michael Shalayeff
+ * Copyright (c) 1997 Niklas Hallqvist
+ * Copyright (c) 1996 Theo de Raadt
+ * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
+ */
+
+/*
+ * This disksubr.c module started to take it's present form on OpenBSD/alpha
+ * but it was always thought it should be made completely MI and not need to
+ * be in that alpha-specific tree at all.
+ *
+ * XXX The DOS partitioning code is not endian-independent, only native
+ * endian DOS partition tables can be parsed yet.
+ *
+ * XXX Amiga RDB partitioning is not understood yet.
+ *
+ * XXX HPUX disklabel is not understood yet.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/device.h>
+#include <sys/disklabel.h>
+#include <sys/syslog.h>
+#include <sys/disk.h>
+
+/* The native defaults... */
+#if defined(alpha) && !defined(DISKLABEL_ALPHA)
+#define DISKLABEL_ALPHA
+#elif (defined(i386) || defined(arc)) && !defined(DISKLABEL_I386)
+#define DISKLABEL_I386
+#elif defined(amiga) && !defined(DISKLABEL_AMIGA)
+#define DISKLABEL_AMIGA
+#elif (defined(hppa) || defined(hppa64)) && !defined(DISKLABEL_HPPA)
+#define DISKLABEL_HPPA
+#endif
+
+#define b_cylin b_resid
+
+#if defined(DISKLABEL_I386) || defined(DISKLABEL_ALPHA) || defined(DISKLABEL_AMIGA) || defined(DISKLABEL_HPPA) || defined(DISKLABEL_ALL)
+void swapdisklabel(struct disklabel *d);
+char *readbsdlabel(struct buf *, void (*)(struct buf *), int, int,
+ int, int, struct disklabel *, int);
+#endif
+#if defined(DISKLABEL_I386) || defined(DISKLABEL_ALL)
+char *readdoslabel(struct buf *, void (*)(struct buf *),
+ struct disklabel *, struct cpu_disklabel *, int *, int *, int);
+#endif
+#if defined(DISKLABEL_AMIGA) || defined(DISKLABEL_ALL)
+char *readamigalabel(struct buf *, void (*)(struct buf *),
+ struct disklabel *, struct cpu_disklabel *, int);
+#endif
+#if defined(DISKLABEL_HPPA) || defined(DISKLABEL_ALL)
+char *readliflabel(struct buf *, void (*)(struct buf *),
+ struct disklabel *, struct cpu_disklabel *, int *, int *, int);
+#endif
+
+static enum disklabel_tag probe_order[] = { LABELPROBES, -1 };
+
+void
+dk_establish(dk, dev)
+ struct disk *dk;
+ struct device *dev;
+{
+}
+
+#if defined(DISKLABEL_I386) || defined(DISKLABEL_ALPHA) || defined(DISKLABEL_AMIGA) || defined(DISKLABEL_HPPA) || defined(DISKLABEL_ALL)
+
+/*
+ * Byteswap all the fields that might be swapped.
+ */
+void
+swapdisklabel(dlp)
+ struct disklabel *dlp;
+{
+ int i;
+ struct partition *pp;
+
+ swap32(dlp->d_magic);
+ swap16(dlp->d_type);
+ swap16(dlp->d_subtype);
+ swap32(dlp->d_secsize);
+ swap32(dlp->d_nsectors);
+ swap32(dlp->d_ntracks);
+ swap32(dlp->d_ncylinders);
+ swap32(dlp->d_secpercyl);
+ swap32(dlp->d_secperunit);
+ swap16(dlp->d_sparespertrack);
+ swap16(dlp->d_sparespercyl);
+ swap32(dlp->d_acylinders);
+ swap16(dlp->d_rpm);
+ swap16(dlp->d_interleave);
+ swap16(dlp->d_trackskew);
+ swap16(dlp->d_cylskew);
+ swap32(dlp->d_headswitch);
+ swap32(dlp->d_trkseek);
+ swap32(dlp->d_flags);
+ for (i = 0; i < NDDATA; i++)
+ swap32(dlp->d_drivedata[i]);
+ for (i = 0; i < NSPARE; i++)
+ swap32(dlp->d_spare[i]);
+ swap32(dlp->d_magic2);
+ swap16(dlp->d_checksum);
+ swap16(dlp->d_npartitions);
+ swap32(dlp->d_bbsize);
+ swap32(dlp->d_sbsize);
+ for (i = 0; i < MAXPARTITIONS; i++) {
+ pp = &dlp->d_partitions[i];
+ swap32(pp->p_size);
+ swap32(pp->p_offset);
+ swap32(pp->p_fsize);
+ swap16(pp->p_cpg);
+ }
+}
+
+/*
+ * Try to read a standard BSD disklabel at a certain sector.
+ */
+char *
+readbsdlabel(bp, strat, cyl, sec, off, endian, lp, spoofonly)
+ struct buf *bp;
+ void (*strat)(struct buf *);
+ int cyl, sec, off, endian;
+ struct disklabel *lp;
+ int spoofonly;
+{
+ struct disklabel *dlp;
+ char *msg = NULL;
+ u_int16_t cksum;
+ u_int32_t magic;
+
+ if (endian != LITTLE_ENDIAN && endian != BIG_ENDIAN)
+ panic("readbsdlabel: unsupported byteorder %d", endian);
+
+ /* don't read the on-disk label if we are in spoofed-only mode */
+ if (spoofonly)
+ return (NULL);
+
+ bp->b_blkno = sec;
+ bp->b_cylin = cyl;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ (*strat)(bp);
+
+ /* if successful, locate disk label within block and validate */
+ if (biowait(bp)) {
+ /* XXX we return the faked label built so far */
+ msg = "disk label I/O error";
+ return (msg);
+ }
+
+ magic = endian == BIG_ENDIAN ? htobe32(DISKMAGIC) : htole32(DISKMAGIC);
+
+ /*
+ * If off is negative, search until the end of the sector for
+ * the label, otherwise, just look at the specific location
+ * we're given.
+ */
+ dlp = (struct disklabel *)(bp->b_data + (off >= 0 ? off : 0));
+ do {
+ if (dlp->d_magic != magic || dlp->d_magic2 != magic) {
+ if (msg == NULL)
+ msg = "no disk label";
+ } else {
+ cksum = dkcksum(dlp);
+ if (endian != BYTE_ORDER)
+ swapdisklabel(dlp);
+ if (dlp->d_npartitions > MAXPARTITIONS || cksum != 0) {
+ msg = "disk label corrupted";
+ /* swap back if necessary. */
+ if (off < 0 && endian != BYTE_ORDER)
+ swapdisklabel(dlp);
+ } else {
+ *lp = *dlp;
+ /* Recalc magic on foreign labels */
+ if (endian != BYTE_ORDER) {
+ lp->d_checksum = 0;
+ lp->d_checksum = dkcksum(lp);
+ }
+ msg = NULL;
+ break;
+ }
+ }
+ if (off >= 0)
+ break;
+ dlp = (struct disklabel *)((char *)dlp + sizeof(int32_t));
+ } while (dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize -
+ sizeof(*dlp)));
+ return (msg);
+}
+#endif
+
+/*
+ * Attempt to read a disk label from a device
+ * using the indicated strategy routine.
+ * The label must be partly set up before this:
+ * secpercyl, secsize and anything required for a block i/o read
+ * operation in the driver's strategy/start routines
+ * must be filled in before calling us.
+ *
+ * Returns null on success and an error string on failure.
+ */
+char *
+readdisklabel(dev, strat, lp, osdep, spoofonly)
+ dev_t dev;
+ void (*strat)(struct buf *);
+ struct disklabel *lp;
+ struct cpu_disklabel *osdep;
+ int spoofonly;
+{
+ struct buf *bp = NULL;
+ char *msg = "no disk label";
+ enum disklabel_tag *tp;
+ int i;
+ struct disklabel minilabel, fallbacklabel;
+
+ /* minimal requirements for archtypal disk label */
+ if (lp->d_secsize < DEV_BSIZE)
+ lp->d_secsize = DEV_BSIZE;
+ if (lp->d_secperunit == 0)
+ lp->d_secperunit = 0x1fffffff;
+ if (lp->d_secpercyl == 0) {
+ msg = "invalid geometry";
+ goto done;
+ }
+ lp->d_npartitions = RAW_PART + 1;
+ for (i = 0; i < RAW_PART; i++) {
+ lp->d_partitions[i].p_size = 0;
+ lp->d_partitions[i].p_offset = 0;
+ }
+ if (lp->d_partitions[i].p_size == 0)
+ lp->d_partitions[i].p_size = 0x1fffffff;
+ lp->d_partitions[i].p_offset = 0;
+ minilabel = fallbacklabel = *lp;
+
+ /* get a buffer and initialize it */
+ bp = geteblk((int)lp->d_secsize);
+ bp->b_dev = dev;
+
+ for (tp = probe_order; msg && *tp != -1; tp++) {
+ switch (*tp) {
+ case DLT_ALPHA:
+#if defined(DISKLABEL_ALPHA) || defined(DISKLABEL_ALL)
+ msg = readbsdlabel(bp, strat, 0, ALPHA_LABELSECTOR,
+ ALPHA_LABELOFFSET, LITTLE_ENDIAN, lp, spoofonly);
+#endif
+ break;
+
+ case DLT_I386:
+#if defined(DISKLABEL_I386) || defined(DISKLABEL_ALL)
+ msg = readdoslabel(bp, strat, lp, osdep, 0, 0, spoofonly);
+ if (msg)
+ /* Fallback alternative */
+ fallbacklabel = *lp;
+#endif
+ break;
+
+ case DLT_AMIGA:
+#if defined(DISKLABEL_AMIGA) || defined(DISKLABEL_ALL)
+ msg = readamigalabel(bp, strat, lp, osdep, spoofonly);
+#endif
+ break;
+
+ case DLT_HPPA:
+#if defined(DISKLABEL_HPPA) || defined(DISKLABEL_ALL)
+ msg = readliflabel(bp, strat, lp, osdep, 0, 0, spoofonly);
+#endif
+ break;
+
+ default:
+ panic("unrecognized disklabel tag %d", *tp);
+ }
+ if (msg)
+ *lp = minilabel;
+ }
+
+ /* Record metainformation about the disklabel. */
+ if (msg == NULL) {
+ osdep->labelsector = bp->b_blkno;
+ osdep->labeltag = *tp;
+ }
+
+#if defined(CD9660)
+ if (msg && iso_disklabelspoof(dev, strat, lp) == 0)
+ msg = NULL;
+#endif
+
+ /* If there was an error, still provide a decent fake one. */
+ if (msg)
+ *lp = fallbacklabel;
+
+done:
+ if (bp) {
+ bp->b_flags |= B_INVAL;
+ brelse(bp);
+ }
+ return (msg);
+}
+
+#if defined(DISKLABEL_I386) || defined(DISKLABEL_ALL)
+/*
+ * If dos partition table requested, attempt to load it and
+ * find disklabel inside a DOS partition. Also, if bad block
+ * table needed, attempt to extract it as well. Return buffer
+ * for use in signalling errors if requested.
+ *
+ * We would like to check if each MBR has a valid BOOT_MAGIC, but
+ * we cannot because it doesn't always exist. So.. we assume the
+ * MBR is valid.
+ */
+char *
+readdoslabel(bp, strat, lp, osdep, partoffp, cylp, spoofonly)
+ struct buf *bp;
+ void (*strat)(struct buf *);
+ struct disklabel *lp;
+ struct cpu_disklabel *osdep;
+ int *partoffp;
+ int *cylp;
+ int spoofonly;
+{
+ struct dos_partition *dp = osdep->u._i386.dosparts, *dp2;
+ struct dkbad *db, *bdp = &DKBAD(osdep);
+ char *msg = NULL, *cp;
+ int dospartoff, cyl, i, ourpart = -1;
+ dev_t dev;
+
+ if (lp->d_secpercyl == 0) {
+ msg = "invalid label, d_secpercyl == 0";
+ return (msg);
+ }
+ if (lp->d_secsize == 0) {
+ msg = "invalid label, d_secsize == 0";
+ return (msg);
+ }
+
+ /* do dos partitions in the process of getting disklabel? */
+ dospartoff = 0;
+ cyl = I386_LABELSECTOR / lp->d_secpercyl;
+ if (dp) {
+ daddr_t part_blkno = DOSBBSECTOR;
+ unsigned long extoff = 0;
+ int wander = 1, n = 0, loop = 0;
+
+ /*
+ * Read dos partition table, follow extended partitions.
+ * Map the partitions to disklabel entries i-p
+ */
+ while (wander && n < 8 && loop < 8) {
+ loop++;
+ wander = 0;
+ if (part_blkno < extoff)
+ part_blkno = extoff;
+
+ /* read boot record */
+ bp->b_blkno = part_blkno;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ bp->b_cylin = part_blkno / lp->d_secpercyl;
+ (*strat)(bp);
+
+ /* if successful, wander through dos partition table */
+ if (biowait(bp)) {
+ msg = "dos partition I/O error";
+ if (partoffp)
+ *partoffp = -1;
+ return (msg);
+ }
+ bcopy(bp->b_data + DOSPARTOFF, dp,
+ NDOSPART * sizeof(*dp));
+
+ if (ourpart == -1) {
+ /* Search for our MBR partition */
+ for (dp2=dp, i=0;
+ i < NDOSPART && ourpart == -1; i++, dp2++)
+ if (dp2->dp_size &&
+ dp2->dp_typ == DOSPTYP_OPENBSD)
+ ourpart = i;
+ for (dp2=dp, i=0;
+ i < NDOSPART && ourpart == -1; i++, dp2++)
+ if (dp2->dp_size &&
+ dp2->dp_typ == DOSPTYP_FREEBSD)
+ ourpart = i;
+ for (dp2=dp, i=0;
+ i < NDOSPART && ourpart == -1; i++, dp2++)
+ if (dp2->dp_size &&
+ dp2->dp_typ == DOSPTYP_NETBSD)
+ ourpart = i;
+ if (ourpart == -1)
+ goto donot;
+ /*
+ * This is our MBR partition. need sector
+ * address for SCSI/IDE, cylinder for
+ * ESDI/ST506/RLL
+ */
+ dp2 = &dp[ourpart];
+ dospartoff = dp2->dp_start + part_blkno;
+ cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
+
+ /* XXX build a temporary disklabel */
+ lp->d_partitions[0].p_size = dp2->dp_size;
+ lp->d_partitions[0].p_offset = dp2->dp_start +
+ part_blkno;
+ if (lp->d_ntracks == 0)
+ lp->d_ntracks = dp2->dp_ehd + 1;
+ if (lp->d_nsectors == 0)
+ lp->d_nsectors = DPSECT(dp2->dp_esect);
+ if (lp->d_secpercyl == 0)
+ lp->d_secpercyl = lp->d_ntracks *
+ lp->d_nsectors;
+ }
+donot:
+ /*
+ * In case the disklabel read below fails, we want to
+ * provide a fake label in i-p.
+ */
+ for (dp2=dp, i=0; i < NDOSPART && n < 8; i++, dp2++) {
+ struct partition *pp = &lp->d_partitions[8+n];
+
+ if (dp2->dp_typ == DOSPTYP_OPENBSD)
+ continue;
+ if (dp2->dp_size)
+ pp->p_size = dp2->dp_size;
+ if (dp2->dp_start)
+ pp->p_offset =
+ dp2->dp_start + part_blkno;
+
+ switch (dp2->dp_typ) {
+ case DOSPTYP_UNUSED:
+ for (cp = (char *)dp2;
+ cp < (char *)(dp2 + 1); cp++)
+ if (*cp)
+ break;
+ /*
+ * Was it all zeroes? If so, it is
+ * an unused entry that we don't
+ * want to show.
+ */
+ if (cp == (char *)(dp2 + 1))
+ continue;
+ lp->d_partitions[8 + n++].p_fstype =
+ FS_UNUSED;
+ break;
+
+ case DOSPTYP_LINUX:
+ pp->p_fstype = FS_EXT2FS;
+ n++;
+ break;
+
+ case DOSPTYP_FAT12:
+ case DOSPTYP_FAT16S:
+ case DOSPTYP_FAT16B:
+ case DOSPTYP_FAT32:
+ case DOSPTYP_FAT32L:
+ case DOSPTYP_FAT16L:
+ pp->p_fstype = FS_MSDOS;
+ n++;
+ break;
+ case DOSPTYP_EXTEND:
+ part_blkno = dp2->dp_start + extoff;
+ if (!extoff) {
+ extoff = dp2->dp_start;
+ part_blkno = 0;
+ }
+ wander = 1;
+ break;
+ default:
+ pp->p_fstype = FS_OTHER;
+ n++;
+ break;
+ }
+ }
+ }
+ lp->d_bbsize = 8192;
+ lp->d_sbsize = 64*1024; /* XXX ? */
+ lp->d_npartitions = n > 0 ? n + 8 : 3;
+ }
+
+ /* record the OpenBSD partition's placement for the caller */
+ if (partoffp)
+ *partoffp = dospartoff;
+ if (cylp)
+ *cylp = cyl;
+
+ /* next, dig out disk label */
+ msg = readbsdlabel(bp, strat, cyl, dospartoff + I386_LABELSECTOR, -1,
+ LITTLE_ENDIAN, lp, spoofonly);
+ if (msg)
+ return (msg);
+
+ /* obtain bad sector table if requested and present */
+ if (bdp && (lp->d_flags & D_BADSECT)) {
+ /*
+ * get a new buffer and initialize it as callers trust the
+ * buffer given to us, to point at the disklabel sector.
+ */
+ dev = bp->b_dev;
+ bp = geteblk((int)lp->d_secsize);
+ bp->b_dev = dev;
+
+ i = 0;
+ do {
+ /* read a bad sector table */
+ bp->b_flags = B_BUSY | B_READ;
+ bp->b_blkno = lp->d_secperunit - lp->d_nsectors + i;
+ if (lp->d_secsize > DEV_BSIZE)
+ bp->b_blkno *= lp->d_secsize / DEV_BSIZE;
+ else
+ bp->b_blkno /= DEV_BSIZE / lp->d_secsize;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_cylin = lp->d_ncylinders - 1;
+ (*strat)(bp);
+
+ /* if successful, validate, otherwise try another */
+ if (biowait(bp))
+ msg = "bad sector table I/O error";
+ else {
+ db = (struct dkbad *)(bp->b_data);
+#define DKBAD_MAGIC 0x4321
+ if (db->bt_mbz == 0 &&
+ db->bt_flag == DKBAD_MAGIC) {
+ msg = NULL;
+ *bdp = *db;
+ break;
+ } else
+ msg = "bad sector table corrupted";
+ }
+ } while ((bp->b_flags & B_ERROR) && (i += 2) < 10 &&
+ i < lp->d_nsectors);
+
+ /* Give back the bad block buffer. */
+ bp->b_flags |= B_INVAL;
+ brelse(bp);
+ }
+ return (msg);
+}
+#endif
+
+#if defined(DISKLABEL_AMIGA) || defined(DISKLABEL_ALL)
+/*
+ * XXX RDB parsing is missing still.
+ */
+char *
+readamigalabel(bp, strat, lp, osdep, spoofonly)
+ struct buf *bp;
+ void (*strat)(struct buf *);
+ struct disklabel *lp;
+ struct cpu_disklabel *osdep;
+ int spoofonly;
+{
+ char *msg;
+
+ msg = readbsdlabel(bp, strat, 0, AMIGA_LABELSECTOR, AMIGA_LABELOFFSET,
+ BIG_ENDIAN, lp, spoofonly);
+ return (msg);
+}
+#endif
+
+#if defined(DISKLABEL_HPPA) || defined(DISKLABEL_ALL)
+char *
+readliflabel (bp, strat, lp, osdep, partoffp, cylp, spoofonly)
+ struct buf *bp;
+ void (*strat)(struct buf *);
+ struct disklabel *lp;
+ struct cpu_disklabel *osdep;
+ int *partoffp;
+ int *cylp;
+ int spoofonly;
+{
+ int fsoff;
+
+ /* read LIF volume header */
+ bp->b_blkno = btodb(LIF_VOLSTART);
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ bp->b_cylin = btodb(LIF_VOLSTART) / lp->d_secpercyl;
+ (*strat)(bp);
+
+ if (biowait(bp)) {
+ if (partoffp)
+ *partoffp = -1;
+ return "LIF volume header I/O error";
+ }
+
+ bcopy (bp->b_data, &osdep->u._hppa.lifvol, sizeof(struct lifvol));
+ if (osdep->u._hppa.lifvol.vol_id != LIF_VOL_ID) {
+ fsoff = 0;
+ } else {
+ struct lifdir *p;
+ struct buf *dbp;
+ dev_t dev;
+
+ dev = bp->b_dev;
+ dbp = geteblk(LIF_DIRSIZE);
+ dbp->b_dev = dev;
+
+ /* read LIF directory */
+ dbp->b_blkno = lifstodb(osdep->u._hppa.lifvol.vol_addr);
+ dbp->b_bcount = lp->d_secsize;
+ dbp->b_flags = B_BUSY | B_READ;
+ dbp->b_cylin = dbp->b_blkno / lp->d_secpercyl;
+ (*strat)(dbp);
+
+ if (biowait(dbp)) {
+ if (partoffp)
+ *partoffp = -1;
+
+ dbp->b_flags |= B_INVAL;
+ brelse(dbp);
+ return ("LIF directory I/O error");
+ }
+
+ bcopy(dbp->b_data, osdep->u._hppa.lifdir, LIF_DIRSIZE);
+ dbp->b_flags |= B_INVAL;
+ brelse(dbp);
+
+ /* scan for LIF_DIR_FS dir entry */
+ for (fsoff = -1, p = &osdep->u._hppa.lifdir[0];
+ fsoff < 0 && p < &osdep->u._hppa.lifdir[LIF_NUMDIR]; p++) {
+ if (p->dir_type == LIF_DIR_FS ||
+ p->dir_type == LIF_DIR_HPLBL)
+ break;
+ }
+
+ if (p->dir_type == LIF_DIR_FS)
+ fsoff = lifstodb(p->dir_addr);
+ else if (p->dir_type == LIF_DIR_HPLBL) {
+ struct hpux_label *hl;
+ struct partition *pp;
+ u_int8_t fstype;
+ int i;
+
+ dev = bp->b_dev;
+ dbp = geteblk(LIF_DIRSIZE);
+ dbp->b_dev = dev;
+
+ /* read LIF directory */
+ dbp->b_blkno = lifstodb(p->dir_addr);
+ dbp->b_bcount = lp->d_secsize;
+ dbp->b_flags = B_BUSY | B_READ;
+ dbp->b_cylin = dbp->b_blkno / lp->d_secpercyl;
+ (*strat)(dbp);
+
+ if (biowait(dbp)) {
+ if (partoffp)
+ *partoffp = -1;
+
+ dbp->b_flags |= B_INVAL;
+ brelse(dbp);
+ return ("HOUX label I/O error");
+ }
+
+ bcopy(dbp->b_data, &osdep->u._hppa.hplabel,
+ sizeof(osdep->u._hppa.hplabel));
+ dbp->b_flags |= B_INVAL;
+ brelse(dbp);
+
+ hl = &osdep->u._hppa.hplabel;
+ if (hl->hl_magic1 != hl->hl_magic2 ||
+ hl->hl_magic != HPUX_MAGIC ||
+ hl->hl_version != 1) {
+ if (partoffp)
+ *partoffp = -1;
+
+ return "HPUX label magic mismatch";
+ }
+
+ lp->d_bbsize = 8192;
+ lp->d_sbsize = 8192;
+ for (i = 0; i < MAXPARTITIONS; i++) {
+ lp->d_partitions[i].p_size = 0;
+ lp->d_partitions[i].p_offset = 0;
+ lp->d_partitions[i].p_fstype = 0;
+ }
+
+ for (i = 0; i < HPUX_MAXPART; i++) {
+ if (!hl->hl_flags[i])
+ continue;
+
+ if (hl->hl_flags[i] == HPUX_PART_ROOT) {
+ pp = &lp->d_partitions[0];
+ fstype = FS_BSDFFS;
+ } else if (hl->hl_flags[i] == HPUX_PART_SWAP) {
+ pp = &lp->d_partitions[1];
+ fstype = FS_SWAP;
+ } else if (hl->hl_flags[i] == HPUX_PART_BOOT) {
+ pp = &lp->d_partitions[RAW_PART + 1];
+ fstype = FS_BSDFFS;
+ } else
+ continue;
+
+ pp->p_size = hl->hl_parts[i].hlp_length * 2;
+ pp->p_offset = hl->hl_parts[i].hlp_start * 2;
+ pp->p_fstype = fstype;
+ }
+
+ lp->d_partitions[RAW_PART].p_size = lp->d_secperunit;
+ lp->d_partitions[RAW_PART].p_offset = 0;
+ lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
+ lp->d_npartitions = MAXPARTITIONS;
+ lp->d_magic = DISKMAGIC;
+ lp->d_magic2 = DISKMAGIC;
+ lp->d_checksum = 0;
+ lp->d_checksum = dkcksum(lp);
+
+ return (NULL);
+ }
+
+ /* if no suitable lifdir entry found assume zero */
+ if (fsoff < 0) {
+ fsoff = 0;
+ }
+ }
+
+ if (partoffp)
+ *partoffp = fsoff;
+
+ return readbsdlabel(bp, strat, 0, fsoff + HPPA_LABELSECTOR,
+ HPPA_LABELOFFSET, BIG_ENDIAN, lp, spoofonly);
+}
+#endif
+
+/*
+ * Check new disk label for sensibility
+ * before setting it.
+ */
+int
+setdisklabel(olp, nlp, openmask, osdep)
+ struct disklabel *olp, *nlp;
+ u_long openmask;
+ struct cpu_disklabel *osdep;
+{
+ int i;
+ struct partition *opp, *npp;
+
+ /* sanity clause */
+ if (nlp->d_secpercyl == 0 || nlp->d_secsize == 0 ||
+ (nlp->d_secsize % DEV_BSIZE) != 0)
+ return(EINVAL);
+
+ /*
+ * XXX Nice thought, but it doesn't work, if the intention was to
+ * force a reread at the next *readdisklabel call. That does not
+ * happen. There's still some use for it though as you can pseudo-
+ * partitition the disk.
+ *
+ * Special case to allow disklabel to be invalidated.
+ */
+ if (nlp->d_magic == 0xffffffff) {
+ *olp = *nlp;
+ return (0);
+ }
+
+ if (nlp->d_magic != DISKMAGIC || nlp->d_magic2 != DISKMAGIC ||
+ dkcksum(nlp) != 0)
+ return (EINVAL);
+
+ /* XXX missing check if other dos partitions will be overwritten */
+
+ while (openmask != 0) {
+ i = ffs((long)openmask) - 1;
+ openmask &= ~(1 << i);
+ if (nlp->d_npartitions <= i)
+ return (EBUSY);
+ opp = &olp->d_partitions[i];
+ npp = &nlp->d_partitions[i];
+ if (npp->p_offset != opp->p_offset ||
+ npp->p_size < opp->p_size)
+ return (EBUSY);
+ /*
+ * Copy internally-set partition information
+ * if new label doesn't include it. XXX
+ */
+ if (npp->p_fstype == FS_UNUSED && opp->p_fstype != FS_UNUSED) {
+ npp->p_fstype = opp->p_fstype;
+ npp->p_fsize = opp->p_fsize;
+ npp->p_frag = opp->p_frag;
+ npp->p_cpg = opp->p_cpg;
+ }
+ }
+ nlp->d_checksum = 0;
+ nlp->d_checksum = dkcksum(nlp);
+ *olp = *nlp;
+ return (0);
+}
+
+
+/*
+ * Write disk label back to device after modification.
+ */
+int
+writedisklabel(dev, strat, lp, osdep)
+ dev_t dev;
+ void (*strat)(struct buf *);
+ struct disklabel *lp;
+ struct cpu_disklabel *osdep;
+{
+ enum disklabel_tag *tp;
+ char *msg = "no disk label";
+ struct buf *bp;
+ struct disklabel dl;
+#if defined(DISKLABEL_I386) || defined(DISKLABEL_HPPA) || defined(DISKLABEL_ALL)
+ struct cpu_disklabel cdl;
+#endif
+ int labeloffset, error, i, endian, partoff = 0, cyl = 0;
+ u_int64_t csum, *p;
+
+ /* get a buffer and initialize it */
+ bp = geteblk((int)lp->d_secsize);
+ bp->b_dev = dev;
+
+ /*
+ * I once played with the thought of using osdep->label{tag,sector}
+ * as a cache for knowing where (and what) to write. However, now I
+ * think it might be useful to reprobe if someone has written
+ * a newer disklabel of another type with disklabel(8) and -r.
+ */
+ for (tp = probe_order; msg && *tp != -1; tp++) {
+ dl = *lp;
+ switch (*tp) {
+ case DLT_ALPHA:
+#if defined(DISKLABEL_ALPHA) || defined(DISKLABEL_ALL)
+ msg = readbsdlabel(bp, strat, 0, ALPHA_LABELSECTOR,
+ ALPHA_LABELOFFSET, LITTLE_ENDIAN, &dl, 0);
+ labeloffset = ALPHA_LABELOFFSET;
+ endian = LITTLE_ENDIAN;
+#endif
+ break;
+
+ case DLT_I386:
+#if defined(DISKLABEL_I386) || defined(DISKLABEL_ALL)
+ msg = readdoslabel(bp, strat, &dl, &cdl, &partoff,
+ &cyl, 0);
+ labeloffset = I386_LABELOFFSET;
+ endian = LITTLE_ENDIAN;
+#endif
+ break;
+
+ case DLT_AMIGA:
+#if defined(DISKLABEL_AMIGA) || defined(DISKLABEL_ALL)
+ msg = readamigalabel(bp, strat, &dl, &cdl, 0);
+ labeloffset = AMIGA_LABELOFFSET;
+ endian = BIG_ENDIAN;
+#endif
+ break;
+
+ case DLT_HPPA:
+#if defined(DISKLABEL_HPPA) || defined(DISKLABEL_ALL)
+ msg = readliflabel(bp, strat, &dl, &cdl, &partoff,
+ &cyl, 0);
+ labeloffset = HPPA_LABELOFFSET;
+ endian = BIG_ENDIAN;
+#endif
+ break;
+
+ default:
+ panic("unrecognized disklabel tag %d", *tp);
+ }
+ }
+
+ if (msg) {
+ if (partoff == -1)
+ return EIO;
+
+ /* Write it in the regular place with native byte order. */
+ labeloffset = LABELOFFSET;
+ endian = BYTE_ORDER;
+ bp->b_blkno = partoff + LABELSECTOR;
+ bp->b_cylin = cyl;
+ bp->b_bcount = lp->d_secsize;
+ }
+
+ if (endian != BYTE_ORDER) {
+ swapdisklabel(lp);
+ /* recalc checksum */
+ lp->d_checksum = 0;
+ lp->d_checksum = dkcksum(lp);
+ }
+
+ *(struct disklabel *)(bp->b_data + labeloffset) = *lp;
+
+ /* Alpha bootblocks are checksummed. */
+ if (*tp == DLT_ALPHA) {
+ for (csum = i = 0, p = (u_int64_t *)bp->b_data; i < 63; i++)
+ csum += *p++;
+ *p = csum;
+ }
+
+ bp->b_flags = B_BUSY | B_WRITE;
+ (*strat)(bp);
+ error = biowait(bp);
+
+ bp->b_flags |= B_INVAL;
+ brelse(bp);
+ return (error);
+}
+
+/*
+ * Determine the size of the transfer, and make sure it is
+ * within the boundaries of the partition. Adjust transfer
+ * if needed, and signal errors or early completion.
+ */
+int
+bounds_check_with_label(bp, lp, osdep, wlabel)
+ struct buf *bp;
+ struct disklabel *lp;
+ struct cpu_disklabel *osdep;
+ int wlabel;
+{
+#define blockpersec(count, lp) ((count) * (((lp)->d_secsize) / DEV_BSIZE))
+ struct partition *p = lp->d_partitions + DISKPART(bp->b_dev);
+ int labelsector = blockpersec(lp->d_partitions[RAW_PART].p_offset,
+ lp) + osdep->labelsector;
+ int sz = howmany(bp->b_bcount, DEV_BSIZE);
+
+ /* avoid division by zero */
+ if (lp->d_secpercyl == 0) {
+ bp->b_error = EINVAL;
+ goto bad;
+ }
+
+ /* beyond partition? */
+ if (bp->b_blkno + sz > blockpersec(p->p_size, lp)) {
+ sz = blockpersec(p->p_size, lp) - bp->b_blkno;
+ if (sz == 0) {
+ /* If exactly at end of disk, return EOF. */
+ bp->b_resid = bp->b_bcount;
+ goto done;
+ }
+ if (sz < 0) {
+ /* If past end of disk, return EINVAL. */
+ bp->b_error = EINVAL;
+ goto bad;
+ }
+ /* Otherwise, truncate request. */
+ bp->b_bcount = sz << DEV_BSHIFT;
+ }
+
+ /* Overwriting disk label? */
+ if (bp->b_blkno + blockpersec(p->p_offset, lp) <= labelsector &&
+ bp->b_blkno + blockpersec(p->p_offset, lp) + sz > labelsector &&
+ (bp->b_flags & B_READ) == 0 && !wlabel) {
+ bp->b_error = EROFS;
+ goto bad;
+ }
+
+ /* calculate cylinder for disksort to order transfers with */
+ bp->b_cylin = (bp->b_blkno + blockpersec(p->p_offset, lp)) /
+ lp->d_secpercyl;
+ return (1);
+
+bad:
+ bp->b_flags |= B_ERROR;
+done:
+ return (0);
+}
diff --git a/sys/arch/hppa64/hppa64/genassym.cf b/sys/arch/hppa64/hppa64/genassym.cf
new file mode 100644
index 00000000000..45e598e1d19
--- /dev/null
+++ b/sys/arch/hppa64/hppa64/genassym.cf
@@ -0,0 +1,142 @@
+# $OpenBSD: genassym.cf,v 1.1 2005/04/01 10:40:47 mickey Exp $
+
+#
+# Copyright (c) 1982, 1990, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# @(#)genassym.c 8.3 (Berkeley) 1/4/94
+#
+
+include <sys/param.h>
+include <sys/systm.h>
+include <sys/proc.h>
+include <sys/syscall.h>
+include <sys/user.h>
+
+include <machine/cpu.h>
+include <machine/psl.h>
+include <machine/reg.h>
+include <machine/vmparam.h>
+include <machine/frame.h>
+include <machine/pcb.h>
+
+include <uvm/uvm.h>
+
+# `break' entry points
+export HPPA_BREAK_KERNEL
+export HPPA_BREAK_GET_PSW
+export HPPA_BREAK_SET_PSW
+
+# saved state fields
+struct trapframe
+member tf_flags
+member tf_r1
+member tf_rp
+member tf_r3
+member tf_r4
+member tf_r5
+member tf_r6
+member tf_r7
+member tf_r8
+member tf_r9
+member tf_r10
+member tf_r11
+member tf_r12
+member tf_r13
+member tf_r14
+member tf_r15
+member tf_r16
+member tf_r17
+member tf_r18
+member tf_args
+member tf_dp
+member tf_ret0
+member tf_ret1
+member tf_sp
+member tf_r31
+member tf_sr0
+member tf_sr1
+member tf_sr2
+member tf_sr3
+member tf_sr4
+member tf_sr5
+member tf_sr6
+member tf_sr7
+member tf_rctr
+member tf_ccr
+member tf_iioq
+member tf_iisq
+member tf_pidr1
+member tf_pidr2
+member tf_eiem
+member tf_eirr
+member tf_isr
+member tf_ior
+member tf_iir
+member tf_ipsw
+member tf_ci
+member tf_vtop
+member tf_cr27
+member tf_cr30
+member tf_sar
+
+# proc fields and values
+struct proc
+member p_forw
+member p_back
+member p_addr
+member p_priority
+member p_stat
+member p_wchan
+member p_md
+member P_MD_FLAGS p_md.md_flags
+member P_MD_REGS p_md.md_regs
+
+export SRUN
+export SONPROC
+
+struct user
+member u_pcb
+
+struct pcb
+member pcb_fpregs
+member pcb_onfault
+member pcb_uva
+member pcb_ksp
+member pcb_space
+
+struct cpu_info
+member ci_curproc
+
+struct uvm
+member page_idle_zero
+
+# system calls
+export SYSCALLGATE
+export SYS_exit
+export SYS_execve
+export SYS_sigreturn
diff --git a/sys/arch/hppa64/hppa64/in_cksum.c b/sys/arch/hppa64/hppa64/in_cksum.c
new file mode 100644
index 00000000000..4aec07520df
--- /dev/null
+++ b/sys/arch/hppa64/hppa64/in_cksum.c
@@ -0,0 +1,125 @@
+/* $OpenBSD: in_cksum.c,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 2000 Michael Shalayeff
+ * All rights reserved.
+ *
+ * based on a sparc version of Zubin Dittia.
+ * Copyright (c) 1995 Zubin Dittia.
+ *
+ * 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 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 HIS RELATIVES 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 MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <netinet/in.h>
+
+/*
+ * Checksum routine for Internet Protocol family headers.
+ *
+ * This routine is very heavily used in the network
+ * code and should be modified for each CPU to be as fast as possible.
+ *
+ * HPPA version.
+ */
+
+/* TODO optimize */
+
+#define ADD32 asm volatile( "ldw 0x00(%1), %%r19! ldw 0x04(%1), %%r20\n\t" \
+ "add %0, %%r19, %0 ! addc %0, %%r20, %0\n\t" \
+ "ldw 0x08(%1), %%r19! ldw 0x0c(%1), %%r20\n\t" \
+ "addc %0, %%r19, %0 ! addc %0, %%r20, %0\n\t" \
+ "ldw 0x10(%1), %%r19! ldw 0x14(%1), %%r20\n\t" \
+ "addc %0, %%r19, %0 ! addc %0, %%r20, %0\n\t" \
+ "ldw 0x18(%1), %%r19! ldw 0x1c(%1), %%r20\n\t" \
+ "addc %0, %%r19, %0 ! addc %0, %%r20, %0\n\t" \
+ "ldo 0x20(%1), %1 ! addc %0, %%r0 , %0" \
+ : "+r" (sum), "+r" (w) :: "r20", "r19")
+#define ADD16 asm volatile( "ldw 0x00(%1), %%r19! ldw 0x04(%1), %%r20\n\t" \
+ "add %0, %%r19, %0! addc %0, %%r20, %0\n\t" \
+ "ldw 0x08(%1), %%r19! ldw 0x0c(%1), %%r20\n\t" \
+ "addc %0, %%r19, %0! addc %0, %%r20, %0\n\t" \
+ "ldo 0x10(%1), %1 ! addc %0, %%r0 , %0" \
+ : "+r" (sum), "+r" (w) :: "r20", "r19")
+
+#define ADDCARRY {if (sum > 0xffff) sum -= 0xffff;}
+#define REDUCE {sum = (sum & 0xffff) + (sum >> 16); ADDCARRY}
+#define ROL asm volatile ("shd %0, %0, 8, %0" : "+r" (sum))
+#define ADDBYTE {ROL; sum += *w++; bins++; mlen--;}
+#define ADDSHORT {sum += *((u_short *)w)++; mlen -= 2;}
+#define ADDWORD asm volatile( "ldwm 4(%1), %%r19! add %0, %%r19, %0\n\t" \
+ "ldo -4(%2), %2 ! addc %0, 0, %0" \
+ : "+r" (sum), "+r" (w), "+r" (mlen) :: "r19")
+
+int
+in_cksum(m, len)
+ register struct mbuf *m;
+ register int len;
+{
+ register u_int sum = 0;
+ register u_int bins = 0;
+
+ for (; m && len; m = m->m_next) {
+ register int mlen = m->m_len;
+ register u_char *w;
+
+ if (!mlen)
+ continue;
+ if (len < mlen)
+ mlen = len;
+ len -= mlen;
+ w = mtod(m, u_char *);
+
+ if (mlen > 16) {
+ /*
+ * If we are aligned on a doubleword boundary
+ * do 32 bit bundled operations
+ */
+ if ((7 & (u_long)w) != 0) {
+ if ((1 & (u_long)w) != 0)
+ ADDBYTE;
+ if ((2 & (u_long)w) != 0)
+ ADDSHORT;
+ if ((4 & (u_long)w) != 0)
+ ADDWORD;
+ }
+
+ while ((mlen -= 32) >= 0)
+ ADD32;
+
+ mlen += 32;
+ if (mlen >= 16) {
+ ADD16;
+ mlen -= 16;
+ }
+ }
+
+ while (mlen > 0)
+ ADDBYTE;
+ }
+ if (bins & 1)
+ ROL;
+ REDUCE;
+
+ return (0xffff ^ sum);
+}
diff --git a/sys/arch/hppa64/hppa64/locore.S b/sys/arch/hppa64/hppa64/locore.S
new file mode 100644
index 00000000000..8882c934d28
--- /dev/null
+++ b/sys/arch/hppa64/hppa64/locore.S
@@ -0,0 +1,1879 @@
+/* $OpenBSD: locore.S,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+ .level 2.0w
+
+#include <sys/errno.h>
+#include <sys/reboot.h>
+#include <machine/param.h>
+#include <machine/asm.h>
+#include <machine/psl.h>
+#include <machine/trap.h>
+#include <machine/iomod.h>
+#include <machine/pdc.h>
+#include <machine/frame.h>
+#include <machine/reg.h>
+#include <machine/pte.h>
+#include "assym.h"
+
+ .import __gp, data
+ .import pdc, data
+ .import boothowto, data
+ .import bootdev, data
+ .import esym, data
+ .import want_resched, data
+ .import proc0, data
+ .import proc0paddr, data
+
+#define EMRG_STACKSIZE (1*PAGE_SIZE)
+#define FPEMU_STACKSIZE (1*PAGE_SIZE)
+
+ .data
+
+ .export netisr, data
+ .align 16
+netisr
+ .word 0
+ .align 16
+$kpsl
+ .word PSL_W | PSL_Q | PSL_P | PSL_C | PSL_D | PSL_S | PSL_O
+ .export cpl, data
+cpl
+ .word IPL_HIGH
+
+ BSS(pdc_stack, 8) /* temp stack for PDC call */
+ BSS(emrg_stack, 8) /* stack for HPMC/TOC/PWRF */
+ BSS(fpemu_stack, 8) /* stack for FPU emulation */
+
+ .export fpu_csw, data
+ BSS(fpu_csw, 4) /* count fpu context switches */
+ .export fpu_enable, data
+ BSS(fpu_enable, 4) /* bits to set in the %cr10 to enable fpu */
+ .export fpu_curpcb, data
+ BSS(fpu_curpcb, 8) /* pcb of the fpu owner */
+ BSS(fpu_scratch, 16) /* FPU scratch space, enough for a quad */
+
+ .text
+
+/*
+ * $start(pdc, boothowto, bootdev, esym)
+ */
+ .export $start, entry
+$start
+ rsm (PSL_R|PSL_Q|PSL_I|PSL_P|PSL_D), %r0
+ nop ! nop ! nop ! nop
+
+ ldil L%__gp, %dp
+ ldo R%__gp(%dp), %dp
+
+ ldi HPPA_PID_KERNEL, %r1
+ mtctl %r1, %pidr1
+ mtctl %r1, %pidr2
+ mtctl %r0, %pidr3
+ mtctl %r0, %pidr4
+
+ mtsp %r0, %sr0
+ mtsp %r0, %sr1
+ mtsp %r0, %sr2
+ mtsp %r0, %sr3
+ mtsp %r0, %sr4
+ mtsp %r0, %sr5
+ mtsp %r0, %sr6
+ mtsp %r0, %sr7
+
+ ldi -1, %r1
+ mtctl %r0, %eiem
+ mtctl %r1, %eirr
+ mtctl %r0, %cr10 /* ccr */
+
+ ldil L%pdc, %r1
+ std %arg0, R%pdc(%r1)
+ ldil L%boothowto, %r1
+ stw %arg1, R%boothowto(%r1)
+ ldil L%bootdev, %r1
+ stw %arg2, R%bootdev(%r1)
+ ldil L%esym, %r1
+ std %arg3, R%esym(%r1)
+
+ /* align esym */
+ ldo PAGE_MASK(%arg3), %arg3
+ depw %r0, 31, PAGE_SHIFT, %arg3
+
+ .import __kernel_pagedir, data
+ ldil L%__kernel_pagedir, %r1
+ ldo R%__kernel_pagedir(%r1), %r1
+ mtctl %r1, %cr25 /* vtop */
+
+ /* setup kernel initial PIEs */
+ ldo PAGE_SIZE(%r1), %r31
+ extrd,u %r31, 51, 32, %arg0
+ ldo 1(%arg0), %arg1
+ ldo 2(%arg0), %arg2
+ stw %arg0, 0(%r1)
+ stw %arg1, 4(%r1)
+ /* (VM_MIN_KERNEL_ADDRESS & PIE_MASK) >> PIE_SHIFT */
+ ldo 1(%arg2), %arg0
+ stw %arg2, 0x20*4(%r1)
+ stw %arg0, 0xffc(%r1)
+
+ .import kernel_ptes, data
+ ldil L%kernel_ptes, %r1
+ ldo R%kernel_ptes(%r1), %r1
+
+ ldd,ma 8(%r1), %r8
+ ldd,ma 8(%r1), %r9
+ ldd,ma 8(%r1), %r10
+ ldd,ma 8(%r1), %r11
+
+ /* fill eight pages at the same time */
+ copy %arg3, %arg0
+ ldo PAGE_SIZE(%arg0), %arg1
+ extrd,u %arg0, 51, 32, %r1
+ stw,ma %r1, 4(%r31)
+ ldo PAGE_SIZE(%arg1), %arg2
+ extrd,u %arg1, 51, 32, %r1
+ stw,ma %r1, 4(%r31)
+ ldo PAGE_SIZE(%arg2), %arg3
+ extrd,u %arg2, 51, 32, %r1
+ stw,ma %r1, 4(%r31)
+ ldo PAGE_SIZE(%arg3), arg4
+ extrd,u %arg3, 51, 32, %r1
+ stw,ma %r1, 4(%r31)
+ ldo PAGE_SIZE(arg4), arg5
+ extrd,u arg4, 51, 32, %r1
+ stw,ma %r1, 4(%r31)
+ ldo PAGE_SIZE(arg5), arg6
+ extrd,u arg5, 51, 32, %r1
+ stw,ma %r1, 4(%r31)
+ ldo PAGE_SIZE(arg6), arg7
+ extrd,u arg6, 51, 32, %r1
+ stw,ma %r1, 4(%r31)
+ extrd,u arg7, 51, 32, %r1
+ stw,ma %r1, 4(%r31)
+ ldi PAGE_SIZE, %r1
+$start_set_ptes
+ std,ma,bc %r8, 8(%arg0)
+ std,ma,bc %r8, 8(%arg1)
+ std,ma,bc %r9, 8(%arg2)
+ std,ma,bc %r9, 8(%arg3)
+ std,ma,bc %r10, 8(arg4)
+ std,ma,bc %r10, 8(arg5)
+ std,ma,bc %r11, 8(arg6)
+ addib,>= -8, %r1, $start_set_ptes
+ std,ma,bc %r11, 8(arg7)
+
+ ldo -8(arg7), %arg3
+
+ /* assuming size being page-aligned */
+#define STACK_ALLOC(n,s) \
+ ldil L%n, %r1 ! \
+ ldil L%s, %r31 ! \
+ std %arg3, R%n(%r1) ! \
+ add %arg3, %r31, %arg3
+
+ STACK_ALLOC(pdc_stack, PDC_STACKSIZE)
+ STACK_ALLOC(emrg_stack, EMRG_STACKSIZE)
+ STACK_ALLOC(fpemu_stack, FPEMU_STACKSIZE)
+
+ copy %arg3, %arg0
+ ldi PAGE_SIZE+TRAPFRAME_SIZEOF, %r1
+$start_zero_tf
+ std,ma,bc %r0, 8(%arg0)
+ addib,>= -16, %r1, $start_zero_tf
+ std,ma,bc %r0, 8(%arg0)
+
+ /* setup proc0/user0 */
+ ldil L%(USPACE+PAGE_SIZE), %arg0
+ add %arg0, %arg3, %arg0
+ ldil L%proc0paddr, %r1
+ std %arg3, R%proc0paddr(%r1)
+
+ ldo PAGE_SIZE(%arg3), %sp
+ mtctl %arg3, %cr30
+ std %r0, U_PCB+PCB_ONFAULT(%arg3)
+ std %r0, U_PCB+PCB_SPACE(%arg3)
+ std %arg3, U_PCB+PCB_UVA(%arg3)
+
+ ldil L%proc0, %r1
+ ldo R%proc0(%r1), %r1
+ ldo -TRAPFRAME_SIZEOF(%sp), %arg2
+ std %arg3, P_ADDR(%r1)
+ std %arg2, P_MD_REGS(%r1)
+
+ ldil TFF_LAST, %r1
+ std %r1, TF_FLAGS(%arg2)
+ std %arg3, TF_CR30(%arg2)
+
+ ldil L%$kpsl, %r1
+ ldw R%$kpsl(%r1), arg7
+ ldil L%$start_virt, %r31
+ ldo R%$start_virt(%r31), %r31
+ ldil L%$ivaaddr, %r1
+ ldo R%$ivaaddr(%r1), %r1
+ mtctl %r1, %iva
+ mtctl %r0, %pcsq
+ mtctl %r0, %pcsq
+ mtctl %r31, %pcoq
+ ldo 4(%r31), %r31
+ mtctl %r31, %pcoq
+ mtctl arg7, %ipsw
+ rfi
+ nop
+
+$start_virt
+ copy %arg0, %r5
+ copy %sp, %r3
+ std,ma %r0, HPPA_FRAME_SIZE(%sp)
+ .call
+ b,l hppa_init, %rp
+ ldo -16(%sp), ap
+
+$start_callmain
+ .import main, code
+ .call
+ b,l main, %rp
+ ldo -TRAPFRAME_SIZEOF(%arg0), %r5
+ .size $start, .-$start
+
+/* int
+ * pdc_call(func, pdc_flag, ...)
+ * iodcio_t func;
+ * int pdc_flag;
+ */
+ENTRY(pdc_call,160)
+ std %rp, HPPA_FRAME_RP(%sp)
+ std %sp, HPPA_FRAME_PSP(%sp)
+ copy %r3, %r31
+ copy %sp, %ret0
+
+ ldil L%pdc_stack, %r1
+ ldd R%pdc_stack(%r1), %r3
+ copy %r3, %sp
+ std,ma %r31, 32+12*4+12*8(%sp) /* old frame+args+save(64) */
+
+ mfctl %eiem, %r1
+ mtctl %r0, %eiem
+ std %r1, 1*8(%r3)
+
+ copy %arg0, %r31
+ /* copy arguments */
+ copy %arg2, %arg0
+ copy %arg3, %arg1
+ copy arg4, %arg2
+ copy arg5, %arg3
+
+ ldd 0*8(ap), arg4
+ ldd 1*8(ap), arg5
+ stw arg6, -32-(4+1)*4(%sp)
+ stw arg7, -32-(5+1)*4(%sp)
+ stw arg4, -32-(6+1)*4(%sp)
+ stw arg5, -32-(7+1)*4(%sp)
+ ldd 2*8(ap), arg4
+ ldd 3*8(ap), arg5
+ ldd 4*8(ap), arg6
+ ldd 5*8(ap), arg7
+ stw arg4, -32-(8+1)*4(%sp)
+ stw arg5, -32-(9+1)*4(%sp)
+ stw arg6, -32-(10+1)*4(%sp)
+ stw arg7, -32-(11+1)*4(%sp)
+
+ mfctl %cr24, arg4
+ mfctl %cr25, arg5
+ mfctl %cr26, arg6
+ mfctl %cr27, arg7
+ std arg4, 2*8(%r3)
+ std arg5, 3*8(%r3)
+ std arg6, 4*8(%r3)
+ std arg7, 5*8(%r3)
+ mfctl %cr28, arg4
+ mfctl %cr29, arg5
+ mfctl %cr30, arg6
+ mfctl %cr31, arg7
+ std arg4, 6*8(%r3)
+ std arg5, 7*8(%r3)
+ std arg6, 8*8(%r3)
+ std arg7, 9*8(%r3)
+
+ copy %arg0, %ret1
+ std %ret0, 11*8(%r3) /* old %sp */
+ ldi PSL_Q, %arg0
+ break HPPA_BREAK_KERNEL, HPPA_BREAK_SET_PSW
+ copy %ret1, %arg0
+
+ .call
+ blr %r0, %rp
+ bv,n (%r31)
+ nop
+
+ /* load temp control regs */
+ ldd 2*8(%r3), arg4
+ ldd 3*8(%r3), arg5
+ ldd 4*8(%r3), arg6
+ ldd 5*8(%r3), arg7
+ mtctl arg4, %cr24
+ mtctl arg5, %cr25
+ mtctl arg6, %cr26
+ mtctl arg7, %cr27
+ ldd 6*8(%r3), arg4
+ ldd 7*8(%r3), arg5
+ ldd 8*8(%r3), arg6
+ ldd 9*8(%r3), arg7
+ mtctl arg4, %cr28
+ mtctl arg5, %cr29
+ mtctl arg6, %cr30
+ mtctl arg7, %cr31
+
+ ldil L%$kpsl, %r1
+ ldw R%$kpsl(%r1), %arg0
+ copy %ret0, %arg1
+ break HPPA_BREAK_KERNEL, HPPA_BREAK_SET_PSW
+ copy %arg1, %ret0
+
+ ldd 1*8(%r3), arg5 /* %eiem */
+ ldd 11*8(%r3), %sp
+ ldd HPPA_FRAME_RP(%sp), %rp
+ ldd 0(%r3), %r3
+
+ bv %r0(%rp)
+ mtctl arg5, %eiem
+EXIT(pdc_call)
+
+/*
+ * the whole syscall() glue is fit on one page
+ * both enter and return paths
+ */
+/* TODO has to be mapped w/a special perms */
+ .align PAGE_SIZE
+ .export gateway_page, entry
+gateway_page
+ nop
+ gate,n $bsd_syscall,%r0
+ nop
+
+ .align 256
+#ifdef COMPAT_LINUX
+ gate,n $linux_syscall, %r0 /* TODO linux syscall fix */
+ nop
+
+$linux_syscall
+ nop
+#endif
+
+$bsd_syscall
+ mfctl %eiem, %r1
+ mtctl %r0, %eiem
+ mtsp %r0, %sr1
+ mfctl %pidr1, %ret0
+ ldi HPPA_PID_KERNEL, %ret0
+ mtctl %ret0, %pidr1
+
+/* TODO prepare for syscall() */
+
+ .import syscall,code
+ b,l syscall, %rp
+ nop
+
+ mfctl %cr24, %arg1
+ ldd CI_CURPROC(%arg1), %r1
+ ldw P_MD_REGS(%r1), %arg0
+
+$syscall_return
+ /* %arg0 -- trapframe */
+
+ mtctl %r0, %eiem
+
+ ldo 8(%arg0), %r31 /* flags */
+
+ rfi
+ nop
+ .size $bsd_syscall, .-$bsd_syscall
+ .size $syscall_return, .-$syscall_return
+
+gateway_end
+ . = gateway_page + PAGE_SIZE
+ .size $gateway_page, .-$gateway_page
+
+/*
+ * interrupt vector table
+ */
+#define TLABEL(name) $trap$name
+#define TRAP(name,num,pre) \
+ .export TLABEL(name)$num, entry ! \
+ .label TLABEL(name)$num ! \
+ pre ! \
+ .call ! \
+ .import TLABEL(name), code ! \
+ b TLABEL(name) ! \
+ ldi num, %r1 ! \
+ .align 32
+
+#define ITLBPRE \
+ mfctl %pcsq, %r8 ! \
+ mfctl %pcoq, %r9 ! \
+ extrd,u %r8, 63, SID_SHIFT, %r1 ! \
+ depd %r1, 31, SID_SHIFT, %r9 ! \
+ depd %r0, 63, SID_SHIFT, %r8
+
+#define DTLBPRE \
+ mfctl %isr, %r8 ! \
+ mfctl %ior, %r9 ! \
+ extrd,u %r8, 63, SID_SHIFT, %r1 ! \
+ depd %r1, 31, SID_SHIFT, %r9 ! \
+ depd %r0, 63, SID_SHIFT, %r8
+
+#define HPMCPRE nop
+
+#define BRKPRE \
+ mfctl %pcoq, %r8
+
+ .align PAGE_SIZE /* already */
+ .export $ivaaddr, entry
+ .export hpmc_v, entry
+$ivaaddr
+ TRAP(all,T_NONEXIST,) /* 0. invalid interrupt vector */
+hpmc_v
+ TRAP(hpmc,T_HPMC,HPMCPRE) /* 1. high priority machine check */
+ TRAP(pfr,T_POWERFAIL,) /* 2. power failure */
+ TRAP(all,T_RECOVERY,) /* 3. recovery counter trap */
+ TRAP(all,T_INTERRUPT,) /* 4. external interrupt */
+ TRAP(all,T_LPMC,) /* 5. low-priority machine check */
+ TRAP(itlb,T_ITLBMISS,ITLBPRE) /* 6. instruction TLB miss fault */
+ TRAP(all,T_IPROT,) /* 7. instruction protection trap */
+ TRAP(all,T_ILLEGAL,) /* 8. Illegal instruction trap */
+ TRAP(ibrk,T_IBREAK,BRKPRE) /* 9. break instruction trap */
+ TRAP(all,T_PRIV_OP,) /* 10. privileged operation trap */
+ TRAP(all,T_PRIV_REG,) /* 11. privileged register trap */
+ TRAP(all,T_OVERFLOW,) /* 12. overflow trap */
+ TRAP(all,T_CONDITION,) /* 13. conditional trap */
+ TRAP(excpt,T_EXCEPTION,) /* 14. assist exception trap */
+ TRAP(dtlb,T_DTLBMISS,DTLBPRE) /* 15. data TLB miss fault */
+ TRAP(itlbna,T_ITLBMISSNA,DTLBPRE)/* 16. ITLB non-access miss fault */
+ TRAP(dtlbna,T_DTLBMISSNA,DTLBPRE)/* 17. DTLB non-access miss fault */
+ TRAP(all,T_DPROT,) /* 18. data protection trap
+ unalligned data reference trap */
+ TRAP(all,T_DBREAK,) /* 19. data break trap */
+ TRAP(tlbd,T_TLB_DIRTY,DTLBPRE) /* 20. TLB dirty bit trap */
+ TRAP(all,T_PAGEREF,) /* 21. page reference trap */
+ TRAP(emu,T_EMULATION,) /* 22. assist emulation trap */
+ TRAP(all,T_HIGHERPL,) /* 23. higher-privelege transfer trap*/
+ TRAP(all,T_LOWERPL,) /* 24. lower-privilege transfer trap */
+ TRAP(all,T_TAKENBR,) /* 25. taken branch trap */
+ TRAP(all,T_DATACC,) /* 26. data access rights trap */
+ TRAP(all,T_DATAPID,) /* 27. data protection ID trap */
+ TRAP(all,T_DATALIGN,) /* 28. unaligned data ref trap */
+ TRAP(all,29,)
+ TRAP(all,30,)
+ TRAP(all,31,)
+ TRAP(all,32,)
+ TRAP(all,33,)
+ TRAP(all,34,)
+ TRAP(all,35,)
+ TRAP(all,36,)
+ TRAP(all,37,)
+ TRAP(all,38,)
+ TRAP(all,39,)
+ TRAP(all,40,)
+ TRAP(all,41,)
+ TRAP(all,42,)
+ TRAP(all,43,)
+ TRAP(all,44,)
+ TRAP(all,45,)
+ TRAP(all,46,)
+ TRAP(all,47,)
+ TRAP(all,48,)
+ TRAP(all,49,)
+ TRAP(all,50,)
+ TRAP(all,51,)
+ TRAP(all,52,)
+ TRAP(all,53,)
+ TRAP(all,54,)
+ TRAP(all,55,)
+ TRAP(all,56,)
+ TRAP(all,57,)
+ TRAP(all,58,)
+ TRAP(all,59,)
+ TRAP(all,60,)
+ TRAP(all,61,)
+ TRAP(all,62,)
+ TRAP(all,63,)
+ /* 64 */
+
+/*
+ * High Priority Machine Check Interrupt
+ */
+ .export TLABEL(hpmc), entry
+ENTRY(TLABEL(hpmc),0)
+ rfi
+ nop
+
+hpmc_never_dies
+ b hpmc_never_dies
+ nop
+EXIT(TLABEL(hpmc))
+
+/*
+ * transfer of control handler
+ */
+ENTRY(hppa_toc,0)
+ rfi
+ nop
+
+ALTENTRY(hppa_toc_end)
+ .word 0
+EXIT(hppa_toc)
+
+/*
+ * power fail recovery handler
+ */
+ENTRY(TLABEL(pfr),0)
+ rfi
+ nop
+
+ALTENTRY(hppa_pfr_end)
+ .word 0
+EXIT(hppa_pfr)
+
+/*
+ * system breaks
+ */
+ .export TLABEL(ibrk), entry
+ENTRY(TLABEL(ibrk),0)
+ /* If called by a user process then always pass it to trap() */
+ extrd,u,*= %r8, 63, 2, %r0
+ b,n TLABEL(all)
+
+ /* don't accept breaks from data segments */
+ .import etext, code
+ ldil L%etext, %r9
+ ldo R%etext(%r9), %r9
+ cmpb,*>>=,n %r8, %r9, TLABEL(all)
+
+ mfctl %iir, %r8
+ extrd,u,*= %r8, 63, 5, %r0
+ b,n TLABEL(all)
+
+ /* now process all those `break' calls we make */
+ extrd,u %r8, 50, 13, %r9
+ comib,=,n HPPA_BREAK_GET_PSW, %r9, $ibrk_getpsw
+ comib,=,n HPPA_BREAK_SET_PSW, %r9, $ibrk_setpsw
+
+ b TLABEL(all)
+ nop
+
+$ibrk_getpsw
+ b $ibrk_exit
+ mfctl %ipsw, %ret0
+
+$ibrk_setpsw
+ mfctl %ipsw, %ret0
+ b $ibrk_exit
+ mtctl %arg0, %ipsw
+
+ /* insert other fast breaks here */
+ nop ! nop
+
+$ibrk_exit
+ /* skip the break */
+ mtctl %r0, %pcoq
+ mfctl %pcoq, %r9
+ mtctl %r9, %pcoq
+ ldo 4(%r9), %r9
+ mtctl %r9, %pcoq
+
+ rfi,r
+ nop
+EXIT(TLABEL(ibrk))
+
+ .export TLABEL(all), entry
+ENTRY(TLABEL(all),0)
+ /* %r1 still has trap type */
+ mfctl %ipsw, %r9
+ mtctl %r9, %cr31
+
+ mtsp %r0, %sr3
+ ldi HPPA_PID_KERNEL, %r9
+ mtctl %r9, %pidr3
+
+ mfctl %isr, %r8
+ mfctl %ior, %r9
+ extrd,u %r8, 63, SID_SHIFT, %r16
+ depd %r16, 31, SID_SHIFT, %r9
+ depd %r0, 63, SID_SHIFT, %r8
+ mtsp %r8, %sr6
+ mtctl %r9, %cr27
+
+ mfctl %pcsq, %r24
+ mtctl %r0, %pcsq
+ mfctl %pcsq, %r25
+ mtctl %r0, %pcsq
+ mtsp %r24, %sr4
+ mtsp %r25, %sr5
+
+ /* TODO fix pcsq:pcoq split */
+ ldil L%TLABEL(all_virt), %r9
+ ldo R%TLABEL(all_virt)(%r9), %r9
+ mfctl %pcoq, %r24
+ mtctl %r9, %pcoq
+ mfctl %pcoq, %r25
+ ldo 4(%r9), %r9
+ mtctl %r24, %cr28
+ mtctl %r9, %pcoq
+ mtctl %r25, %cr29
+
+ ldil L%$kpsl, %r9
+ ldw R%$kpsl(%r9), %r9
+ mtctl %r9, %ipsw
+
+ mfctl %cr30, %r9
+
+ mfsp %sr0, %r8
+ extrd,u,*<> %r24, 63, 2, %r0 /* still pcoq head */
+ cmpb,*= %r0, %r8, TLABEL(all_kern)
+ copy %sp, %r17
+
+ depdi 1, T_USER_POS, 1, %r1
+ depdi 1, TFF_LAST_POS, 1, %r1
+ ldd U_PCB+PCB_UVA(%r9), %sp
+ ldo PAGE_SIZE-TRAPFRAME_SIZEOF(%sp), %sp
+
+TLABEL(all_kern)
+ ldo 127(%sp), %sp
+ depdi 0, 63, 7, %sp
+
+ ldo TF_SP(%sp), %r8
+ std %r17, 0(%r8)
+ fdc %r0(%r8)
+
+ mfctl %iir, %r16
+ ldo TF_IIR(%sp), %r8
+ std %r16, 0(%r8)
+ fdc %r0(%r8)
+
+ mtctl %r1, %cr26
+ rfi,r
+ nop ! nop ! nop ! nop ! nop ! nop ! nop ! nop
+TLABEL(all_virt)
+
+ ldo 8(%sp), %sp /* space for flags */
+ std,ma %r1, 8(%sr3,%sp)
+ mfctl %cr26, %r1 /* sar */
+ std %r1, -16(%sr3,%sp)
+ std,ma %rp, 8(%sr3,%sp)
+ std,ma %r3, 8(%sr3,%sp)
+ std,ma %r4, 8(%sr3,%sp)
+ std,ma %r5, 8(%sr3,%sp)
+ std,ma %r6, 8(%sr3,%sp)
+ std,ma %r7, 8(%sr3,%sp)
+ std,ma %r8, 8(%sr3,%sp)
+ std,ma %r9, 8(%sr3,%sp)
+ std,ma %r10, 8(%sr3,%sp)
+ std,ma %r11, 8(%sr3,%sp)
+ std,ma %r12, 8(%sr3,%sp)
+ std,ma %r13, 8(%sr3,%sp)
+ std,ma %r14, 8(%sr3,%sp)
+ std,ma %r15, 8(%sr3,%sp)
+ std,ma %r16, 8(%sr3,%sp)
+ std,ma %r17, 8(%sr3,%sp)
+ std,ma %r18, 8(%sr3,%sp)
+ std,ma %r19, 8(%sr3,%sp)
+ std,ma %r20, 8(%sr3,%sp)
+ std,ma %r21, 8(%sr3,%sp)
+ std,ma %r22, 8(%sr3,%sp)
+ std,ma %r23, 8(%sr3,%sp)
+ std,ma %r24, 8(%sr3,%sp)
+ std,ma %r25, 8(%sr3,%sp)
+ std,ma %r26, 8(%sr3,%sp)
+ std,ma %r27, 8(%sr3,%sp)
+ std,ma %r28, 8(%sr3,%sp)
+ std,ma %r29, 8(%sr3,%sp)
+ ldo -30*8(%sp), %arg1
+ ldo 8(%sp), %sp /* %sp */
+ std,ma %r31, 8(%sr3,%sp)
+ copy %r1, %arg0
+
+ mfsp %sr0, %arg2
+ mfsp %sr1, %arg3
+ std,ma %arg2, 8(%sr3,%sp) /* %sr0 */
+ std,ma %arg3, 8(%sr3,%sp) /* %sr1 */
+ std,ma %arg2, 8(%sr3,%sp) /* %sr2 */
+ std,ma %arg2, 8(%sr3,%sp) /* %sr3 */
+ std,ma %arg2, 8(%sr3,%sp) /* %sr4 */
+ std,ma %arg2, 8(%sr3,%sp) /* %sr5 */
+ std,ma %arg2, 8(%sr3,%sp) /* %sr6 */
+ std,ma %arg2, 8(%sr3,%sp) /* %sr7 */
+
+ mfctl %cr0, %arg3
+ mfctl %cr10, %arg2
+ std,ma %arg3, 8(%sr3,%sp) /* rctr */
+ std,ma %arg2, 8(%sr3,%sp) /* ccr */
+
+ mfctl %cr28, %arg2 /* pcoq */
+ mfctl %cr29, %arg3
+ std,ma %arg2, 8(%sr3,%sp)
+ std,ma %arg3, 8(%sr3,%sp)
+
+ mfsp %sr4, %arg2 /* pcsq */
+ mfsp %sr5, %arg3
+ std,ma %arg2, 8(%sr3,%sp)
+ std,ma %arg3, 8(%sr3,%sp)
+
+ mfctl %pidr1, %arg2
+ mfctl %pidr2, %arg3
+ std,ma %arg2, 8(%sr3,%sp) /* pidr1 */
+ std,ma %arg3, 8(%sr3,%sp) /* pidr2 */
+
+ mfctl %pidr3, %r1
+ mtctl %r1, %pidr1
+ mtctl %r0, %pidr3
+
+ mfctl %eiem, %arg2
+ mfctl %eirr, %arg3
+ std,ma %arg2, 8(%sr3,%sp) /* eiem */
+ std,ma %arg3, 8(%sr3,%sp) /* eirr */
+
+ mfctl %cr27, %arg2
+ mfsp %sr6, %arg3
+ std,ma %arg2, 8(%sr3,%sp) /* ior */
+ std,ma %arg3, 8(%sr3,%sp) /* isr */
+
+ ldo 8(%sp), %sp /* iir */
+ mfctl %cr31, %arg3
+ std,ma %arg3, 8(%sr3,%sp) /* ipsw */
+
+ mfctl %cr24, %arg2
+ mfctl %cr25, %arg3
+ std,ma %arg2, 8(%sr3,%sp) /* curcpuinfo */
+ std,ma %arg3, 8(%sr3,%sp) /* vtop */
+
+ mfctl %cr30, %arg2
+ mfctl %cr27, %arg3 /* XXX */
+ std,ma %arg2, 8(%sr3,%sp) /* pa(u) */
+ std,ma %arg3, 8(%sr3,%sp) /* user curthread */
+
+ mfctl %sar, %arg2
+ std,ma %arg2, 8(%sr3,%sp) /* sar */
+
+ mtsp %r0, %sr0
+ mtsp %r0, %sr1
+ mtsp %r0, %sr2
+ mtsp %r0, %sr3
+ mtsp %r0, %sr4
+ mtsp %r0, %sr5
+ mtsp %r0, %sr6
+ mtsp %r0, %sr7
+
+ ldo TRAPFRAME_SIZEOF(%arg1), %sp
+ copy %sp, %r3
+ std,ma %r0, HPPA_FRAME_SIZE(%sp)
+
+ ldil L%__gp, %dp
+ ldo R%__gp(%dp), %dp
+ copy %arg1, %r5
+
+ depd %r0, T_USER_POS+1, T_USER_POS, %arg0
+ .import trap, code
+ b,l trap, %rp
+ copy %arg0, %r4
+
+ /* non-terminal frames return to the same proc */
+ bb,*>=,n %r4, TFF_LAST_POS, $syscall_return
+ copy %r5, %arg0
+
+ /* see if curproc have really changed */
+ mfctl %cr24, %arg1
+ ldd CI_CURPROC(%arg1), %r1
+ sub,*= %r0, %r1, %r0
+ ldd P_MD_REGS(%r1), %r5
+
+ b $syscall_return
+ copy %r5, %arg0
+EXIT(TLABEL(all))
+
+#define PTPULL(bits,lbl) \
+ /* space:offset -- %r8:%r9 */ ! \
+ ldil L%__kernel_pagedir, %r24 ! \
+ or,*= %r8, %r8, %r0 ! \
+ mfctl %cr25, %r24 /* vtop */ ! \
+ ldo PAGE_SIZE(%r24), %r25 ! \
+ extrd,u %r25, 51, 32, %r25 ! \
+ extrd,u,*= %r9, 32, 10, %r17 ! \
+ ldw,s %r17(%r24), %r25 ! \
+ extrd,u %r9, 42, 10, %r17 ! \
+ depd,z,*<> %r25, 51, 32, %r25 ! \
+ b,n lbl ! \
+ ldw,s %r17(%r25), %r25 ! \
+ extrd,u %r9, 51, 9, %r24 ! \
+ depd,z,*<> %r25, 51, 32, %r25 ! \
+ b,n lbl ! \
+ ldd,s %r24(%r25), %r16 ! \
+ or,*<> %r16, %r0, %r17 ! \
+ b,n lbl ! \
+ depdi bits, 2+bits, 1+bits, %r17 ! \
+ shladd,l %r24, 3, %r25, %r25 ! \
+ sub,*= %r16, %r17, %r0 ! \
+ std %r17, 0(%r25) ! \
+ extrd,s %r16, 63, 37, %r16 ! \
+ depd %r8, 63, 48, %r17 ! \
+ depdi 1, 62, 1, %r17
+
+TLABEL(itlb)
+ PTPULL(0, TLABEL(all))
+ iitlbt %r16, %r17
+ rfi,r
+ nop
+
+TLABEL(tlbd)
+ PTPULL(1, TLABEL(all))
+ idtlbt %r16, %r17
+ rfi,r
+ nop
+
+TLABEL(itlbna)
+TLABEL(dtlbna)
+ PTPULL(0, TLABEL(dtlbna_fake))
+ idtlbt %r16, %r17
+ rfi,r
+ nop
+TLABEL(dtlbna_fake)
+ /* parse probei?,[rw] insns, decent to trap() to set regs proper */
+ mfctl %iir, %r16
+ extrd,u %r16, 38, 6, %r24
+ comib,=,n 1, %r24, TLABEL(all)
+ extrd,u %r16, 56, 6, %r24
+ subi,<> 0x23, %r24, %r0
+ b TLABEL(all)
+ subi,<> 0x63, %r24, %r0
+ b TLABEL(all)
+ /* otherwise generate a flush-only tlb entry */
+ depd,z %r8, 62, 47, %r17
+ depdi -13, 11, 7, %r17
+ ldo 2(%r17), %r17 /* 3? */
+ idtlbt %r0, %r17
+ rfi,r
+ nop
+
+TLABEL(dtlb)
+ PTPULL(0, TLABEL(all))
+ idtlbt %r16, %r17
+ rfi,r
+ nop
+
+ .export TLABEL(excpt), entry
+ENTRY(TLABEL(excpt),0)
+ /* assume we never get this one w/o fpu [enabled] */
+ copy %rp, %r1
+ copy %arg0, %r8
+ mfctl %cr30, %r9
+#if (PCB_FPREGS+U_PCB) != 0
+ ldo PCB_FPREGS+U_PCB(%r9), %r9
+#endif
+ .import fpu_save, code
+ .call
+ b,l fpu_save, %rp
+ copy %r9, %arg0
+ copy %r1, %rp
+ copy %r8, %arg0
+ mtctl %r0, %cr10 /* reset ccr: cause a reload after exception */
+ ldil L%fpu_curpcb, %r1
+ std %r0, R%fpu_curpcb(%r1)
+
+ /* now, check for trap */
+ ldw 0(%r9), %r1
+ bb,>=,n %r1, HPPA_FPU_T_POS, excpt_notrap
+ ldw 1*4(%r9), %r1
+ comb,<>,n %r0, %r1, excpt_emulate
+ ldw 2*4(%r9), %r1
+ comb,<>,n %r0, %r1, excpt_emulate
+ ldw 3*4(%r9), %r1
+ comb,<>,n %r0, %r1, excpt_emulate
+ ldw 4*4(%r9), %r1
+ comb,<>,n %r0, %r1, excpt_emulate
+ ldw 5*4(%r9), %r1
+ comb,<>,n %r0, %r1, excpt_emulate
+ ldw 6*4(%r9), %r1
+ comb,<>,n %r0, %r1, excpt_emulate
+ ldw 7*4(%r9), %r1
+
+excpt_emulate
+ bb,*>=,n %r1, 37, excpt_notrap /* HPPA_FPU_UNMPL not set */
+
+#if TODO_emulate
+ ldw 0(%r9), %r16
+ depi 0, HPPA_FPU_T_POS, 1, %r16
+ .import $fpu_emulate, code
+ b $fpu_emulate
+ stw %r16, 0(%r9)
+#endif
+
+excpt_notrap
+ sync
+ b TLABEL(all)
+ ldi T_EXCEPTION, %r1
+EXIT(TLABEL(excpt))
+
+ .export TLABEL(emu), entry
+ENTRY(TLABEL(emu),0)
+ /*
+ * Switch FPU/SFU context
+ *
+ * %isr:%ior - data address
+ * %iir - instruction to emulate
+ * iisq:iioq - address of instruction to emulate
+ *
+ * note: ISR and IOR contain valid data only if the
+ * instruction is a coprocessor load or store.
+ *
+ */
+
+ mfctl %iir, %r8
+ extrd,u %r8, 37, 6, %r9 /* no sfu implementation right now */
+ comib,= 4, %r9, TLABEL(all)
+ ldi T_ILLEGAL, %r1
+
+ /*
+ * pass through for all coprocessors now and
+ * do not check the uid here.
+ * in case that piece does not exist emulate
+ * or the trap will be generted later.
+ */
+
+ /* if we are already enabled and hit again, emulate */
+ mfctl %cr10, %r1 /* ccr */
+ extru,<> %r1, 25, 2, %r0
+ b,n $fpusw_set
+ nop
+
+$fpusw_emu
+ mtctl %r0, %cr10 /* reset ccr: cause a reload after exception */
+ std %r0, R%fpu_curpcb(%r1)
+#if TODO_emulate
+ /* here we emulate the fld/fst */
+ mfctl %iir, %r1
+ extrd,u %r1, 37, 6, %r1
+ comib,= 0xb, %r9, TLABEL(all)
+ ldi T_ILLEGAL, %r1
+
+ mfctl %iir, %r1
+ extrd,u %r1, 37, 6, %r1
+ comib,= 0x9, %r9, TLABEL(all)
+ ldi T_ILLEGAL, %r1
+
+ mfctl %iir, %r1
+ .import $fpu_emulate, code
+ b $fpu_emulate
+ nop
+#else
+ b TLABEL(all)
+ ldi T_ILLEGAL, %r1
+#endif
+$fpusw_set
+ /* enable coprocessor */
+ depdi 3, 37, 2, %r1
+ mtctl %r1, %cr10 /* ccr */
+
+ ldil L%fpu_curpcb, %r16
+ mfctl %cr30, %r9
+ ldd R%fpu_curpcb(%r16), %r16
+
+ comb,=,n %r16, %r0, $fpusw_nosave
+ comb,=,n %r16, %r9, $fpusw_done
+
+ copy %arg0, %r17
+ copy %rp, %r1
+#if (PCB_FPREGS+U_PCB) != 0
+ ldo PCB_FPREGS+U_PCB(%r16), %r16
+#endif
+ .import fpu_save, code
+ .call
+ b,l fpu_save, %rp
+ copy %r16, %arg0
+ copy %r1, %rp
+ copy %r17, %arg0
+
+$fpusw_nosave
+ /* count switches */
+ ldil L%fpu_csw, %r1
+ ldw R%fpu_csw(%r1), %r16
+ ldo 31*8+PCB_FPREGS+U_PCB(%r9), %r17
+ ldo 1(%r16), %r16
+ stw %r16, R%fpu_csw(%r1)
+
+ fldds,ma -8(%r17), %fr31
+ fldds,ma -8(%r17), %fr30
+ fldds,ma -8(%r17), %fr29
+ fldds,ma -8(%r17), %fr28
+ fldds,ma -8(%r17), %fr27
+ fldds,ma -8(%r17), %fr26
+ fldds,ma -8(%r17), %fr25
+ fldds,ma -8(%r17), %fr24
+ fldds,ma -8(%r17), %fr23
+ fldds,ma -8(%r17), %fr22
+ fldds,ma -8(%r17), %fr21
+ fldds,ma -8(%r17), %fr20
+ fldds,ma -8(%r17), %fr19
+ fldds,ma -8(%r17), %fr18
+ fldds,ma -8(%r17), %fr17
+ fldds,ma -8(%r17), %fr16
+ fldds,ma -8(%r17), %fr15
+ fldds,ma -8(%r17), %fr14
+ fldds,ma -8(%r17), %fr13
+ fldds,ma -8(%r17), %fr12
+ fldds,ma -8(%r17), %fr11
+ fldds,ma -8(%r17), %fr10
+ fldds,ma -8(%r17), %fr9
+ fldds,ma -8(%r17), %fr8
+ fldds,ma -8(%r17), %fr7
+ fldds,ma -8(%r17), %fr6
+ fldds,ma -8(%r17), %fr5
+ fldds,ma -8(%r17), %fr4
+ fldds,ma -8(%r17), %fr3
+ fldds,ma -8(%r17), %fr2
+ fldds,ma -8(%r17), %fr1
+ fldds 0(%r17), %fr0 /* fr0 must be restored last */
+
+ ldil L%fpu_curpcb, %r1
+ std %r17, R%fpu_curpcb(%r1)
+
+$fpusw_done
+ rfir
+ nop
+EXIT(TLABEL(emu))
+
+LEAF_ENTRY(fpu_exit)
+ /* enable coprocessor XXX */
+ depi 3, 25, 2, %r1
+ mtctl %r1, %cr10
+
+ ldil L%fpu_scratch, %r25
+ ldo R%fpu_scratch(%r25), %r25
+ fstds %fr0, 0(%r25)
+ sync
+ bv %r0(%rp)
+ mtctl %r0, %cr10
+EXIT(fpu_exit)
+
+LEAF_ENTRY(fpu_save)
+ fstds,ma %fr0 , 8(%arg0)
+ fstds,ma %fr1 , 8(%arg0)
+ fstds,ma %fr2 , 8(%arg0)
+ fstds,ma %fr3 , 8(%arg0)
+ fstds,ma %fr4 , 8(%arg0)
+ fstds,ma %fr5 , 8(%arg0)
+ fstds,ma %fr6 , 8(%arg0)
+ fstds,ma %fr7 , 8(%arg0)
+ fstds,ma %fr8 , 8(%arg0)
+ fstds,ma %fr9 , 8(%arg0)
+ fstds,ma %fr10, 8(%arg0)
+ fstds,ma %fr11, 8(%arg0)
+ fstds,ma %fr12, 8(%arg0)
+ fstds,ma %fr13, 8(%arg0)
+ fstds,ma %fr14, 8(%arg0)
+ fstds,ma %fr15, 8(%arg0)
+ fstds,ma %fr16, 8(%arg0)
+ fstds,ma %fr17, 8(%arg0)
+ fstds,ma %fr18, 8(%arg0)
+ fstds,ma %fr19, 8(%arg0)
+ fstds,ma %fr20, 8(%arg0)
+ fstds,ma %fr21, 8(%arg0)
+ fstds,ma %fr22, 8(%arg0)
+ fstds,ma %fr23, 8(%arg0)
+ fstds,ma %fr24, 8(%arg0)
+ fstds,ma %fr25, 8(%arg0)
+ fstds,ma %fr26, 8(%arg0)
+ fstds,ma %fr27, 8(%arg0)
+ fstds,ma %fr28, 8(%arg0)
+ fstds,ma %fr29, 8(%arg0)
+ fstds,ma %fr30, 8(%arg0)
+ fstds %fr31, 0(%arg0)
+ ldo -24(%arg0), %arg0
+ ldi -32, %r25 /* gotta be free for all callers */
+ fdc,m %r25(%arg0)
+ fdc,m %r25(%arg0)
+ fdc,m %r25(%arg0)
+ fdc,m %r25(%arg0)
+ fdc,m %r25(%arg0)
+ fdc,m %r25(%arg0)
+ fdc,m %r25(%arg0)
+ fdc,m %r25(%arg0)
+ bv %r0(%rp)
+ sync
+EXIT(fpu_save)
+
+/*
+ * void
+ * mtctl(register_t val, int reg)
+ */
+LEAF_ENTRY(mtctl)
+ b,l mtctl_end, %r1
+ extrd,u %arg1, 63, 32, %arg1
+ bv %r0(%rp)
+ mtctl %arg0, %cr0
+ bv %r0(%rp)
+ nop /* mtctl %arg0, %cr1 */
+ bv %r0(%rp)
+ nop /* mtctl %arg0, %cr2 */
+ bv %r0(%rp)
+ nop /* mtctl %arg0, %cr3 */
+ bv %r0(%rp)
+ nop /* mtctl %arg0, %cr4 */
+ bv %r0(%rp)
+ nop /* mtctl %arg0, %cr5 */
+ bv %r0(%rp)
+ nop /* mtctl %arg0, %cr6 */
+ bv %r0(%rp)
+ nop /* mtctl %arg0, %cr7 */
+ bv %r0(%rp)
+ mtctl %arg0, %cr8
+ bv %r0(%rp)
+ mtctl %arg0, %cr9
+ bv %r0(%rp)
+ mtctl %arg0, %cr10
+ bv %r0(%rp)
+ mtctl %arg0, %cr11
+ bv %r0(%rp)
+ mtctl %arg0, %cr12
+ bv %r0(%rp)
+ mtctl %arg0, %cr13
+ bv %r0(%rp)
+ mtctl %arg0, %cr14
+ bv %r0(%rp)
+ mtctl %arg0, %cr15
+ bv %r0(%rp)
+ mtctl %arg0, %cr16
+ bv %r0(%rp)
+ mtctl %arg0, %cr17
+ bv %r0(%rp)
+ mtctl %arg0, %cr18
+ bv %r0(%rp)
+ mtctl %arg0, %cr19
+ bv %r0(%rp)
+ mtctl %arg0, %cr20
+ bv %r0(%rp)
+ mtctl %arg0, %cr21
+ bv %r0(%rp)
+ mtctl %arg0, %cr22
+ bv %r0(%rp)
+ mtctl %arg0, %cr23
+ bv %r0(%rp)
+ mtctl %arg0, %cr24
+ bv %r0(%rp)
+ mtctl %arg0, %cr25
+ bv %r0(%rp)
+ mtctl %arg0, %cr26
+ bv %r0(%rp)
+ mtctl %arg0, %cr27
+ bv %r0(%rp)
+ mtctl %arg0, %cr28
+ bv %r0(%rp)
+ mtctl %arg0, %cr29
+ bv %r0(%rp)
+ mtctl %arg0, %cr30
+ bv %r0(%rp)
+ mtctl %arg0, %cr31
+mtctl_end
+ subi,<< 31, %arg1, %r0
+ bv,n %arg1(%r1)
+ bv %r0(%rp)
+ nop
+EXIT(mtctl)
+
+/*
+ * void
+ * pdtlb(pa_space_t sp, vaddr_t va)
+ */
+LEAF_ENTRY(pdtlb)
+ mfsp %sr1, %arg2
+ mtsp %arg0, %sr1
+ pdtlb %r0(%sr1, %arg1)
+ bv %r0(%rp)
+ mtsp %arg2, %sr1
+EXIT(pdtlb)
+
+/*
+ * void
+ * pitlb(pa_space_t sp, vaddr_t va)
+ */
+LEAF_ENTRY(pitlb)
+ mfsp %sr1, %arg2
+ mtsp %arg0, %sr1
+ pitlb %r0(%sr1, %arg1)
+ bv %r0(%rp)
+ mtsp %arg2, %sr1
+EXIT(pitlb)
+
+/*
+ * register_t
+ * mfctl(int reg)
+ */
+LEAF_ENTRY(mfctl)
+ b,l mfctl_end, %r1
+ extrd,u %arg0, 63, 32, %arg0
+ bv %r0(%rp)
+ mfctl %cr0, %ret0
+ bv %r0(%rp)
+ nop /* mfctl %cr1, %ret0 */
+ bv %r0(%rp)
+ nop /* mfctl %cr2, %ret0 */
+ bv %r0(%rp)
+ nop /* mfctl %cr3, %ret0 */
+ bv %r0(%rp)
+ nop /* mfctl %cr4, %ret0 */
+ bv %r0(%rp)
+ nop /* mfctl %cr5, %ret0 */
+ bv %r0(%rp)
+ nop /* mfctl %cr6, %ret0 */
+ bv %r0(%rp)
+ nop /* mfctl %cr7, %ret0 */
+ bv %r0(%rp)
+ mfctl %cr8, %ret0
+ bv %r0(%rp)
+ mfctl %cr9, %ret0
+ bv %r0(%rp)
+ mfctl %cr10, %ret0
+ bv %r0(%rp)
+ mfctl %cr11, %ret0
+ bv %r0(%rp)
+ mfctl %cr12, %ret0
+ bv %r0(%rp)
+ mfctl %cr13, %ret0
+ bv %r0(%rp)
+ mfctl %cr14, %ret0
+ bv %r0(%rp)
+ mfctl %cr15, %ret0
+ bv %r0(%rp)
+ mfctl %cr16, %ret0
+ bv %r0(%rp)
+ mfctl %cr17, %ret0
+ bv %r0(%rp)
+ mfctl %cr18, %ret0
+ bv %r0(%rp)
+ mfctl %cr19, %ret0
+ bv %r0(%rp)
+ mfctl %cr20, %ret0
+ bv %r0(%rp)
+ mfctl %cr21, %ret0
+ bv %r0(%rp)
+ mfctl %cr22, %ret0
+ bv %r0(%rp)
+ mfctl %cr23, %ret0
+ bv %r0(%rp)
+ mfctl %cr24, %ret0
+ bv %r0(%rp)
+ mfctl %cr25, %ret0
+ bv %r0(%rp)
+ mfctl %cr26, %ret0
+ bv %r0(%rp)
+ mfctl %cr27, %ret0
+ bv %r0(%rp)
+ mfctl %cr28, %ret0
+ bv %r0(%rp)
+ mfctl %cr29, %ret0
+ bv %r30(%rp)
+ mfctl %cr30, %ret0
+ bv %r30(%rp)
+ mfctl %cr31, %ret0
+
+mfctl_end
+ subi,<< 31, %arg0, %r0
+ bv,n %arg0(%r1)
+ bv %r0(%rp)
+ nop
+EXIT(mfctl)
+
+#define CACHELOOP(sp,addr,len,step,insn) \
+ mtsp sp, %sr1 ! \
+ ldi -1, arg7 ! \
+ sh3add step, arg7, %r1 ! \
+ andcm len, %r1, %r1 ! \
+ add addr, %r1, %r1 ! \
+ b __CONCAT(insn,_loop) ! \
+ add addr, len, len ! \
+ .label __CONCAT(insn,_loop8) ! \
+ insn,m step(%sr1, addr) ! \
+ insn,m step(%sr1, addr) ! \
+ insn,m step(%sr1, addr) ! \
+ insn,m step(%sr1, addr) ! \
+ insn,m step(%sr1, addr) ! \
+ insn,m step(%sr1, addr) ! \
+ insn,m step(%sr1, addr) ! \
+ .label __CONCAT(insn,_loop) ! \
+ comb,<< addr, %r1, __CONCAT(insn,_loop8) ! \
+ insn,m step(%sr1, addr) ! \
+ .label __CONCAT(insn,_loop1) ! \
+ comb,<<,n addr, len, __CONCAT(insn,_loop1) ! \
+ insn,m step(%sr1, addr)
+
+
+LEAF_ENTRY(fdcache)
+ ldil L%dcache_stride, %r1
+ ldw R%dcache_stride(%r1), %arg3
+ CACHELOOP(%arg0,%arg1,%arg2,%arg3,fdc)
+ bv %r0(%rp)
+ sync
+EXIT(fdcache)
+
+LEAF_ENTRY(pdcache)
+ ldil L%dcache_stride, %r1
+ ldw R%dcache_stride(%r1), %arg3
+ CACHELOOP(%arg0,%arg1,%arg2,%arg3,pdc)
+ bv %r0(%rp)
+ sync
+EXIT(pdcache)
+
+LEAF_ENTRY(ficache)
+ ldil L%icache_stride, %r1
+ ldw R%icache_stride(%r1), %arg3
+ CACHELOOP(%arg0,%arg1,%arg2,%arg3,fic)
+ bv %r0(%rp)
+ sync
+EXIT(ficache)
+
+LEAF_ENTRY(copy_on_fault)
+ mtsp %r0, %sr1
+ mtsp %r0, %sr2
+ std %r1, PCB_ONFAULT+U_PCB(%rp)
+ ldd HPPA_FRAME_RP(%sp), %rp
+ ldo -HPPA_FRAME_SIZE(%sp), %sp
+ bv %r0(%rp)
+ ldi EFAULT, %ret0
+EXIT(copy_on_fault)
+
+LEAF_ENTRY(sync_caches)
+ sync
+ syncdma
+ sync
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ bv %r0(%rp)
+ nop
+EXIT(sync_caches)
+
+/*
+ * int spstrcpy (pa_space_t ssp, const void *src, pa_space_t dsp, void *dst,
+ * size_t size, size_t *rsize)
+ * do a space to space strncpy, return actual copy size in the rsize;
+ */
+LEAF_ENTRY(spstrcpy)
+ stw %rp, HPPA_FRAME_RP(%sp)
+ ldo HPPA_FRAME_SIZE(%sp), %sp
+ add arg4, %arg1, arg4
+ /* setup fault handler */
+ mfctl %cr24, %arg1
+ ldd CI_CURPROC(%arg1), %r1
+ ldil L%copy_on_fault, arg7
+ ldd P_ADDR(arg6), %rp
+ ldo R%copy_on_fault(arg7), arg7
+ ldd PCB_ONFAULT+U_PCB(%rp), %r1
+ std arg7, PCB_ONFAULT+U_PCB(%rp)
+
+ mtsp %arg0, %sr1
+ mtsp %arg2, %sr2
+ copy %arg1, %arg0
+
+$spstrcpy_loop
+ ldbs,ma 1(%sr1, %arg1), arg7
+ comb,= arg4, %arg1, $spstrcpy_exit
+ stbs,ma arg7, 1(%sr2, %arg3)
+ comb,<>,n %r0, arg7, $spstrcpy_loop
+ nop
+
+$spstrcpy_exit
+ ldo -HPPA_FRAME_SIZE(%sp), %sp
+ mtsp %r0, %sr1
+ mtsp %r0, %sr2
+ std %r1, PCB_ONFAULT+U_PCB(%rp)
+ sub %arg1, %arg0, %arg1
+ ldd HPPA_FRAME_RP(%sp), %rp
+ sub,= %r0, arg5, %r0
+ stw %arg1, 0(arg5)
+ bv 0(%rp)
+ copy %r0, %ret0
+EXIT(spstrcpy)
+
+LEAF_ENTRY(setjmp)
+ std,ma %rp, 8(%arg0)
+ std,ma %sp, 8(%arg0)
+ std,ma %r3, 8(%arg0)
+ std,ma %r4, 8(%arg0)
+ std,ma %r5, 8(%arg0)
+ std,ma %r6, 8(%arg0)
+ std,ma %r7, 8(%arg0)
+ std,ma %r8, 8(%arg0)
+ std,ma %r9, 8(%arg0)
+ std,ma %r10, 8(%arg0)
+ std,ma %r11, 8(%arg0)
+ std,ma %r12, 8(%arg0)
+ std,ma %r13, 8(%arg0)
+ std,ma %r14, 8(%arg0)
+ std,ma %r15, 8(%arg0)
+ std,ma %r16, 8(%arg0)
+ std,ma %r17, 8(%arg0)
+ std,ma %r18, 8(%arg0)
+ std,ma %r19, 8(%arg0)
+ std,ma %r27, 8(%arg0)
+
+ bv %r0(%rp)
+ copy %r0, %ret0
+EXIT(setjmp)
+
+LEAF_ENTRY(longjmp)
+ ldd,ma 8(%arg0), %rp
+ ldd,ma 8(%arg0), %sp
+ ldd,ma 8(%arg0), %r3
+ ldd,ma 8(%arg0), %r4
+ ldd,ma 8(%arg0), %r5
+ ldd,ma 8(%arg0), %r6
+ ldd,ma 8(%arg0), %r7
+ ldd,ma 8(%arg0), %r8
+ ldd,ma 8(%arg0), %r9
+ ldd,ma 8(%arg0), %r10
+ ldd,ma 8(%arg0), %r11
+ ldd,ma 8(%arg0), %r12
+ ldd,ma 8(%arg0), %r13
+ ldd,ma 8(%arg0), %r14
+ ldd,ma 8(%arg0), %r15
+ ldd,ma 8(%arg0), %r16
+ ldd,ma 8(%arg0), %r17
+ ldd,ma 8(%arg0), %r18
+ ldd,ma 8(%arg0), %r19
+ ldd,ma 8(%arg0), %r27
+
+ bv %r0(%rp)
+ copy %arg1, %ret0
+EXIT(longjmp)
+
+ .import whichqs, data
+ .import qs, data
+/*
+ * setrunqueue(struct proc *p);
+ * Insert a process on the appropriate queue. Should be called at splclock().
+ */
+ .align 32
+ENTRY(setrunqueue,0)
+#ifdef DIAGNOSTIC
+ ldd P_BACK(%arg0), %r1
+ comb,<>,n %r0, %r1, Lsetrunqueue_panic
+ ldd P_WCHAN(%arg0), %r1
+ comb,<>,n %r0, %r1, Lsetrunqueue_panic
+ ldb P_STAT(%arg0), %r1
+ comib,=,n SRUN, %r1, Lsetrunqueue_ok
+Lsetrunqueue_panic
+ copy %arg0, %arg1
+ ldil L%Lsrqpstr, %arg0
+ .call
+ b,l panic, %rp
+ ldo R%Lsrqpstr(%arg0), %arg0
+Lsrqpstr
+ .asciz "setrunqueue(%p)"
+ .align 8
+Lsetrunqueue_ok
+#endif
+
+ ldb P_PRIORITY(%arg0), %r1
+ ldil L%qs, arg7
+ shd %r0, %r1, 2, %r1
+ ldo R%qs(arg7), arg7
+ sh3add %r1, arg7, arg7
+ ldil L%whichqs, %arg3
+ ldd P_BACK(arg7), arg6
+ std arg7, P_FORW(%arg0)
+ std %arg0, P_BACK(arg7)
+ ldw R%whichqs(%arg3), arg5
+ std %arg0, P_FORW(arg6)
+ mtctl %r1, %sar
+ std arg6, P_BACK(%arg0)
+ vdepi 1, 1, arg5
+ bv 0(%rp)
+ stw arg5, R%whichqs(%arg3)
+EXIT(setrunqueue)
+
+/*
+ * remrunqueue(struct proc *p);
+ * Remove a process from its queue. Should be called at splclock().
+ */
+ .align 32
+ENTRY(remrunqueue,0)
+ ldb P_PRIORITY(%arg0), %r1
+ shd %r0, %r1, 2, %r1
+ ldil L%whichqs, arg5
+ mtsar %r1
+ ldw R%whichqs(arg5), arg6
+
+#ifdef DIAGNOSTIC
+ bvb,<,n arg6, remrunqueue_ok
+
+Lremrunqueue_panic
+ copy %arg0, %arg1
+ ldil L%Lrrqpstr, %arg0
+ .call
+ b,l panic, %rp
+ ldo R%Lrrqpstr(%arg0), %arg0
+
+Lrrqpstr
+ .asciz "remrunqueue(%p), bit=%x"
+ .align 8
+remrunqueue_ok
+#endif
+ ldd P_BACK(%arg0), arg7
+ std %r0, P_BACK(%arg0)
+ ldd P_FORW(%arg0), %arg0
+ std %arg0, P_FORW(arg7)
+ vdepi 0, 1, arg6
+ sub,*<> arg7, %arg0, %r0
+ stw arg6, R%whichqs(arg5)
+ bv 0(%rp)
+ std arg7, P_BACK(%arg0)
+EXIT(remrunqueue)
+
+/*
+ * cpu_switch()
+ * find the highest priority process and resume it.
+ */
+ .align 32
+ENTRY(cpu_switch,128)
+ ldil L%cpl, %r1
+ ldw R%cpl(%r1), %ret0
+ copy %r3, %r1
+ std %rp, HPPA_FRAME_RP(%sp)
+ copy %sp, %r3
+ stwm %r1, HPPA_FRAME_SIZE+20*8(%sp)
+ ldo -(HPPA_FRAME_SIZE)(%sp), ap
+ stw %ret0, 2*8(ap) /* cpl */
+
+ /*
+ * Clear curproc so that we don't accumulate system time while idle.
+ */
+ mfctl %cr24, %r1
+ ldd CI_CURPROC(%r1), %arg2
+ b switch_search
+ std %r0, CI_CURPROC(%r1)
+ /* remain on the old (curproc)'s stack until we have a better choice */
+
+cpu_idle
+ .call
+ b,l spllower, %rp
+ copy %r0, %arg0
+ .import uvm, data
+ ldil L%uvm, %r1
+ ldo R%uvm(%r1), %r1
+ ldw PAGE_IDLE_ZERO(%r1), %r1
+ sub,<> %r0, %r1, %r0
+ b,n cpu_loop
+
+ .call
+ b,l uvm_pageidlezero, %rp
+ std %arg2, 8(%r3)
+
+ ldw 2*8(ap), %ret0 /* cpl */
+ ldd 8(%r3), %arg2
+
+cpu_loop
+ ldil L%cpl, %arg0
+ stw %ret0, R%cpl(%arg0)
+
+switch_search
+ /*
+ * t1: &whichqs
+ * arg2: old curproc
+ *
+ */
+ ldil L%whichqs, %r1
+ ldw R%whichqs(%r1), %arg2
+ comb,=,n %r0, %arg2, cpu_idle
+ copy %r0, %arg0
+
+ ldi 0, %arg3
+getbit
+ mtsar %arg3
+ bvb,>=,n %arg2, getbit
+ ldo 1(%arg3), %arg3
+
+ ldil L%qs, %arg2
+ ldo R%qs(%arg2), %arg2
+ depd %arg3, 62, 63, %arg3
+ shladd,l %arg3, 3, %arg2, %arg2
+
+ ldd P_FORW(%arg2), %arg1
+#ifdef DIAGNOSTIC
+ comb,<> %arg2, %arg1, link_ok
+ nop
+switch_error
+ copy %arg3, %arg1
+ copy %arg2, %arg2
+ ldil L%Lcspstr, %arg0
+ .call
+ b,l panic, %rp
+ ldo R%Lcspstr(%arg0), %arg0
+Lcspstr
+ .asciz "cpu_switch: bit=%x, q/p=%p"
+ .align 8
+link_ok
+#endif
+ ldil L%want_resched, %r1
+ stw %r0, R%want_resched(%r1)
+
+ ldd P_FORW(%arg1), %arg0
+ std %arg0, P_FORW(%arg2)
+ std %arg2, P_BACK(%arg0)
+ std %r0, P_BACK(%arg1)
+
+ ldil L%whichqs, %r1
+ vdepi 0, 1, %arg3
+ sub,<> %arg2, %arg0, %r0
+ stw %arg3, R%whichqs(%r1)
+
+ /* don't need &whichqs (t1) starting here */
+#ifdef DIAGNOSTIC
+ ldd P_WCHAN(%arg1), %arg3
+ comb,<>,n %r0, %arg3, switch_error
+ copy %arg1, %t2
+ ldb P_STAT(%arg1), %arg3
+ comib,<>,n SRUN, %arg3, switch_error
+ copy %arg1, %arg2
+ /*
+ * Either we must be switching to the same process, or
+ * the new process' kernel stack must be reasonable.
+ */
+ comb,=,n %arg1, %arg2, kstack_ok
+ ldd P_ADDR(%arg1), %arg0
+ ldd U_PCB+PCB_KSP(%arg0), %arg3
+ ldo NBPG(%arg0), %arg0
+ comb,>>,n %arg0, %arg3, switch_error
+ copy %arg1, %arg2
+ sub %arg3, %arg0, %arg3
+ ldil L%USPACE, %arg0
+ ldo R%USPACE(%arg0), %arg0
+ comb,<<=,n %arg0, %arg3, switch_error
+ copy %arg1, %arg2
+kstack_ok
+#endif
+ ldi SONPROC, %r1
+ stb %r1, P_STAT(%arg1)
+ /* Skip context switch if same process. */
+ comb,=,n %arg1, %arg2, switch_return
+
+ /* If old process exited, don't bother. */
+ comb,=,n %r0, %arg2, switch_exited
+
+ /*
+ * 2. save old proc context
+ *
+ * arg2: old proc
+ */
+ ldd P_ADDR(%arg2), %r1
+ /* save callee-save registers */
+ std %r4, 1*8(%r3)
+ std %sp, U_PCB+PCB_KSP(%r1)
+ std %r5, 2*8(%r3)
+ std %r6, 3*8(%r3)
+ std %r7, 4*8(%r3)
+ std %r8, 5*8(%r3)
+ std %r9, 6*8(%r3)
+ std %r10, 7*8(%r3)
+ std %r11, 8*8(%r3)
+ std %r12, 9*8(%r3)
+ std %r13, 10*8(%r3)
+ std %r14, 11*8(%r3)
+ std %r15, 12*8(%r3)
+ std %r16, 13*8(%r3)
+ std %r17, 14*8(%r3)
+ std %r18, 15*8(%r3)
+ fdc %r0(%r1)
+ std %r0, 1*8(ap) /* say no trampoline */
+ sync
+
+ /* don't need old curproc (arg2) starting from here */
+switch_exited
+ /*
+ * 3. restore new proc context
+ *
+ * arg1: new proc
+ */
+ ldd P_ADDR(%arg1), %arg3
+ ldd P_MD_REGS(%arg1), %r1
+ ldd U_PCB+PCB_KSP(%arg3), %sp
+ mtctl %r0, %cr10 /* ccr */
+ ldd TF_CR30(%r1), %arg2
+ ldd TF_PIDR2(%r1), %arg3
+ mtctl %arg2, %cr30
+ mtctl %arg3, %pidr2
+ ldo -(HPPA_FRAME_SIZE+20*8)(%sp), %r3
+ ldo -(HPPA_FRAME_SIZE)(%sp), ap
+ ldd 0*8(ap), %arg0
+ ldd 1*8(ap), %arg3 /* in case we're on trampoline */
+ sub,*= %r0, %arg3, %r0
+ b,n switch_gonnajump
+ ldd 1*8(%r3), %r4
+ ldd 2*8(%r3), %r5
+ ldd 3*8(%r3), %r6
+ ldd 4*8(%r3), %r7
+ ldd 5*8(%r3), %r8
+ ldd 6*8(%r3), %r9
+ ldd 7*8(%r3), %r10
+ ldd 8*8(%r3), %r11
+ ldd 9*8(%r3), %r12
+ ldd 10*8(%r3), %r13
+ ldd 11*8(%r3), %r14
+ ldd 12*8(%r3), %r15
+ ldd 13*8(%r3), %r16
+ ldd 14*8(%r3), %r17
+ ldd 15*8(%r3), %r18
+switch_gonnajump
+ ldw 2*8(ap), %ret0 /* cpl */
+ ldil L%cpl, %r1
+ stw %ret0, R%cpl(%r1)
+ sync
+
+switch_return
+ mfctl %cr24, %r1
+ std %arg1, CI_CURPROC(%r1)
+ ldd HPPA_FRAME_RP(%r3), %rp
+ bv 0(%rp)
+ ldd,mb -(HPPA_FRAME_SIZE+20*8)(%sp), %r3
+EXIT(cpu_switch)
+
+ENTRY(switch_trampoline,0)
+ .call
+ blr %r0, %rp
+ bv,n %r0(%arg3)
+ nop
+ mfctl %cr24, %arg1
+ ldd CI_CURPROC(%arg1), %r1
+ b $syscall_return
+ ldd P_MD_REGS(%r1), %arg0
+EXIT(switch_trampoline)
+
+/*
+ * Signal "trampoline" code. Invoked from RTE setup by sendsig().
+ */
+ENTRY(sigcode,0)
+ bb,>=,n %arg3, 30, sigcode_call
+ dep %r0, 31, 2, %arg3
+ ldd 4(%arg3), %r19
+ ldd 0(%arg3), %arg3
+sigcode_call
+ .call
+ ble 0(%sr0, %arg3)
+ copy %r31, %rp
+
+ ldil L%SYSCALLGATE, %r1
+ copy %r4, %arg0
+ .call
+ ble 4(%sr7, %r1)
+ ldi SYS_sigreturn, %r1
+
+ ldil L%SYSCALLGATE, %r1
+ copy %ret0, %arg0
+ .call
+ ble 4(%sr7, %r1)
+ ldi SYS_exit, %r1
+
+ .align 256
+/* TODO syscall entry */
+
+ALTENTRY(esigcode)
+EXIT(sigcode)
+
+/*
+ * struct cpu_info *curcpu(void);
+ */
+LEAF_ENTRY(curcpu)
+ bv %r0(%rp)
+ mfctl %cr24, %ret0
+EXIT(curcpu)
+
+/*
+ * int splraise(int newcpl);
+ */
+LEAF_ENTRY(splraise)
+ bv %r0(%rp)
+ nop
+
+ extrd,u %arg0, 63, 32, %arg0
+#ifdef DEBUG
+ cmpib,<=,n NIPL, %arg0, splraise_ok
+ copy %arg0, %arg1
+ ldil L%splraise_fmt, %arg0
+ b,l panic, %rp
+ ldo R%splraise_fmt(%arg0), %arg0
+ bv %r0(%rp)
+ ldi IPL_HIGH, %ret0
+splraise_fmt
+ .asciz "splraise(%d)"
+ .align 8
+splraise_ok
+#endif
+ sync
+ mfctl %eiem, %arg2
+ mtctl %r0, %eiem
+ ldil L%cpl, %r1
+ ldw R%cpl(%r1), %ret0
+ ldil L%imask, %arg3
+ ldo R%imask(%arg3), %arg3
+ sub,<= %arg0, %ret0, %r0
+ ldd,s %arg0(%arg3), %arg2
+ sub,<= %arg0, %ret0, %r0
+ stw %arg0, R%cpl(%r1)
+ sync
+ bv %r0(%rp)
+ mtctl %arg2, %eiem
+EXIT(splraise)
+
+/*
+ * int spllower(int newcpl);
+ */
+LEAF_ENTRY(spllower)
+ bv %r0(%rp)
+ nop
+
+ extrd,u %arg0, 63, 32, %arg0
+#ifdef DEBUG
+ cmpib,<=,n NIPL, %arg0, spllower_ok
+ copy %arg0, %arg1
+ ldil L%spllower_fmt, %arg0
+ b,l panic, %rp
+ ldo R%spllower_fmt(%arg0), %arg0
+ bv %r0(%rp)
+ ldi IPL_HIGH, %ret0
+spllower_fmt
+ .asciz "spllower(%d)"
+ .align 8
+spllower_ok
+#endif
+ sync
+ mfctl %eiem, %arg2
+ mtctl %r0, %eiem
+ ldil L%cpl, %r1
+ ldw R%cpl(%r1), %ret0
+ ldil L%imask, %arg3
+ ldo R%imask(%arg3), %arg3
+ sub,>= %arg0, %ret0, %r0
+ ldd,s %arg0(%arg3), %arg2
+ sub,>= %arg0, %ret0, %r0
+ stw %arg0, R%cpl(%r1)
+ sync
+ bv %r0(%rp)
+ mtctl %arg2, %eiem
+EXIT(spllower)
+
+ .end
diff --git a/sys/arch/hppa64/hppa64/machdep.c b/sys/arch/hppa64/hppa64/machdep.c
new file mode 100644
index 00000000000..4f47ca92e49
--- /dev/null
+++ b/sys/arch/hppa64/hppa64/machdep.c
@@ -0,0 +1,1200 @@
+/* $OpenBSD: machdep.c,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/signalvar.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/buf.h>
+#include <sys/reboot.h>
+#include <sys/device.h>
+#include <sys/conf.h>
+#include <sys/file.h>
+#include <sys/timeout.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/msgbuf.h>
+#include <sys/ioctl.h>
+#include <sys/tty.h>
+#include <sys/user.h>
+#include <sys/exec.h>
+#include <sys/sysctl.h>
+#include <sys/core.h>
+#include <sys/kcore.h>
+#include <sys/extent.h>
+#ifdef SYSVMSG
+#include <sys/msg.h>
+#endif
+
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
+
+#include <uvm/uvm.h>
+#include <uvm/uvm_page.h>
+
+#include <dev/cons.h>
+#include <dev/clock_subr.h>
+
+#include <machine/pdc.h>
+#include <machine/iomod.h>
+#include <machine/psl.h>
+#include <machine/reg.h>
+#include <machine/autoconf.h>
+#include <machine/kcore.h>
+
+#ifdef COMPAT_HPUX
+#include <compat/hpux/hpux.h>
+#endif
+
+#ifdef DDB
+#include <machine/db_machdep.h>
+#include <ddb/db_access.h>
+#include <ddb/db_sym.h>
+#include <ddb/db_extern.h>
+#endif
+
+#include <hppa/dev/cpudevs.h>
+
+/*
+ * Patchable buffer cache parameters
+ */
+#ifdef NBUF
+int nbuf = NBUF;
+#else
+int nbuf = 0;
+#endif
+
+#ifndef BUFCACHEPERCENT
+#define BUFCACHEPERCENT 10
+#endif /* BUFCACHEPERCENT */
+
+#ifdef BUFPAGES
+int bufpages = BUFPAGES;
+#else
+int bufpages = 0;
+#endif
+int bufcachepercent = BUFCACHEPERCENT;
+
+/*
+ * Different kinds of flags used throughout the kernel.
+ */
+int cold = 1; /* unset when engine is up to go */
+extern int msgbufmapped; /* set when safe to use msgbuf */
+
+/*
+ * cache configuration, for most machines is the same
+ * numbers, so it makes sense to do defines w/ numbers depending
+ * on configured cpu types in the kernel
+ */
+int icache_stride, icache_line_mask;
+int dcache_stride, dcache_line_mask;
+
+/*
+ * things to not kill
+ */
+volatile u_int8_t *machine_ledaddr;
+int machine_ledword, machine_leds;
+struct cpu_info cpu0_info;
+
+/*
+ * CPU params (should be the same for all cpus in the system)
+ */
+struct pdc_cache pdc_cache PDC_ALIGNMENT;
+struct pdc_model pdc_model PDC_ALIGNMENT;
+
+ /* w/ a little deviation should be the same for all installed cpus */
+u_int cpu_ticksnum, cpu_ticksdenom;
+
+ /* exported info */
+char machine[] = MACHINE_ARCH;
+char cpu_model[128];
+int cpu_hvers;
+enum hppa_cpu_type cpu_type;
+const char *cpu_typename;
+u_int fpu_version;
+#ifdef COMPAT_HPUX
+int cpu_model_hpux; /* contains HPUX_SYSCONF_CPU* kind of value */
+#endif
+
+dev_t bootdev;
+int physmem, resvmem, resvphysmem, esym;
+paddr_t avail_end;
+
+/*
+ * Things for MI glue to stick on.
+ */
+struct user *proc0paddr;
+long mem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(32) / sizeof(long)];
+struct extent *hppa_ex;
+
+struct vm_map *exec_map = NULL;
+struct vm_map *phys_map = NULL;
+/* Virtual page frame for /dev/mem (see mem.c) */
+vaddr_t vmmap;
+
+void delay_init(void);
+static __inline void fall(int, int, int, int, int);
+void dumpsys(void);
+void hpmc_dump(void);
+void cpuid(void);
+
+/*
+ * wide used hardware params
+ */
+struct pdc_hwtlb pdc_hwtlb PDC_ALIGNMENT;
+struct pdc_coproc pdc_coproc PDC_ALIGNMENT;
+struct pdc_coherence pdc_coherence PDC_ALIGNMENT;
+struct pdc_spidb pdc_spidbits PDC_ALIGNMENT;
+struct pdc_model pdc_model PDC_ALIGNMENT;
+
+#ifdef DEBUG
+int sigdebug = 0;
+pid_t sigpid = 0;
+#define SDB_FOLLOW 0x01
+#endif
+
+int
+hppa_cpuspeed(int *mhz)
+{
+ *mhz = PAGE0->mem_10msec / 10000;
+
+ return (0);
+}
+
+void
+hppa_init(start)
+ paddr_t start;
+{
+ extern int kernel_text;
+ int error;
+
+ mtctl((long)&cpu0_info, 24);
+
+ pdc_init(); /* init PDC iface, so we can call em easy */
+
+ delay_init(); /* calculate cpu clock ratio */
+
+ cpuid();
+
+ /* cache parameters */
+ if ((error = pdc_call((iodcio_t)pdc, 0, PDC_CACHE, PDC_CACHE_DFLT,
+ &pdc_cache)) < 0) {
+#ifdef DEBUG
+ printf("WARNING: PDC_CACHE error %d\n", error);
+#endif
+ }
+
+ dcache_line_mask = pdc_cache.dc_conf.cc_line * 16 - 1;
+ dcache_stride = pdc_cache.dc_stride;
+ icache_line_mask = pdc_cache.ic_conf.cc_line * 16 - 1;
+ icache_stride = pdc_cache.ic_stride;
+
+ /* cache coherence params (pbably available for 8k only) */
+ error = pdc_call((iodcio_t)pdc, 0, PDC_CACHE, PDC_CACHE_SETCS,
+ &pdc_coherence, 1, 1, 1, 1);
+#ifdef DEBUG
+ printf ("PDC_CACHE_SETCS: %d, %d, %d, %d (%d)\n",
+ pdc_coherence.ia_cst, pdc_coherence.da_cst,
+ pdc_coherence.ita_cst, pdc_coherence.dta_cst, error);
+#endif
+ error = pdc_call((iodcio_t)pdc, 0, PDC_CACHE, PDC_CACHE_GETSPIDB,
+ &pdc_spidbits, 0, 0, 0, 0);
+ printf("SPID bits: 0x%x, error = %d\n", pdc_spidbits.spidbits, error);
+
+#if 0
+TODO hpmc/toc/pfr
+ /* setup hpmc handler */
+ {
+ extern u_int hpmc_v[]; /* from locore.s */
+ register u_int *p = hpmc_v;
+
+ if (pdc_call((iodcio_t)pdc, 0, PDC_INSTR, PDC_INSTR_DFLT, p))
+ *p = 0x08000240;
+
+ p[6] = (u_int)&hpmc_dump;
+ p[7] = 32;
+ p[5] = -(p[0] + p[1] + p[2] + p[3] + p[4] + p[6] + p[7]);
+ }
+
+ {
+ extern u_int hppa_toc[], hppa_toc_end[];
+ register u_int cksum, *p;
+
+ for (cksum = 0, p = hppa_toc; p < hppa_toc_end; p++)
+ cksum += *p;
+
+ *p = cksum;
+ PAGE0->ivec_toc = (u_int)&hppa_toc[0];
+ PAGE0->ivec_toclen = (hppa_toc_end - hppa_toc + 1) * 4;
+ }
+
+ {
+ extern u_int hppa_pfr[], hppa_pfr_end[];
+ register u_int cksum, *p;
+
+ for (cksum = 0, p = hppa_pfr; p < hppa_pfr_end; p++)
+ cksum += *p;
+
+ *p = cksum;
+ PAGE0->ivec_mempf = (u_int)&hppa_pfr[0];
+ PAGE0->ivec_mempflen = (hppa_pfr_end - hppa_pfr + 1) * 4;
+ }
+#endif
+ avail_end = trunc_page(PAGE0->imm_max_mem);
+ if (avail_end > 0x4000000)
+ avail_end = 0x4000000;
+ physmem = btoc(avail_end);
+ resvmem = btoc(((vaddr_t)&kernel_text));
+
+ /* we hope this won't fail */
+ hppa_ex = extent_create("mem", 0, HPPA_PHYSMAP, M_DEVBUF,
+ (caddr_t)mem_ex_storage, sizeof(mem_ex_storage),
+ EX_NOCOALESCE|EX_NOWAIT);
+ if (extent_alloc_region(hppa_ex, 0, (vaddr_t)PAGE0->imm_max_mem,
+ EX_NOWAIT))
+ panic("cannot reserve main memory");
+
+#ifdef SYSVMSG
+{
+ vaddr_t v;
+
+ v = hppa_round_page(start);
+#define valloc(name, type, num) (name) = (type *)v; v = (vaddr_t)((name)+(num))
+ valloc(msgpool, char, msginfo.msgmax);
+ valloc(msgmaps, struct msgmap, msginfo.msgseg);
+ valloc(msghdrs, struct msg, msginfo.msgtql);
+ valloc(msqids, struct msqid_ds, msginfo.msgmni);
+#undef valloc
+ v = hppa_round_page(v);
+ bzero ((void *)start, (v - start));
+ start = v;
+}
+#endif
+ /* sets resvphysmem */
+ pmap_bootstrap(start);
+
+ /* buffer cache parameters */
+ if (bufpages == 0)
+ bufpages = physmem / 100 *
+ (physmem <= 0x1000? 5 : bufcachepercent);
+
+ if (nbuf == 0)
+ nbuf = bufpages < 16? 16 : bufpages;
+
+ /* Restrict to at most 50% filled kvm */
+ if (nbuf * MAXBSIZE >
+ (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) / 2)
+ nbuf = (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) /
+ MAXBSIZE / 2;
+
+ /* More buffer pages than fits into the buffers is senseless. */
+ if (bufpages > nbuf * MAXBSIZE / PAGE_SIZE)
+ bufpages = nbuf * MAXBSIZE / PAGE_SIZE;
+
+ if (!(buf = (struct buf *)pmap_steal_memory(round_page(nbuf *
+ sizeof(struct buf)), NULL, NULL)))
+ panic("cpu_startup: no space for bufs");
+ bzero(buf, nbuf * sizeof(struct buf));
+
+ /* space has been reserved in pmap_bootstrap() */
+ msgbufp = (struct msgbuf *)(ptoa(physmem) - round_page(MSGBUFSIZE));
+ initmsgbuf((caddr_t)msgbufp, round_page(MSGBUFSIZE));
+ msgbufmapped = 1;
+
+ /* they say PDC_COPROC might turn fault light on */
+ pdc_call((iodcio_t)pdc, 0, PDC_CHASSIS, PDC_CHASSIS_DISP,
+ PDC_OSTAT(PDC_OSTAT_RUN) | 0xCEC0);
+
+ cpu_cpuspeed = &hppa_cpuspeed;
+
+#ifdef DDB
+ ddb_init();
+ if (boothowto & RB_KDB)
+ Debugger();
+#endif
+ ptlball();
+ ficacheall();
+ fdcacheall();
+printf("out\n");
+}
+
+void
+cpuid()
+{
+ extern u_int fpu_enable;
+ struct pdc_cpuid pdc_cpuid PDC_ALIGNMENT;
+ int error;
+
+ /* identify system type */
+ if ((error = pdc_call((iodcio_t)pdc, 0, PDC_MODEL, PDC_MODEL_INFO,
+ &pdc_model)) < 0) {
+#ifdef DEBUG
+ printf("WARNING: PDC_MODEL error %d\n", error);
+#endif
+ pdc_model.hvers = 0;
+ }
+
+ bzero(&pdc_cpuid, sizeof(pdc_cpuid));
+ if (pdc_call((iodcio_t)pdc, 0, PDC_MODEL, PDC_MODEL_CPUID,
+ &pdc_cpuid, 0, 0, 0, 0) >= 0) {
+
+ /* patch for old 8200 */
+ if (pdc_cpuid.version == HPPA_CPU_PCXU &&
+ pdc_cpuid.revision > 0x0d)
+ pdc_cpuid.version = HPPA_CPU_PCXUP;
+
+ cpu_type = pdc_cpuid.version;
+ }
+
+ /* locate coprocessors and SFUs */
+ bzero(&pdc_coproc, sizeof(pdc_coproc));
+ if ((error = pdc_call((iodcio_t)pdc, 0, PDC_COPROC, PDC_COPROC_DFLT,
+ &pdc_coproc, 0, 0, 0, 0)) < 0)
+ printf("WARNING: PDC_COPROC error %d\n", error);
+ else {
+ printf("pdc_coproc: 0x%x, 0x%x; model %x rev %x\n",
+ pdc_coproc.ccr_enable, pdc_coproc.ccr_present,
+ pdc_coproc.fpu_model, pdc_coproc.fpu_revision);
+ fpu_enable = pdc_coproc.ccr_enable & 0xc0;
+
+ /* a kludge to detect PCXW */
+ if (pdc_coproc.fpu_model == HPPA_FPU_PCXW)
+ cpu_type = HPPA_CPU_PCXW;
+ }
+
+ if (!cpu_type)
+ printf("WARNING: UNKNOWN CPU TYPE; GOOD LUCK\n");
+ cpu_typename = hppa_mod_info(HPPA_TYPE_CPU, cpu_type);
+
+ if (pdc_model.arch_rev != 8)
+ panic("CANNOT RUN 64BIT KERNEL on 32BIT CPU");
+
+ {
+ const char *p;
+ char buf[32];
+
+ cpu_hvers = pdc_model.hvers >> 4;
+ if (!cpu_hvers) {
+ p = "(UNKNOWN)";
+ } else {
+ p = hppa_mod_info(HPPA_TYPE_BOARD, cpu_hvers);
+ if (!p) {
+ snprintf(buf, sizeof buf, "(UNKNOWN 0x%x)",
+ cpu_hvers);
+ p = buf;
+ }
+ }
+
+ snprintf(cpu_model, sizeof cpu_model,
+ "HP 9000/%s PA-RISC 2.0", p);
+ }
+#ifdef DEBUG
+ printf("%s\n", cpu_model);
+#endif
+}
+
+void
+cpu_startup(void)
+{
+ vaddr_t minaddr, maxaddr;
+ vsize_t size;
+ int i, base, residual;
+
+ /*
+ * psychodelic kingdom come
+ * ... run, run, run
+ * psychodelic kings and queens
+ * join me in this one love dream
+ */
+ printf("%s%s\n", version, cpu_model);
+ printf("real mem = %u (%u reserved for PROM, %u used by OpenBSD)\n",
+ ctob(physmem), ctob(resvmem), ctob(resvphysmem - resvmem));
+
+printf("here2\n");
+ size = MAXBSIZE * nbuf;
+ if (uvm_map(kernel_map, &minaddr, round_page(size),
+ NULL, UVM_UNKNOWN_OFFSET, 0, UVM_MAPFLAG(UVM_PROT_NONE,
+ UVM_PROT_NONE, UVM_INH_NONE, UVM_ADV_NORMAL, 0)))
+ panic("cpu_startup: cannot allocate VM for buffers");
+ buffers = (caddr_t)minaddr;
+ base = bufpages / nbuf;
+ residual = bufpages % nbuf;
+ for (i = 0; i < nbuf; i++) {
+ vaddr_t curbuf;
+ int cbpgs, pd;
+
+{ extern int pmapdebug; pd = pmapdebug; pmapdebug = 0; }
+ /*
+ * First <residual> buffers get (base+1) physical pages
+ * allocated for them. The rest get (base) physical pages.
+ *
+ * The rest of each buffer occupies virtual space,
+ * but has no physical memory allocated for it.
+ */
+ curbuf = (vaddr_t) buffers + (i * MAXBSIZE);
+
+ for (cbpgs = base + (i < residual? 1 : 0); cbpgs--; ) {
+ struct vm_page *pg;
+
+ if ((pg = uvm_pagealloc(NULL, 0, NULL, 0)) == NULL)
+ panic("cpu_startup: not enough memory for "
+ "buffer cache");
+ pmap_kenter_pa(curbuf, VM_PAGE_TO_PHYS(pg),
+ UVM_PROT_RW);
+ curbuf += PAGE_SIZE;
+ }
+{ extern int pmapdebug; pmapdebug = pd; }
+ }
+
+printf("here3\n");
+ /*
+ * Allocate a submap for exec arguments. This map effectively
+ * limits the number of processes exec'ing at any time.
+ */
+ exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
+ 16*NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
+
+printf("here4\n");
+ /*
+ * Allocate a submap for physio
+ */
+ phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
+ VM_PHYS_SIZE, 0, FALSE, NULL);
+
+printf("here5\n");
+ printf("avail mem = %lu\n", ptoa(uvmexp.free));
+ printf("using %u buffers containing %u bytes of memory\n",
+ nbuf, (unsigned)bufpages * PAGE_SIZE);
+
+ /*
+ * Set up buffers, so they can be used to read disk labels.
+ */
+ bufinit();
+ vmmap = uvm_km_valloc_wait(kernel_map, NBPG);
+
+printf("here6\n");
+ /*
+ * Configure the system.
+ */
+ if (boothowto & RB_CONFIG) {
+#ifdef BOOT_CONFIG
+ user_config();
+#else
+ printf("kernel does not support -c; continuing..\n");
+#endif
+ }
+printf("here7\n");
+}
+
+/*
+ * initialize the system time from the time of day clock
+ */
+void
+inittodr(t)
+ time_t t;
+{
+ struct pdc_tod tod PDC_ALIGNMENT;
+ int error, tbad = 0;
+
+ if (t < 12*SECYR) {
+ printf ("WARNING: preposterous time in file system");
+ t = 6*SECYR + 186*SECDAY + SECDAY/2;
+ tbad = 1;
+ }
+
+ if ((error = pdc_call((iodcio_t)pdc,
+ 1, PDC_TOD, PDC_TOD_READ, &tod, 0, 0, 0, 0, 0)))
+ printf("clock: failed to fetch (%d)\n", error);
+
+ time.tv_sec = tod.sec;
+ time.tv_usec = tod.usec;
+
+ if (!tbad) {
+ u_long dt;
+
+ dt = (time.tv_sec < t)? t - time.tv_sec : time.tv_sec - t;
+
+ if (dt < 2 * SECDAY)
+ return;
+ printf("WARNING: clock %s %ld days",
+ time.tv_sec < t? "lost" : "gained", dt / SECDAY);
+ }
+
+ printf (" -- CHECK AND RESET THE DATE!\n");
+}
+
+/*
+ * reset the time of day clock to the value in time
+ */
+void
+resettodr()
+{
+ int error;
+
+ if ((error = pdc_call((iodcio_t)pdc, 1, PDC_TOD, PDC_TOD_WRITE,
+ time.tv_sec, time.tv_usec)))
+ printf("clock: failed to save (%d)\n", error);
+}
+
+/*
+ * compute cpu clock ratio such as:
+ * cpu_ticksnum / cpu_ticksdenom = t + delta
+ * delta -> 0
+ */
+void
+delay_init(void)
+{
+ u_long num, denom, delta, mdelta;
+
+ mdelta = ULONG_MAX;
+ for (denom = 1; denom < 1000; denom++) {
+ num = (PAGE0->mem_10msec * denom) / 10000;
+ delta = num * 10000 / denom - PAGE0->mem_10msec;
+ if (!delta) {
+ cpu_ticksdenom = denom;
+ cpu_ticksnum = num;
+ break;
+ } else if (delta < mdelta) {
+ cpu_ticksdenom = denom;
+ cpu_ticksnum = num;
+ mdelta = delta;
+ }
+ }
+printf("nom=%lu denom=%lu\n", cpu_ticksnum, cpu_ticksdenom);
+}
+
+void
+delay(us)
+ u_int us;
+{
+ u_long start, end, n;
+
+ start = mfctl(CR_ITMR);
+ while (us) {
+ n = min(1000, us);
+ end = start + n * cpu_ticksnum / cpu_ticksdenom;
+
+ /* N.B. Interval Timer may wrap around */
+ if (end < start)
+ do
+ start = mfctl(CR_ITMR);
+ while (start > end);
+
+ do
+ start = mfctl(CR_ITMR);
+ while (start < end);
+
+ us -= n;
+ }
+}
+
+static __inline void
+fall(c_base, c_count, c_loop, c_stride, data)
+ int c_base, c_count, c_loop, c_stride, data;
+{
+ int loop;
+
+ for (; c_count--; c_base += c_stride)
+ for (loop = c_loop; loop--; )
+ if (data)
+ __asm __volatile("fdce 0(%%sr0,%0)"
+ :: "r" (c_base));
+ else
+ __asm __volatile("fice 0(%%sr0,%0)"
+ :: "r" (c_base));
+}
+
+void
+ficacheall(void)
+{
+ /*
+ * Flush the instruction, then data cache.
+ */
+ fall(pdc_cache.ic_base, pdc_cache.ic_count, pdc_cache.ic_loop,
+ pdc_cache.ic_stride, 0);
+ sync_caches();
+}
+
+void
+fdcacheall(void)
+{
+ fall(pdc_cache.dc_base, pdc_cache.dc_count, pdc_cache.dc_loop,
+ pdc_cache.dc_stride, 1);
+ sync_caches();
+}
+
+void
+ptlball(void)
+{
+ register pa_space_t sp;
+ register int i, j, k;
+
+ /* instruction TLB */
+ sp = pdc_cache.it_sp_base;
+ for (i = 0; i < pdc_cache.it_sp_count; i++) {
+ register vaddr_t off = pdc_cache.it_off_base;
+ for (j = 0; j < pdc_cache.it_off_count; j++) {
+ for (k = 0; k < pdc_cache.it_loop; k++)
+ pitlb(sp, off);
+ off += pdc_cache.it_off_stride;
+ }
+ sp += pdc_cache.it_sp_stride;
+ }
+
+ /* data TLB */
+ sp = pdc_cache.dt_sp_base;
+ for (i = 0; i < pdc_cache.dt_sp_count; i++) {
+ register vaddr_t off = pdc_cache.dt_off_base;
+ for (j = 0; j < pdc_cache.dt_off_count; j++) {
+ for (k = 0; k < pdc_cache.dt_loop; k++)
+ pdtlb(sp, off);
+ off += pdc_cache.dt_off_stride;
+ }
+ sp += pdc_cache.dt_sp_stride;
+ }
+}
+
+void
+boot(howto)
+ int howto;
+{
+ /* If system is cold, just halt. */
+ if (cold) {
+ /* (Unless the user explicitly asked for reboot.) */
+ if ((howto & RB_USERREQ) == 0)
+ howto |= RB_HALT;
+ } else {
+
+ boothowto = howto | (boothowto & RB_HALT);
+
+ if (!(howto & RB_NOSYNC)) {
+ vfs_shutdown();
+ /*
+ * If we've been adjusting the clock, the todr
+ * will be out of synch; adjust it now unless
+ * the system was sitting in ddb.
+ */
+ if ((howto & RB_TIMEBAD) == 0)
+ resettodr();
+ else
+ printf("WARNING: not updating battery clock\n");
+ }
+
+ /* XXX probably save howto into stable storage */
+
+ splhigh();
+
+ if (howto & RB_DUMP)
+ dumpsys();
+
+ doshutdownhooks();
+ }
+
+ /* in case we came on powerfail interrupt */
+ if (cold_hook)
+ (*cold_hook)(HPPA_COLD_COLD);
+
+ if (howto & RB_HALT) {
+ if (howto & RB_POWERDOWN && cold_hook) {
+ printf("Powering off...");
+ DELAY(2000000);
+ (*cold_hook)(HPPA_COLD_OFF);
+ DELAY(1000000);
+ }
+
+ printf("System halted!\n");
+ DELAY(2000000);
+ __asm __volatile("stwas %0, 0(%1)"
+ :: "r" (CMD_STOP), "r" (HPPA_LBCAST + iomod_command));
+ } else {
+ printf("rebooting...");
+ DELAY(2000000);
+ __asm __volatile(".export hppa_reset, entry\n\t"
+ ".label hppa_reset");
+ __asm __volatile("stwas %0, 0(%1)"
+ :: "r" (CMD_RESET), "r" (HPPA_LBCAST + iomod_command));
+ }
+
+ for(;;); /* loop while bus reset is comming up */
+ /* NOTREACHED */
+}
+
+u_long dumpmag = 0x8fca0101; /* magic number */
+int dumpsize = 0; /* pages */
+long dumplo = 0; /* blocks */
+
+/*
+ * cpu_dumpsize: calculate size of machine-dependent kernel core dump headers.
+ */
+int
+cpu_dumpsize(void)
+{
+ int size;
+
+ size = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t));
+ if (roundup(size, dbtob(1)) != dbtob(1))
+ return -1;
+
+ return 1;
+}
+
+/*
+ * Called from HPMC handler in locore
+ */
+void
+hpmc_dump(void)
+{
+ printf("HPMC\n");
+
+ cold = 0;
+ boot(RB_NOSYNC);
+}
+
+int
+cpu_dump(void)
+{
+ long buf[dbtob(1) / sizeof (long)];
+ kcore_seg_t *segp;
+ cpu_kcore_hdr_t *cpuhdrp;
+
+ segp = (kcore_seg_t *)buf;
+ cpuhdrp = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(*segp)) / sizeof (long)];
+
+ /*
+ * Generate a segment header.
+ */
+ CORE_SETMAGIC(*segp, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
+ segp->c_size = dbtob(1) - ALIGN(sizeof(*segp));
+
+ /*
+ * Add the machine-dependent header info
+ */
+ /* nothing for now */
+
+ return (bdevsw[major(dumpdev)].d_dump)
+ (dumpdev, dumplo, (caddr_t)buf, dbtob(1));
+}
+
+/*
+ * Dump the kernel's image to the swap partition.
+ */
+#define BYTES_PER_DUMP NBPG
+
+void
+dumpsys(void)
+{
+ int psize, bytes, i, n;
+ register caddr_t maddr;
+ register daddr_t blkno;
+ register int (*dump)(dev_t, daddr_t, caddr_t, size_t);
+ register int error;
+
+ /* Save registers
+ savectx(&dumppcb); */
+
+ if (dumpsize == 0)
+ dumpconf();
+ if (dumplo <= 0) {
+ printf("\ndump to dev %x not possible\n", dumpdev);
+ return;
+ }
+ printf("\ndumping to dev %x, offset %ld\n", dumpdev, dumplo);
+
+ psize = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
+ printf("dump ");
+ if (psize == -1) {
+ printf("area unavailable\n");
+ return;
+ }
+
+ if (!(error = cpu_dump())) {
+
+ bytes = ctob(physmem);
+ maddr = NULL;
+ blkno = dumplo + cpu_dumpsize();
+ dump = bdevsw[major(dumpdev)].d_dump;
+ for (i = 0; i < bytes; i += n) {
+
+ /* Print out how many MBs we are to go. */
+ n = bytes - i;
+ if (n && (n % (1024*1024)) == 0)
+ printf("%d ", n / (1024 * 1024));
+
+ /* Limit size for next transfer. */
+ if (n > BYTES_PER_DUMP)
+ n = BYTES_PER_DUMP;
+
+ if ((error = (*dump)(dumpdev, blkno, maddr, n)))
+ break;
+ maddr += n;
+ blkno += btodb(n);
+ }
+ }
+
+ switch (error) {
+ case ENXIO: printf("device bad\n"); break;
+ case EFAULT: printf("device not ready\n"); break;
+ case EINVAL: printf("area improper\n"); break;
+ case EIO: printf("i/o error\n"); break;
+ case EINTR: printf("aborted from console\n"); break;
+ case 0: printf("succeeded\n"); break;
+ default: printf("error %d\n", error); break;
+ }
+}
+
+/* bcopy(), error on fault */
+int
+kcopy(from, to, size)
+ const void *from;
+ void *to;
+ size_t size;
+{
+ return spcopy(HPPA_SID_KERNEL, from, HPPA_SID_KERNEL, to, size);
+}
+
+int
+copystr(src, dst, size, lenp)
+ const void *src;
+ void *dst;
+ size_t size;
+ size_t *lenp;
+{
+ return spstrcpy(HPPA_SID_KERNEL, src, HPPA_SID_KERNEL, dst, size, lenp);
+}
+
+int
+copyinstr(src, dst, size, lenp)
+ const void *src;
+ void *dst;
+ size_t size;
+ size_t *lenp;
+{
+ return spstrcpy(curproc->p_addr->u_pcb.pcb_space, src,
+ HPPA_SID_KERNEL, dst, size, lenp);
+}
+
+
+int
+copyoutstr(src, dst, size, lenp)
+ const void *src;
+ void *dst;
+ size_t size;
+ size_t *lenp;
+{
+ return spstrcpy(HPPA_SID_KERNEL, src,
+ curproc->p_addr->u_pcb.pcb_space, dst, size, lenp);
+}
+
+
+int
+copyin(src, dst, size)
+ const void *src;
+ void *dst;
+ size_t size;
+{
+ return spcopy(curproc->p_addr->u_pcb.pcb_space, src,
+ HPPA_SID_KERNEL, dst, size);
+}
+
+int
+copyout(src, dst, size)
+ const void *src;
+ void *dst;
+ size_t size;
+{
+ return spcopy(HPPA_SID_KERNEL, src,
+ curproc->p_addr->u_pcb.pcb_space, dst, size);
+}
+
+/*
+ * Set registers on exec.
+ */
+void
+setregs(p, pack, stack, retval)
+ struct proc *p;
+ struct exec_package *pack;
+ u_long stack;
+ register_t *retval;
+{
+ extern paddr_t fpu_curpcb; /* from locore.S */
+ struct trapframe *tf = p->p_md.md_regs;
+ struct pcb *pcb = &p->p_addr->u_pcb;
+ register_t zero;
+
+ tf->tf_flags = TFF_SYS|TFF_LAST;
+ tf->tf_iioq[1] = 4 +
+ (tf->tf_iioq[0] = pack->ep_entry | HPPA_PC_PRIV_USER);
+ tf->tf_rp = 0;
+ tf->tf_args[0] = (u_long)PS_STRINGS;
+ tf->tf_args[1] = tf->tf_args[2] = 0; /* XXX dynload stuff */
+
+ /* setup terminal stack frame */
+ stack = (stack + 0x1f) & ~0x1f;
+ tf->tf_r3 = stack;
+ tf->tf_sp = stack += HPPA_FRAME_SIZE;
+ tf->tf_ret1 = stack - 16; /* ap */
+ zero = 0;
+ copyout(&zero, (caddr_t)(stack - HPPA_FRAME_SIZE), sizeof(register_t));
+ copyout(&zero, (caddr_t)(stack + HPPA_FRAME_RP), sizeof(register_t));
+
+ /* reset any of the pending FPU exceptions */
+ if (tf->tf_cr30 == fpu_curpcb) {
+ fpu_exit();
+ fpu_curpcb = 0;
+ }
+ pcb->pcb_fpregs[0] = ((u_int64_t)HPPA_FPU_INIT) << 32;
+ pcb->pcb_fpregs[1] = 0;
+ pcb->pcb_fpregs[2] = 0;
+ pcb->pcb_fpregs[3] = 0;
+ fdcache(HPPA_SID_KERNEL, (vaddr_t)pcb->pcb_fpregs, 8 * 4);
+
+ retval[1] = 0;
+}
+
+/*
+ * Send an interrupt to process.
+ */
+void
+sendsig(catcher, sig, mask, code, type, val)
+ sig_t catcher;
+ int sig, mask;
+ u_long code;
+ int type;
+ union sigval val;
+{
+ extern paddr_t fpu_curpcb; /* from locore.S */
+ extern u_int fpu_enable;
+ struct proc *p = curproc;
+ struct trapframe *tf = p->p_md.md_regs;
+ struct sigacts *psp = p->p_sigacts;
+ struct sigcontext ksc;
+ siginfo_t ksi;
+ register_t scp, sip, zero;
+ int sss;
+
+ /* TODO sendsig */
+
+#ifdef DEBUG
+ if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid))
+ printf("sendsig: %s[%d] sig %d catcher %p\n",
+ p->p_comm, p->p_pid, sig, catcher);
+#endif
+
+ /* flush the FPU ctx first */
+ if (tf->tf_cr30 == fpu_curpcb) {
+ mtctl(fpu_enable, CR_CCR);
+ fpu_save(fpu_curpcb);
+ /* fpu_curpcb = 0; only needed if fpregs are preset */
+ mtctl(0, CR_CCR);
+ }
+
+ ksc.sc_onstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
+
+ /*
+ * Allocate space for the signal handler context.
+ */
+ if ((psp->ps_flags & SAS_ALTSTACK) && !ksc.sc_onstack &&
+ (psp->ps_sigonstack & sigmask(sig))) {
+ scp = (register_t)psp->ps_sigstk.ss_sp;
+ psp->ps_sigstk.ss_flags |= SS_ONSTACK;
+ } else
+ scp = (tf->tf_sp + 63) & ~63;
+
+ sss = (sizeof(ksc) + 63) & ~63;
+ sip = 0;
+ if (psp->ps_siginfo & sigmask(sig)) {
+ sip = scp + sizeof(ksc);
+ sss += (sizeof(ksi) + 63) & ~63;
+ }
+
+#ifdef DEBUG
+ if ((tf->tf_iioq[0] & ~PAGE_MASK) == SYSCALLGATE)
+ printf("sendsig: interrupted syscall at 0x%x:0x%x, flags %b\n",
+ tf->tf_iioq[0], tf->tf_iioq[1], tf->tf_ipsw, PSL_BITS);
+#endif
+
+ ksc.sc_mask = mask;
+ ksc.sc_fp = scp + sss;
+ ksc.sc_ps = tf->tf_ipsw;
+ ksc.sc_pcoqh = tf->tf_iioq[0];
+ ksc.sc_pcoqt = tf->tf_iioq[1];
+ bcopy(tf, &ksc.sc_regs[0], 32*8);
+ ksc.sc_regs[0] = tf->tf_sar;
+ bcopy(p->p_addr->u_pcb.pcb_fpregs, ksc.sc_fpregs,
+ sizeof(ksc.sc_fpregs));
+
+ sss += HPPA_FRAME_SIZE;
+ tf->tf_args[0] = sig;
+ tf->tf_args[1] = sip;
+ tf->tf_args[2] = tf->tf_r4 = scp;
+ tf->tf_args[3] = (register_t)catcher;
+ tf->tf_sp = scp + sss;
+ tf->tf_ipsw &= ~(PSL_N|PSL_B);
+ tf->tf_iioq[0] = HPPA_PC_PRIV_USER | p->p_sigcode;
+ tf->tf_iioq[1] = tf->tf_iioq[0] + 4;
+ /* disable tracing in the trapframe */
+
+#ifdef DEBUG
+ if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid))
+ printf("sendsig(%d): sig %d scp %p fp %p sp 0x%x\n",
+ p->p_pid, sig, scp, ksc.sc_fp, (register_t)scp + sss);
+#endif
+
+ if (copyout(&ksc, (void *)scp, sizeof(ksc)))
+ sigexit(p, SIGILL);
+
+ if (sip) {
+ initsiginfo(&ksi, sig, code, type, val);
+ if (copyout(&ksi, (void *)sip, sizeof(ksi)))
+ sigexit(p, SIGILL);
+ }
+
+ zero = 0;
+ if (copyout(&zero, (caddr_t)scp + sss - HPPA_FRAME_SIZE,
+ sizeof(register_t)))
+ sigexit(p, SIGILL);
+
+#ifdef DEBUG
+ if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid))
+ printf("sendsig(%d): pc 0x%x, catcher 0x%x\n", p->p_pid,
+ tf->tf_iioq[0], tf->tf_args[3]);
+#endif
+}
+
+int
+sys_sigreturn(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ extern paddr_t fpu_curpcb; /* from locore.S */
+ struct sys_sigreturn_args /* {
+ syscallarg(struct sigcontext *) sigcntxp;
+ } */ *uap = v;
+ struct sigcontext *scp, ksc;
+ struct trapframe *tf = p->p_md.md_regs;
+ int error;
+
+ /* TODO sigreturn */
+
+ scp = SCARG(uap, sigcntxp);
+#ifdef DEBUG
+ if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid))
+ printf("sigreturn: pid %d, scp %p\n", p->p_pid, scp);
+#endif
+
+ /* flush the FPU ctx first */
+ if (tf->tf_cr30 == fpu_curpcb) {
+ fpu_exit();
+ fpu_curpcb = 0;
+ }
+
+ if ((error = copyin((caddr_t)scp, (caddr_t)&ksc, sizeof ksc)))
+ return (error);
+
+#define PSL_MBS (PSL_C|PSL_Q|PSL_P|PSL_D|PSL_I)
+#define PSL_MBZ (PSL_Y|PSL_Z|PSL_S|PSL_X|PSL_M|PSL_R)
+ if ((ksc.sc_ps & (PSL_MBS|PSL_MBZ)) != PSL_MBS)
+ return (EINVAL);
+
+ if (ksc.sc_onstack)
+ p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
+ else
+ p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
+ p->p_sigmask = ksc.sc_mask &~ sigcantmask;
+
+ tf->tf_sar = ksc.sc_regs[0];
+ ksc.sc_regs[0] = tf->tf_flags;
+ bcopy(&ksc.sc_regs[0], tf, 32*8);
+ bcopy(ksc.sc_fpregs, p->p_addr->u_pcb.pcb_fpregs,
+ sizeof(ksc.sc_fpregs));
+ fdcache(HPPA_SID_KERNEL, (vaddr_t)p->p_addr->u_pcb.pcb_fpregs,
+ sizeof(ksc.sc_fpregs));
+
+ tf->tf_iioq[0] = ksc.sc_pcoqh;
+ tf->tf_iioq[1] = ksc.sc_pcoqt;
+ tf->tf_ipsw = ksc.sc_ps;
+
+#ifdef DEBUG
+ if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid))
+ printf("sigreturn(%d): returns\n", p->p_pid);
+#endif
+ return (EJUSTRETURN);
+}
+
+/*
+ * machine dependent system variables.
+ */
+int
+cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
+ int *name;
+ u_int namelen;
+ void *oldp;
+ size_t *oldlenp;
+ void *newp;
+ size_t newlen;
+ struct proc *p;
+{
+ dev_t consdev;
+
+ /* all sysctl names at this level are terminal */
+ if (namelen != 1)
+ return (ENOTDIR); /* overloaded */
+ switch (name[0]) {
+ case CPU_CONSDEV:
+ if (cn_tab != NULL)
+ consdev = cn_tab->cn_dev;
+ else
+ consdev = NODEV;
+ return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
+ sizeof consdev));
+ default:
+ return (EOPNOTSUPP);
+ }
+ /* NOTREACHED */
+}
+
+
+/*
+ * consinit:
+ * initialize the system console.
+ */
+void
+consinit(void)
+{
+ static int initted;
+
+ if (!initted) {
+ initted++;
+ cninit();
+ }
+}
+
+#ifdef DIAGNOSTIC
+void
+splassert_check(int wantipl, const char *func)
+{
+ extern int cpl; /* from locoore.s */
+
+ if (cpl < wantipl) {
+ splassert_fail(wantipl, cpl, func);
+ }
+}
+#endif
diff --git a/sys/arch/hppa64/hppa64/mainbus.c b/sys/arch/hppa64/hppa64/mainbus.c
new file mode 100644
index 00000000000..871d032d846
--- /dev/null
+++ b/sys/arch/hppa64/hppa64/mainbus.c
@@ -0,0 +1,661 @@
+/* $OpenBSD: mainbus.c,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "power.h"
+
+#undef BTLBDEBUG
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/reboot.h>
+#include <sys/extent.h>
+#include <sys/mbuf.h>
+
+#include <uvm/uvm.h>
+#include <uvm/uvm_page.h>
+
+#include <machine/pdc.h>
+#include <machine/iomod.h>
+#include <machine/autoconf.h>
+
+struct mainbus_softc {
+ struct device sc_dv;
+
+ hppa_hpa_t sc_hpa;
+};
+
+int mbmatch(struct device *, void *, void *);
+void mbattach(struct device *, struct device *, void *);
+
+struct cfattach mainbus_ca = {
+ sizeof(struct mainbus_softc), mbmatch, mbattach
+};
+
+struct cfdriver mainbus_cd = {
+ NULL, "mainbus", DV_DULL
+};
+
+struct pdc_hpa pdc_hpa PDC_ALIGNMENT;
+struct pdc_power_info pdc_power_info PDC_ALIGNMENT;
+
+/* from machdep.c */
+extern struct extent *hppa_ex;
+
+int
+mbus_add_mapping(bus_addr_t bpa, bus_size_t size, int flags,
+ bus_space_handle_t *bshp)
+{
+ paddr_t spa, epa;
+ int bank, off;
+
+ if ((bank = vm_physseg_find(atop(bpa), &off)) >= 0)
+ panic("mbus_add_mapping: mapping real memory @0x%lx", bpa);
+
+ for (spa = trunc_page(bpa), epa = bpa + size;
+ spa < epa; spa += PAGE_SIZE)
+ pmap_kenter_pa(spa, spa, UVM_PROT_RW);
+
+ *bshp = bpa;
+ return (0);
+}
+
+int
+mbus_map(void *v, bus_addr_t bpa, bus_size_t size,
+ int flags, bus_space_handle_t *bshp)
+{
+ int error;
+
+ bpa &= HPPA_PHYSMAP;
+ if ((error = extent_alloc_region(hppa_ex, bpa, size, EX_NOWAIT)))
+ return (error);
+
+ if ((error = mbus_add_mapping(bpa, size, flags, bshp))) {
+ if (extent_free(hppa_ex, bpa, size, EX_NOWAIT)) {
+ printf("bus_space_map: pa 0x%lx, size 0x%lx\n",
+ bpa, size);
+ printf("bus_space_map: can't free region\n");
+ }
+ }
+
+ return error;
+}
+
+void
+mbus_unmap(void *v, bus_space_handle_t bsh, bus_size_t size)
+{
+ u_long sva, eva;
+
+ sva = hppa_trunc_page(bsh);
+ eva = hppa_round_page(bsh + size);
+
+#ifdef DIAGNOSTIC
+ if (eva <= sva)
+ panic("bus_space_unmap: overflow");
+#endif
+
+ pmap_kremove(sva, eva - sva);
+
+ if (extent_free(hppa_ex, bsh, size, EX_NOWAIT)) {
+ printf("bus_space_unmap: ps 0x%lx, size 0x%lx\n",
+ bsh, size);
+ printf("bus_space_unmap: can't free region\n");
+ }
+}
+
+int
+mbus_alloc(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size,
+ bus_size_t align, bus_size_t boundary, int flags,
+ bus_addr_t *addrp, bus_space_handle_t *bshp)
+{
+ bus_addr_t bpa;
+ int error;
+
+ rstart &= HPPA_PHYSMAP;
+ rend &= HPPA_PHYSMAP;
+ if (rstart < hppa_ex->ex_start || rend > hppa_ex->ex_end)
+ panic("bus_space_alloc: bad region start/end");
+
+ if ((error = extent_alloc_subregion(hppa_ex, rstart, rend, size,
+ align, 0, boundary, EX_NOWAIT, &bpa)))
+ return (error);
+
+ if ((error = mbus_add_mapping(bpa, size, flags, bshp))) {
+ if (extent_free(hppa_ex, bpa, size, EX_NOWAIT)) {
+ printf("bus_space_alloc: pa 0x%lx, size 0x%lx\n",
+ bpa, size);
+ printf("bus_space_alloc: can't free region\n");
+ }
+ }
+
+ *addrp = bpa | ~HPPA_PHYSMAP;
+ return (error);
+}
+
+void
+mbus_free(void *v, bus_space_handle_t h, bus_size_t size)
+{
+ /* bus_space_unmap() does all that we need to do. */
+ mbus_unmap(v, h, size);
+}
+
+int
+mbus_subregion(void *v, bus_space_handle_t bsh, bus_size_t offset,
+ bus_size_t size, bus_space_handle_t *nbshp)
+{
+ *nbshp = bsh + offset;
+ return (0);
+}
+
+void
+mbus_barrier(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int op)
+{
+ sync_caches();
+}
+
+struct hppa64_bus_space_tag hppa_bustag = {
+ NULL,
+
+ mbus_map, mbus_unmap, mbus_subregion, mbus_alloc, mbus_free,
+ mbus_barrier,
+};
+
+int
+mbus_dmamap_create(void *v, bus_size_t size, int nsegments,
+ bus_size_t maxsegsz, bus_size_t boundary, int flags,
+ bus_dmamap_t *dmamp)
+{
+ struct hppa64_bus_dmamap *map;
+ size_t mapsize;
+
+ mapsize = sizeof(*map) + (sizeof(bus_dma_segment_t) * (nsegments - 1));
+ map = malloc(mapsize, M_DEVBUF,
+ (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK);
+ if (!map)
+ return (ENOMEM);
+
+ bzero(map, mapsize);
+ map->_dm_size = size;
+ map->_dm_segcnt = nsegments;
+ map->_dm_maxsegsz = maxsegsz;
+ map->_dm_boundary = boundary;
+ map->_dm_flags = flags & ~(BUS_DMA_WAITOK|BUS_DMA_NOWAIT);
+ map->dm_mapsize = 0;
+ map->dm_nsegs = 0;
+
+ *dmamp = map;
+ return (0);
+}
+
+void
+mbus_dmamap_unload(void *v, bus_dmamap_t map)
+{
+ map->dm_mapsize = 0;
+ map->dm_nsegs = 0;
+}
+
+void
+mbus_dmamap_destroy(void *v, bus_dmamap_t map)
+{
+ if (map->dm_mapsize != 0)
+ mbus_dmamap_unload(v, map);
+
+ free(map, M_DEVBUF);
+}
+
+/*
+ * Utility function to load a linear buffer. lastaddrp holds state
+ * between invocations (for multiple-buffer loads). segp contains
+ * the starting segment on entrace, and the ending segment on exit.
+ * first indicates if this is the first invocation of this function.
+ */
+int
+_bus_dmamap_load_buffer(bus_dma_tag_t t, bus_dmamap_t map, void *buf,
+ bus_size_t buflen, struct proc *p, int flags, paddr_t *lastaddrp,
+ int *segp, int first)
+{
+ bus_size_t sgsize;
+ bus_addr_t curaddr, lastaddr, baddr, bmask;
+ vaddr_t vaddr = (vaddr_t)buf;
+ int seg;
+ pmap_t pmap;
+
+ pmap = p? p->p_vmspace->vm_map.pmap : pmap_kernel();
+ lastaddr = *lastaddrp;
+ bmask = ~(map->_dm_boundary - 1);
+
+ for (seg = *segp; buflen > 0 ; ) {
+ /*
+ * Get the physical address for this segment.
+ */
+ pmap_extract(pmap, vaddr, (paddr_t *)&curaddr);
+
+ /*
+ * Compute the segment size, and adjust counts.
+ */
+ sgsize = PAGE_SIZE - ((u_long)vaddr & PAGE_MASK);
+ if (buflen < sgsize)
+ sgsize = buflen;
+
+ /*
+ * Make sure we don't cross any boundaries.
+ */
+ if (map->_dm_boundary > 0) {
+ baddr = (curaddr + map->_dm_boundary) & bmask;
+ if (sgsize > (baddr - curaddr))
+ sgsize = (baddr - curaddr);
+ }
+
+ /*
+ * Insert chunk into a segment, coalescing with
+ * previous segment if possible.
+ */
+ if (first) {
+ map->dm_segs[seg].ds_addr = curaddr;
+ map->dm_segs[seg].ds_len = sgsize;
+ map->dm_segs[seg]._ds_va = vaddr;
+ first = 0;
+ } else {
+ if (curaddr == lastaddr &&
+ (map->dm_segs[seg].ds_len + sgsize) <=
+ map->_dm_maxsegsz &&
+ (map->_dm_boundary == 0 ||
+ (map->dm_segs[seg].ds_addr & bmask) ==
+ (curaddr & bmask)))
+ map->dm_segs[seg].ds_len += sgsize;
+ else {
+ if (++seg >= map->_dm_segcnt)
+ break;
+ map->dm_segs[seg].ds_addr = curaddr;
+ map->dm_segs[seg].ds_len = sgsize;
+ map->dm_segs[seg]._ds_va = vaddr;
+ }
+ }
+
+ lastaddr = curaddr + sgsize;
+ vaddr += sgsize;
+ buflen -= sgsize;
+ }
+
+ *segp = seg;
+ *lastaddrp = lastaddr;
+
+ /*
+ * Did we fit?
+ */
+ if (buflen != 0)
+ return (EFBIG); /* XXX better return value here? */
+ return (0);
+}
+
+int
+mbus_dmamap_load(void *v, bus_dmamap_t map, void *addr, bus_size_t size,
+ struct proc *p, int flags)
+{
+ paddr_t lastaddr;
+ int seg, error;
+
+ /*
+ * Make sure that on error condition we return "no valid mappings".
+ */
+ map->dm_nsegs = 0;
+ map->dm_mapsize = 0;
+
+ if (size > map->_dm_size)
+ return (EINVAL);
+
+ seg = 0;
+ lastaddr = 0;
+ error = _bus_dmamap_load_buffer(NULL, map, addr, size, p, flags,
+ &lastaddr, &seg, 1);
+ if (error == 0) {
+ map->dm_mapsize = size;
+ map->dm_nsegs = seg + 1;
+ }
+
+ return (0);
+}
+
+int
+mbus_dmamap_load_mbuf(void *v, bus_dmamap_t map, struct mbuf *m0, int flags)
+{
+ paddr_t lastaddr;
+ int seg, error, first;
+ struct mbuf *m;
+
+ map->dm_mapsize = 0;
+ map->dm_nsegs = 0;
+
+#ifdef DIAGNOSTIC
+ if ((m0->m_flags & M_PKTHDR) == 0)
+ panic("_bus_dmamap_load_mbuf: no packet header");
+#endif
+
+ if (m0->m_pkthdr.len > map->_dm_size)
+ return (EINVAL);
+
+ first = 1;
+ seg = 0;
+ error = 0;
+ lastaddr = 0;
+ for (m = m0; m != NULL && error == 0; m = m->m_next) {
+ error = _bus_dmamap_load_buffer(NULL, map, m->m_data, m->m_len,
+ NULL, flags, &lastaddr, &seg, first);
+ first = 0;
+ }
+ if (error == 0) {
+ map->dm_mapsize = m0->m_pkthdr.len;
+ map->dm_nsegs = seg + 1;
+ }
+
+ return (error);
+}
+
+int
+mbus_dmamap_load_uio(void *v, bus_dmamap_t map, struct uio *uio, int flags)
+{
+ paddr_t lastaddr;
+ int seg, i, error, first;
+ bus_size_t minlen, resid;
+ struct proc *p = NULL;
+ struct iovec *iov;
+ caddr_t addr;
+
+ /*
+ * Make sure that on error condition we return "no valid mappings".
+ */
+ map->dm_mapsize = 0;
+ map->dm_nsegs = 0;
+
+ resid = uio->uio_resid;
+ iov = uio->uio_iov;
+
+ if (resid > map->_dm_size)
+ return (EINVAL);
+
+ if (uio->uio_segflg == UIO_USERSPACE) {
+ p = uio->uio_procp;
+#ifdef DIAGNOSTIC
+ if (p == NULL)
+ panic("_bus_dmamap_load_uio: USERSPACE but no proc");
+#endif
+ }
+
+ first = 1;
+ seg = 0;
+ error = 0;
+ lastaddr = 0;
+ for (i = 0; i < uio->uio_iovcnt && resid != 0 && error == 0; i++) {
+ /*
+ * Now at the first iovec to load. Load each iovec
+ * until we have exhausted the residual count.
+ */
+ minlen = resid < iov[i].iov_len ? resid : iov[i].iov_len;
+ addr = (caddr_t)iov[i].iov_base;
+
+ error = _bus_dmamap_load_buffer(NULL, map, addr, minlen,
+ p, flags, &lastaddr, &seg, first);
+ first = 0;
+
+ resid -= minlen;
+ }
+ if (error == 0) {
+ map->dm_mapsize = uio->uio_resid;
+ map->dm_nsegs = seg + 1;
+ }
+ return (error);
+}
+
+int
+mbus_dmamap_load_raw(void *v, bus_dmamap_t map, bus_dma_segment_t *segs,
+ int nsegs, bus_size_t size, int flags)
+{
+ if (nsegs > map->_dm_segcnt || size > map->_dm_size)
+ return (EINVAL);
+
+ /*
+ * Make sure we don't cross any boundaries.
+ */
+ if (map->_dm_boundary) {
+ bus_addr_t bmask = ~(map->_dm_boundary - 1);
+ int i;
+
+ for (i = 0; i < nsegs; i++) {
+ if (segs[i].ds_len > map->_dm_maxsegsz)
+ return (EINVAL);
+ if ((segs[i].ds_addr & bmask) !=
+ ((segs[i].ds_addr + segs[i].ds_len - 1) & bmask))
+ return (EINVAL);
+ }
+ }
+
+ bcopy(segs, map->dm_segs, nsegs * sizeof(*segs));
+ map->dm_nsegs = nsegs;
+ map->dm_mapsize = size;
+ return (0);
+}
+
+void
+mbus_dmamap_sync(void *v, bus_dmamap_t map, bus_addr_t off, bus_size_t len,
+ int ops)
+{
+ bus_dma_segment_t *ps = map->dm_segs,
+ *es = &map->dm_segs[map->dm_nsegs];
+
+ if (off >= map->_dm_size)
+ return;
+
+ if ((off + len) > map->_dm_size)
+ len = map->_dm_size - off;
+
+ for (; len && ps < es; ps++)
+ if (off > ps->ds_len)
+ off -= ps->ds_len;
+ else {
+ bus_size_t l = ps->ds_len - off;
+ if (l > len)
+ l = len;
+ fdcache(HPPA_SID_KERNEL, ps->_ds_va + off, l);
+ len -= l;
+ off = 0;
+ }
+
+ /* for either operation sync the shit away */
+ sync_caches();
+}
+
+int
+mbus_dmamem_alloc(void *v, bus_size_t size, bus_size_t alignment,
+ bus_size_t boundary, bus_dma_segment_t *segs, int nsegs,
+ int *rsegs, int flags)
+{
+ extern paddr_t avail_end;
+ struct pglist pglist;
+ struct vm_page *pg;
+
+ size = round_page(size);
+
+ TAILQ_INIT(&pglist);
+ if (uvm_pglistalloc(size, 0, avail_end, alignment, boundary,
+ &pglist, 1, flags & BUS_DMA_NOWAIT))
+ return (ENOMEM);
+
+ pg = TAILQ_FIRST(&pglist);
+ segs[0]._ds_va = segs[0].ds_addr = VM_PAGE_TO_PHYS(pg);
+ segs[0].ds_len = size;
+ *rsegs = 1;
+
+ for(; pg; pg = TAILQ_NEXT(pg, pageq))
+ /* XXX for now */
+ pmap_changebit(pg, PTE_UNCACHABLE, 0);
+ pmap_update(pmap_kernel());
+
+ return (0);
+}
+
+void
+mbus_dmamem_free(void *v, bus_dma_segment_t *segs, int nsegs)
+{
+ struct pglist pglist;
+ paddr_t pa, epa;
+
+ TAILQ_INIT(&pglist);
+ for(; nsegs--; segs++)
+ for (pa = segs->ds_addr, epa = pa + segs->ds_len;
+ pa < epa; pa += PAGE_SIZE) {
+ struct vm_page *pg = PHYS_TO_VM_PAGE(pa);
+ if (!pg)
+ panic("mbus_dmamem_free: no page for pa");
+ TAILQ_INSERT_TAIL(&pglist, pg, pageq);
+ }
+ uvm_pglistfree(&pglist);
+}
+
+int
+mbus_dmamem_map(void *v, bus_dma_segment_t *segs, int nsegs, size_t size,
+ caddr_t *kvap, int flags)
+{
+ *kvap = (caddr_t)segs[0].ds_addr;
+ return 0;
+}
+
+void
+mbus_dmamem_unmap(void *v, caddr_t kva, size_t size)
+{
+}
+
+paddr_t
+mbus_dmamem_mmap(void *v, bus_dma_segment_t *segs, int nsegs, off_t off,
+ int prot, int flags)
+{
+ panic("_dmamem_mmap: not implemented");
+}
+
+const struct hppa64_bus_dma_tag hppa_dmatag = {
+ NULL,
+ mbus_dmamap_create, mbus_dmamap_destroy,
+ mbus_dmamap_load, mbus_dmamap_load_mbuf,
+ mbus_dmamap_load_uio, mbus_dmamap_load_raw,
+ mbus_dmamap_unload, mbus_dmamap_sync,
+
+ mbus_dmamem_alloc, mbus_dmamem_free, mbus_dmamem_map,
+ mbus_dmamem_unmap, mbus_dmamem_mmap
+};
+
+int
+mbmatch(parent, cfdata, aux)
+ struct device *parent;
+ void *cfdata;
+ void *aux;
+{
+ struct cfdata *cf = cfdata;
+
+ /* there will be only one */
+ if (cf->cf_unit)
+ return 0;
+
+ return 1;
+}
+
+void
+mbattach(parent, self, aux)
+ struct device *parent;
+ struct device *self;
+ void *aux;
+{
+ struct mainbus_softc *sc = (struct mainbus_softc *)self;
+ struct confargs nca;
+ bus_space_handle_t ioh;
+ bus_addr_t hpa;
+
+ /* fetch the "default" cpu hpa */
+ if (pdc_call((iodcio_t)pdc, 0, PDC_HPA, PDC_HPA_DFLT, &pdc_hpa) < 0)
+ panic("mbattach: PDC_HPA failed");
+ hpa = pdc_hpa.hpa | 0xffffffff00000000UL;
+
+ printf(" [flex %lx]\n", hpa & HPPA_FLEX_MASK);
+
+ /* map all the way till the end of the memory */
+ if (bus_space_map(&hppa_bustag, hpa, HPPA_PHYSEND - hpa + 1, 0, &ioh))
+ panic("mbattach: cannot map mainbus IO space");
+
+ /*
+ * Local-Broadcast the HPA to all modules on this bus
+ */
+ ((struct iomod *)(HPPA_LBCAST & HPPA_PHYSMAP))->io_flex =
+ (hpa & HPPA_FLEX_MASK) | DMA_ENABLE;
+
+ sc->sc_hpa = hpa;
+
+ /* PDC first */
+ bzero (&nca, sizeof(nca));
+ nca.ca_name = "pdc";
+ nca.ca_iot = &hppa_bustag;
+ nca.ca_dmatag = &hppa_dmatag;
+ config_found(self, &nca, mbprint);
+
+#if NPOWER > 0
+ /* get some power */
+ bzero (&nca, sizeof(nca));
+ nca.ca_name = "power";
+ nca.ca_irq = -1;
+ if (!pdc_call((iodcio_t)pdc, 0, PDC_SOFT_POWER,
+ PDC_SOFT_POWER_INFO, &pdc_power_info, 0)) {
+ nca.ca_iot = &hppa_bustag;
+ nca.ca_hpa = pdc_power_info.addr;
+ nca.ca_hpamask = HPPA_IOBEGIN;
+ }
+ config_found(self, &nca, mbprint);
+#endif
+
+ bzero (&nca, sizeof(nca));
+ nca.ca_iot = &hppa_bustag;
+ nca.ca_dmatag = &hppa_dmatag;
+ pdc_patscan(self, &nca, -1);
+}
+
+/*
+ * retrive CPU #N HPA value
+ */
+hppa_hpa_t
+cpu_gethpa(n)
+ int n;
+{
+ struct mainbus_softc *sc;
+
+ sc = mainbus_cd.cd_devs[0];
+
+ return sc->sc_hpa;
+}
+
+int
+mbprint(aux, pnp)
+ void *aux;
+ const char *pnp;
+{
+ struct confargs *ca = aux;
+
+ if (pnp)
+ printf("\"%s\" at %s", ca->ca_name, pnp);
+
+ if (ca->ca_hpa)
+ printf(" hpa %lx", ca->ca_hpa);
+
+ return (UNCONF);
+}
diff --git a/sys/arch/hppa64/hppa64/pmap.c b/sys/arch/hppa64/hppa64/pmap.c
new file mode 100644
index 00000000000..4edab6922d7
--- /dev/null
+++ b/sys/arch/hppa64/hppa64/pmap.c
@@ -0,0 +1,1216 @@
+/* $OpenBSD: pmap.c,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define PMAPDEBUG
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/lock.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <sys/pool.h>
+#include <sys/extent.h>
+
+#include <uvm/uvm.h>
+
+#include <machine/iomod.h>
+
+#include <dev/rndvar.h>
+
+#ifdef PMAPDEBUG
+#define DPRINTF(l,s) do { \
+ if ((pmapdebug & (l)) == (l)) \
+ printf s; \
+} while(0)
+#define PDB_FOLLOW 0x00000001
+#define PDB_INIT 0x00000002
+#define PDB_ENTER 0x00000004
+#define PDB_REMOVE 0x00000008
+#define PDB_CREATE 0x00000010
+#define PDB_PTPAGE 0x00000020
+#define PDB_CACHE 0x00000040
+#define PDB_BITS 0x00000080
+#define PDB_COLLECT 0x00000100
+#define PDB_PROTECT 0x00000200
+#define PDB_EXTRACT 0x00000400
+#define PDB_VP 0x00000800
+#define PDB_PV 0x00001000
+#define PDB_PARANOIA 0x00002000
+#define PDB_WIRING 0x00004000
+#define PDB_PMAP 0x00008000
+#define PDB_STEAL 0x00010000
+#define PDB_PHYS 0x00020000
+#define PDB_POOL 0x00040000
+int pmapdebug = 0
+ | PDB_INIT
+/* | PDB_FOLLOW */
+/* | PDB_VP */
+/* | PDB_PV */
+/* | PDB_ENTER */
+/* | PDB_REMOVE */
+/* | PDB_STEAL */
+/* | PDB_PROTECT */
+/* | PDB_PHYS */
+ ;
+#else
+#define DPRINTF(l,s) /* */
+#endif
+
+paddr_t physical_steal, physical_end;
+
+struct pmap kernel_pmap_store;
+struct pool pmap_pmap_pool;
+struct pool pmap_pv_pool;
+int pmap_pvlowat = 252;
+int pmap_initialized;
+int pmap_nkpdes = 32;
+
+pt_entry_t hppa_prot[8];
+#define pmap_prot(m,vp) (hppa_prot[(vp)] | ((m) == pmap_kernel()? 0 : PTE_USER))
+
+pt_entry_t kernel_ptes[] = {
+ PTE_EXEC | PTE_ORDER | PTE_PREDICT | PTE_WIRED |
+ TLB_PAGE(0x000000) | PTE_PG4M,
+ PTE_WRITE | PTE_ORDER | PTE_DIRTY | PTE_WIRED |
+ TLB_PAGE(0x400000) | PTE_PG4M,
+ PTE_WRITE | PTE_ORDER | PTE_DIRTY | PTE_WIRED |
+ TLB_PAGE(0x800000) | PTE_PG4M,
+ PTE_WRITE | PTE_ORDER | PTE_DIRTY | PTE_WIRED |
+ TLB_PAGE(0xc00000) | PTE_PG4M
+};
+
+#define pmap_pvh_attrs(a) \
+ (((a) & PTE_DIRTY) | ((a) ^ PTE_REFTRAP))
+
+struct vm_page *
+pmap_pagealloc(int wait)
+{
+ struct vm_page *pg;
+
+ if ((pg = uvm_pagealloc(NULL, 0, NULL,
+ UVM_PGA_USERESERVE | UVM_PGA_ZERO)) == NULL)
+ printf("pmap_pagealloc fail\n");
+
+ return (pg);
+}
+
+volatile pt_entry_t *
+pmap_pde_get(volatile u_int32_t *pd, vaddr_t va)
+{
+ int i;
+
+ DPRINTF(PDB_FOLLOW|PDB_VP,
+ ("pmap_pde_get(%p, 0x%lx)\n", pd, va));
+
+ i = (va & PIE_MASK) >> PIE_SHIFT;
+ if (i) {
+ pd = (volatile u_int32_t *)((u_int64_t)pd[i] << PAGE_SHIFT);
+
+ if (!pd)
+ return (NULL);
+ } else
+ pd += PAGE_SIZE / sizeof(*pd);
+
+ i = (va & PDE_MASK) >> PDE_SHIFT;
+ return (pt_entry_t *)((u_int64_t)pd[i] << PAGE_SHIFT);
+}
+
+void
+pmap_pde_set(struct pmap *pm, vaddr_t va, paddr_t ptp)
+{
+ volatile u_int32_t *pd = pm->pm_pdir;
+ int i;
+
+ DPRINTF(PDB_FOLLOW|PDB_VP,
+ ("pmap_pde_set(%p, 0x%lx, 0x%lx)\n", pm, va, ptp));
+
+ i = (va & PIE_MASK) >> PIE_SHIFT;
+ if (i)
+ pd = (volatile u_int32_t *)((u_int64_t)pd[i] << PAGE_SHIFT);
+ else
+ pd += PAGE_SIZE / sizeof(*pd);
+
+ i = (va & PDE_MASK) >> PDE_SHIFT;
+ pd[i] = ptp >> PAGE_SHIFT;
+}
+
+pt_entry_t *
+pmap_pde_alloc(struct pmap *pm, vaddr_t va, struct vm_page **pdep)
+{
+ struct vm_page *pg;
+ paddr_t pa;
+
+ DPRINTF(PDB_FOLLOW|PDB_VP,
+ ("pmap_pde_alloc(%p, 0x%lx, %p)\n", pm, va, pdep));
+
+ if ((pg = pmap_pagealloc(0)) == NULL)
+ return (NULL);
+
+ pa = VM_PAGE_TO_PHYS(pg);
+
+ DPRINTF(PDB_FOLLOW|PDB_VP, ("pmap_pde_alloc: pde %lx\n", pa));
+
+ pg->flags &= ~PG_BUSY; /* never busy */
+ pg->wire_count = 1; /* no mappings yet */
+ pmap_pde_set(pm, va, pa);
+ pm->pm_stats.resident_count++; /* count PTP as resident */
+ pm->pm_ptphint = pg;
+ if (pdep)
+ *pdep = pg;
+ return ((pt_entry_t *)pa);
+}
+
+static __inline struct vm_page *
+pmap_pde_ptp(struct pmap *pm, volatile pt_entry_t *pde)
+{
+ paddr_t pa = (paddr_t)pde;
+
+ DPRINTF(PDB_FOLLOW|PDB_PV, ("pmap_pde_ptp(%p, %p)\n", pm, pde));
+
+ if (pm->pm_ptphint && VM_PAGE_TO_PHYS(pm->pm_ptphint) == pa)
+ return (pm->pm_ptphint);
+
+ DPRINTF(PDB_FOLLOW|PDB_PV, ("pmap_pde_ptp: lookup 0x%lx\n", pa));
+
+ return (PHYS_TO_VM_PAGE(pa));
+}
+
+static __inline void
+pmap_pde_release(struct pmap *pmap, vaddr_t va, struct vm_page *ptp)
+{
+ DPRINTF(PDB_FOLLOW|PDB_PV,
+ ("pmap_pde_release(%p, 0x%lx, %p)\n", pmap, va, ptp));
+
+ if (pmap != pmap_kernel() && --ptp->wire_count <= 1) {
+ DPRINTF(PDB_FOLLOW|PDB_PV,
+ ("pmap_pde_release: disposing ptp %p\n", ptp));
+ pmap_pde_set(pmap, va, 0);
+ pmap->pm_stats.resident_count--;
+ if (pmap->pm_ptphint == ptp)
+ pmap->pm_ptphint = NULL;
+ ptp->wire_count = 0;
+#ifdef DIAGNOSTIC
+ if (ptp->flags & PG_BUSY)
+ panic("pmap_pde_release: busy page table page");
+#endif
+ pdcache(HPPA_SID_KERNEL, (vaddr_t)ptp, PAGE_SIZE);
+ uvm_pagefree(ptp);
+ }
+}
+
+static __inline pt_entry_t
+pmap_pte_get(volatile pt_entry_t *pde, vaddr_t va)
+{
+ DPRINTF(PDB_FOLLOW|PDB_VP,
+ ("pmap_pte_get(%p, 0x%lx)\n", pde, va));
+
+ return (pde[(va & PTE_MASK) >> PTE_SHIFT]);
+}
+
+static __inline void
+pmap_pte_set(volatile pt_entry_t *pde, vaddr_t va, pt_entry_t pte)
+{
+ DPRINTF(PDB_FOLLOW|PDB_VP,
+ ("pmap_pte_set(%p, 0x%lx, 0x%lx)\n", pde, va, pte));
+
+ pde[(va & PTE_MASK) >> PTE_SHIFT] = pte;
+}
+
+void
+pmap_pte_flush(struct pmap *pmap, vaddr_t va, pt_entry_t pte)
+{
+ if (pte & PTE_EXEC) {
+ ficache(pmap->pm_space, va, PAGE_SIZE);
+ pitlb(pmap->pm_space, va);
+ }
+ fdcache(pmap->pm_space, va, PAGE_SIZE);
+ pdtlb(pmap->pm_space, va);
+}
+
+static __inline pt_entry_t
+pmap_vp_find(struct pmap *pm, vaddr_t va)
+{
+ volatile pt_entry_t *pde;
+
+ if (!(pde = pmap_pde_get(pm->pm_pdir, va)))
+ return (0);
+
+ return (pmap_pte_get(pde, va));
+}
+
+#ifdef DDB
+void
+pmap_dump_table(pa_space_t space, vaddr_t sva)
+{
+ pa_space_t sp;
+ volatile pt_entry_t *pde;
+ volatile u_int32_t *pd;
+ pt_entry_t pte;
+ vaddr_t va, pdemask;
+
+ if (space)
+ pd = (u_int32_t *)mfctl(CR_VTOP);
+ else
+ pd = pmap_kernel()->pm_pdir;
+
+ for (pdemask = 1, va = sva ? sva : 0;
+ va < VM_MAX_ADDRESS; va += PAGE_SIZE) {
+ if (pdemask != (va & (PDE_MASK|PIE_MASK))) {
+ pdemask = va & (PDE_MASK|PIE_MASK);
+ if (!(pde = pmap_pde_get(pd, va))) {
+ va += ~PDE_MASK + 1 - PAGE_SIZE;
+ continue;
+ }
+ printf("%x:%8p:\n", sp, pde);
+ }
+
+ if (!(pte = pmap_pte_get(pde, va)))
+ continue;
+
+ printf("0x%08lx-0x%08lx:%b\n",
+ va, PTE_PAGE(pte), PTE_GETBITS(pte), PTE_BITS);
+ }
+}
+
+void
+pmap_dump_pv(paddr_t pa)
+{
+ struct vm_page *pg;
+ struct pv_entry *pve;
+
+ pg = PHYS_TO_VM_PAGE(pa);
+ simple_lock(&pg->mdpage.pvh_lock);
+ for(pve = pg->mdpage.pvh_list; pve; pve = pve->pv_next)
+ printf("%x:%lx\n", pve->pv_pmap->pm_space, pve->pv_va);
+ simple_unlock(&pg->mdpage.pvh_lock);
+}
+#endif
+
+#ifdef PMAPDEBUG
+int
+pmap_check_alias(struct pv_entry *pve, vaddr_t va, pt_entry_t pte)
+{
+ int ret;
+
+ /* check for non-equ aliased mappings */
+ for (ret = 0; pve; pve = pve->pv_next) {
+ pte |= pmap_vp_find(pve->pv_pmap, pve->pv_va);
+ if ((va & HPPA_PGAOFF) != (pve->pv_va & HPPA_PGAOFF) &&
+ (pte & PTE_WRITE)) {
+ printf("pmap_check_alias: "
+ "aliased writable mapping 0x%x:0x%lx\n",
+ pve->pv_pmap->pm_space, pve->pv_va);
+ ret++;
+ }
+ }
+
+ return (ret);
+}
+#endif
+
+static __inline struct pv_entry *
+pmap_pv_alloc(void)
+{
+ struct pv_entry *pv;
+
+ DPRINTF(PDB_FOLLOW|PDB_PV, ("pmap_pv_alloc()\n"));
+
+ pv = pool_get(&pmap_pv_pool, PR_NOWAIT);
+
+ DPRINTF(PDB_FOLLOW|PDB_PV, ("pmap_pv_alloc: %p\n", pv));
+
+ return (pv);
+}
+
+void
+pmap_pv_free(struct pv_entry *pv)
+{
+ if (pv->pv_ptp)
+ pmap_pde_release(pv->pv_pmap, pv->pv_va, pv->pv_ptp);
+
+ pool_put(&pmap_pv_pool, pv);
+}
+
+void
+pmap_pv_enter(struct vm_page *pg, struct pv_entry *pve, struct pmap *pm,
+ vaddr_t va, struct vm_page *pdep)
+{
+ DPRINTF(PDB_FOLLOW|PDB_PV, ("pmap_pv_enter(%p, %p, %p, 0x%lx, %p)\n",
+ pg, pve, pm, va, pdep));
+ pve->pv_pmap = pm;
+ pve->pv_va = va;
+ pve->pv_ptp = pdep;
+ pve->pv_next = pg->mdpage.pvh_list;
+ pg->mdpage.pvh_list = pve;
+#ifdef PMAPDEBUG
+ if (pmap_check_alias(pve, va, 0))
+ Debugger();
+#endif
+}
+
+struct pv_entry *
+pmap_pv_remove(struct vm_page *pg, struct pmap *pmap, vaddr_t va)
+{
+ struct pv_entry **pve, *pv;
+
+ DPRINTF(PDB_FOLLOW|PDB_PV, ("pmap_pv_remove(%p, %p, 0x%lx)\n",
+ pg, pmap, va));
+
+ simple_lock(&pg->mdpage.pvh_lock); /* lock pv_head */
+ for(pv = *(pve = &pg->mdpage.pvh_list);
+ pv; pv = *(pve = &(*pve)->pv_next))
+ if (pv->pv_pmap == pmap && pv->pv_va == va) {
+ *pve = pv->pv_next;
+ break;
+ }
+ simple_unlock(&pg->mdpage.pvh_lock); /* unlock, done! */
+ return (pv);
+}
+
+const pt_entry_t hppa_pgs[] = {
+ PTE_PG4K,
+ PTE_PG16K,
+ PTE_PG64K,
+ PTE_PG256K,
+ PTE_PG1M,
+ PTE_PG4M,
+ PTE_PG16M,
+ PTE_PG64M
+};
+#define nhppa_pgs sizeof(hppa_pgs)/sizeof(hppa_pgs[0])
+
+void
+pmap_maphys(paddr_t spa, paddr_t epa)
+{
+ volatile pt_entry_t *pde, *epde, pte;
+ paddr_t pa, tpa;
+ int s, e, i;
+
+ DPRINTF(PDB_INIT, ("pmap_maphys: mapping 0x%lx - 0x%lx\n", spa, epa));
+
+ s = ffs(spa) - 12;
+ e = ffs(epa) - 12;
+
+ if (s < e || (s == e && s / 2 < nhppa_pgs)) {
+ i = s / 2;
+ if (i > nhppa_pgs)
+ i = nhppa_pgs;
+ pa = spa;
+ spa = tpa = 0x1000 << ((i + 1) * 2);
+ } else if (s > e) {
+ i = e / 2;
+ if (i > nhppa_pgs)
+ i = nhppa_pgs;
+ epa = pa = epa & (0xfffff000 << ((i + 1) * 2));
+ tpa = epa;
+ } else {
+ i = s / 2;
+ if (i > nhppa_pgs)
+ i = nhppa_pgs;
+ pa = spa;
+ spa = tpa = epa;
+ }
+
+printf("pa 0x%lx tpa 0x%lx\n", pa, tpa);
+ while (pa < tpa) {
+ pte = TLB_PAGE(pa) | hppa_pgs[i - 1] |
+ PTE_WRITE | PTE_ORDER | PTE_DIRTY | PTE_WIRED;
+ pde = pmap_pde_get(pmap_kernel()->pm_pdir, pa);
+ epde = pde + (PTE_MASK >> PTE_SHIFT) + 1;
+ if (pa + (PTE_MASK + (1 << PTE_SHIFT)) > tpa)
+ epde = pde + ((tpa & PTE_MASK) >> PTE_SHIFT);
+printf("pde %p epde %p pte 0x%lx\n", pde, epde, pte);
+ for (pde += (pa & PTE_MASK) >> PTE_SHIFT; pde < epde;)
+ *pde++ = pte;
+ pa += PTE_MASK + (1 << PTE_SHIFT);
+ pa &= ~(PTE_MASK | PAGE_MASK);
+ }
+
+ if (spa < epa)
+ pmap_maphys(spa, epa);
+}
+
+void
+pmap_bootstrap(vstart)
+ vaddr_t vstart;
+{
+ extern int resvphysmem, __rodata_end, __data_start;
+ vaddr_t va, eaddr, addr = hppa_round_page(vstart);
+ struct pmap *kpm;
+
+ DPRINTF(PDB_FOLLOW|PDB_INIT, ("pmap_bootstrap(0x%lx)\n", vstart));
+
+ uvm_setpagesize();
+
+ hppa_prot[UVM_PROT_NONE] = PTE_ORDER|PTE_ACC_NONE;
+ hppa_prot[UVM_PROT_READ] = PTE_ORDER|PTE_READ;
+ hppa_prot[UVM_PROT_WRITE] = PTE_ORDER|PTE_WRITE;
+ hppa_prot[UVM_PROT_RW] = PTE_ORDER|PTE_READ|PTE_WRITE;
+ hppa_prot[UVM_PROT_EXEC] = PTE_ORDER|PTE_EXEC;
+ hppa_prot[UVM_PROT_RX] = PTE_ORDER|PTE_READ|PTE_EXEC;
+ hppa_prot[UVM_PROT_WX] = PTE_ORDER|PTE_WRITE|PTE_EXEC;
+ hppa_prot[UVM_PROT_RWX] = PTE_ORDER|PTE_READ|PTE_WRITE|PTE_EXEC;
+
+ /*
+ * Initialize kernel pmap
+ */
+ kpm = &kernel_pmap_store;
+ bzero(kpm, sizeof(*kpm));
+ simple_lock_init(&kpm->pm_lock);
+ kpm->pm_refcount = 1;
+ kpm->pm_space = HPPA_SID_KERNEL;
+ TAILQ_INIT(&kpm->pm_pglist);
+ kpm->pm_pdir = (u_int32_t *)mfctl(CR_VTOP);
+
+ /*
+ * Allocate various tables and structures.
+ */
+
+ if (&__rodata_end < &__data_start) {
+ physical_steal = (vaddr_t)&__rodata_end;
+ physical_end = (vaddr_t)&__data_start;
+ DPRINTF(PDB_INIT, ("physpool: 0x%lx @ 0x%lx\n",
+ physical_end - physical_steal, physical_steal));
+ }
+
+ /* map enough PDEs to map initial physmem */
+ for (va = 0x1000000, eaddr = ptoa(physmem);
+ va < eaddr; addr += PAGE_SIZE, va += 1 << PDE_SHIFT) {
+ bzero((void *)addr, PAGE_SIZE);
+ pmap_pde_set(kpm, va, addr);
+ kpm->pm_stats.resident_count++; /* count PTP as resident */
+ }
+
+ /* map a little of initial kmem */
+ for (va = VM_MIN_KERNEL_ADDRESS + ((pmap_nkpdes - 1) << PDE_SHIFT);
+ va >= VM_MIN_KERNEL_ADDRESS;
+ addr += PAGE_SIZE, va -= 1 << PDE_SHIFT) {
+ bzero((void *)addr, PAGE_SIZE);
+ pmap_pde_set(kpm, va, addr);
+ kpm->pm_stats.resident_count++; /* count PTP as resident */
+ }
+
+ pmap_maphys(0x1000000, ctob(physmem));
+
+ eaddr = physmem - atop(round_page(MSGBUFSIZE));
+ resvphysmem = atop(addr);
+ DPRINTF(PDB_INIT, ("physmem: 0x%lx - 0x%lx\n", resvphysmem, eaddr));
+ uvm_page_physload(0, physmem,
+ resvphysmem, eaddr, VM_FREELIST_DEFAULT);
+}
+
+void
+pmap_init()
+{
+ DPRINTF(PDB_FOLLOW|PDB_INIT, ("pmap_init()\n"));
+
+ pool_init(&pmap_pmap_pool, sizeof(struct pmap), 0, 0, 0, "pmappl",
+ &pool_allocator_nointr);
+ pool_init(&pmap_pv_pool, sizeof(struct pv_entry),0,0,0, "pmappv", NULL);
+ pool_setlowat(&pmap_pv_pool, pmap_pvlowat);
+ pool_sethiwat(&pmap_pv_pool, pmap_pvlowat * 32);
+
+ pmap_initialized = 1;
+
+ DPRINTF(PDB_FOLLOW|PDB_INIT, ("pmap_init(): done\n"));
+}
+
+#ifdef PMAP_STEAL_MEMORY
+vaddr_t
+pmap_steal_memory(vsize_t size, vaddr_t *vstartp, vaddr_t *vendp)
+{
+ vaddr_t va;
+ int npg;
+
+ DPRINTF(PDB_FOLLOW|PDB_PHYS,
+ ("pmap_steal_memory(0x%lx, %p, %p)\n", size, vstartp, vendp));
+
+ size = round_page(size);
+ npg = atop(size);
+
+ if (vm_physmem[0].avail_end - vm_physmem[0].avail_start < npg)
+ panic("pmap_steal_memory: no more");
+
+ if (vstartp)
+ *vstartp = VM_MIN_KERNEL_ADDRESS;
+ if (vendp)
+ *vendp = VM_MAX_KERNEL_ADDRESS;
+
+ vm_physmem[0].end -= npg;
+ vm_physmem[0].avail_end -= npg;
+ va = ptoa(vm_physmem[0].avail_end) - size;
+ bzero((void *)va, size);
+
+ DPRINTF(PDB_FOLLOW|PDB_PHYS, ("pmap_steal_memory: 0x%lx\n", va));
+
+ return (va);
+}
+#else
+void
+pmap_virtual_space(vaddr_t *startp, vaddr_t *endp)
+{
+ *startp = VM_MIN_KERNEL_ADDRESS;
+ *endp = VM_MAX_KERNEL_ADDRESS;
+}
+#endif /* PMAP_STEAL_MEMORY */
+
+#ifdef PMAP_GROWKERNEL
+vaddr_t
+pmap_growkernel(vaddr_t kva)
+{
+ vaddr_t va;
+
+ DPRINTF(PDB_FOLLOW|PDB_PHYS, ("pmap_growkernel(0x%lx)\n", kva));
+
+ va = VM_MIN_KERNEL_ADDRESS + (pmap_nkpdes << PDE_SHIFT);
+ DPRINTF(PDB_PHYS, ("pmap_growkernel: was va 0x%lx\n", va));
+ if (va < kva) {
+ simple_lock(&pmap_kernel()->pm_obj.vmobjlock);
+
+ for ( ; va < kva ; pmap_nkpdes++, va += 1 << PDE_SHIFT)
+ if (uvm.page_init_done) {
+ if (!pmap_pde_alloc(pmap_kernel(), va, NULL))
+ break;
+ } else {
+ paddr_t pa;
+
+ pa = pmap_steal_memory(PAGE_SIZE, NULL, NULL);
+ if (pa)
+ panic("pmap_growkernel: out of memory");
+ pmap_pde_set(pmap_kernel(), va, pa);
+ pmap_kernel()->pm_stats.resident_count++;
+ }
+
+ simple_unlock(&pmap_kernel()->pm_obj.vmobjlock);
+ }
+ DPRINTF(PDB_PHYS|PDB_VP, ("pmap_growkernel: now va 0x%lx\n", va));
+ return (va);
+}
+#endif /* PMAP_GROWKERNEL */
+
+struct pmap *
+pmap_create()
+{
+ struct pmap *pmap;
+ struct vm_page *pg;
+ pa_space_t space;
+ paddr_t pa;
+
+ DPRINTF(PDB_FOLLOW|PDB_PMAP, ("pmap_create()\n"));
+
+ pmap = pool_get(&pmap_pmap_pool, PR_WAITOK);
+
+ simple_lock_init(&pmap->pm_lock);
+ pmap->pm_refcount = 1;
+ pmap->pm_ptphint = NULL;
+
+ TAILQ_INIT(&pmap->pm_pglist);
+ if (uvm_pglistalloc(2 * PAGE_SIZE, 0, VM_MIN_KERNEL_ADDRESS,
+ PAGE_SIZE, 2 * PAGE_SIZE, &pmap->pm_pglist, 1, 1))
+ panic("pmap_create: no pages");
+
+ pg = TAILQ_FIRST(&pmap->pm_pglist);
+ pg->flags &= ~(PG_BUSY|PG_CLEAN);
+ pmap->pm_pdir = (u_int32_t *)(pa = VM_PAGE_TO_PHYS(pg));
+ bzero((void *)pa, PAGE_SIZE);
+
+ /* set the first PIE that's covering low 2g of the address space */
+ pg = TAILQ_LAST(&pmap->pm_pglist, pglist);
+ pg->flags &= ~(PG_BUSY|PG_CLEAN);
+ *pmap->pm_pdir = (pa = VM_PAGE_TO_PHYS(pg)) >> PAGE_SHIFT;
+ bzero((void *)pa, PAGE_SIZE);
+
+/* TODO for (space = 1 + (arc4random() & HPPA_SID_MAX);
+ pmap_sdir_get(space); space = (space + 1) % HPPA_SID_MAX); */
+ pmap->pm_space = space;
+
+ pmap->pm_stats.resident_count = 2;
+ pmap->pm_stats.wired_count = 0;
+
+ return (pmap);
+}
+
+void
+pmap_destroy(pmap)
+ struct pmap *pmap;
+{
+ int refs;
+
+ DPRINTF(PDB_FOLLOW|PDB_PMAP, ("pmap_destroy(%p)\n", pmap));
+
+ simple_lock(&pmap->pm_lock);
+ refs = --pmap->pm_refcount;
+ simple_unlock(&pmap->pm_lock);
+
+ if (refs > 0)
+ return;
+
+ uvm_pglistfree(&pmap->pm_pglist);
+ TAILQ_INIT(&pmap->pm_pglist);
+ pool_put(&pmap_pmap_pool, pmap);
+}
+
+/*
+ * Add a reference to the specified pmap.
+ */
+void
+pmap_reference(struct pmap *pmap)
+{
+ DPRINTF(PDB_FOLLOW|PDB_PMAP, ("pmap_reference(%p)\n", pmap));
+
+ simple_lock(&pmap->pm_lock);
+ pmap->pm_refcount++;
+ simple_unlock(&pmap->pm_lock);
+}
+
+void
+pmap_collect(struct pmap *pmap)
+{
+ DPRINTF(PDB_FOLLOW|PDB_PMAP, ("pmap_collect(%p)\n", pmap));
+ /* nothing yet */
+}
+
+int
+pmap_enter(pmap, va, pa, prot, flags)
+ struct pmap *pmap;
+ vaddr_t va;
+ paddr_t pa;
+ vm_prot_t prot;
+ int flags;
+{
+ volatile pt_entry_t *pde;
+ pt_entry_t pte;
+ struct vm_page *pg, *ptp = NULL;
+ struct pv_entry *pve;
+ boolean_t wired = (flags & PMAP_WIRED) != 0;
+
+ DPRINTF(PDB_FOLLOW|PDB_ENTER,
+ ("pmap_enter(%p, 0x%lx, 0x%lx, 0x%x, 0x%x)\n",
+ pmap, va, pa, prot, flags));
+
+ simple_lock(&pmap->pm_lock);
+
+ if (!(pde = pmap_pde_get(pmap->pm_pdir, va)) &&
+ !(pde = pmap_pde_alloc(pmap, va, &ptp))) {
+ if (flags & PMAP_CANFAIL) {
+ simple_unlock(&pmap->pm_lock);
+ return (KERN_RESOURCE_SHORTAGE);
+ }
+
+ panic("pmap_enter: cannot allocate pde");
+ }
+
+ if (!ptp)
+ ptp = pmap_pde_ptp(pmap, pde);
+
+ if ((pte = pmap_pte_get(pde, va))) {
+
+ DPRINTF(PDB_ENTER,
+ ("pmap_enter: remapping 0x%lx -> 0x%lx\n", pte, pa));
+
+ pmap_pte_flush(pmap, va, pte);
+ if (wired && !(pte & PTE_WIRED))
+ pmap->pm_stats.wired_count++;
+ else if (!wired && (pte & PTE_WIRED))
+ pmap->pm_stats.wired_count--;
+ pte &= PTE_UNCACHABLE|PTE_DIRTY|PTE_REFTRAP;
+
+ if (PTE_PAGE(pte) == pa) {
+ DPRINTF(PDB_FOLLOW|PDB_ENTER,
+ ("pmap_enter: same page\n"));
+ goto enter;
+ }
+
+ pg = PHYS_TO_VM_PAGE(PTE_PAGE(pte));
+ simple_lock(&pg->mdpage.pvh_lock);
+ pve = pmap_pv_remove(pg, pmap, va);
+ pg->mdpage.pvh_attrs |= pmap_pvh_attrs(pte);
+ } else {
+ DPRINTF(PDB_ENTER,
+ ("pmap_enter: new mapping 0x%lx -> 0x%lx\n", va, pa));
+ pte = PTE_REFTRAP;
+ pve = NULL;
+ pmap->pm_stats.resident_count++;
+ if (wired)
+ pmap->pm_stats.wired_count++;
+ if (ptp)
+ ptp->wire_count++;
+ simple_lock(&pg->mdpage.pvh_lock);
+ }
+
+ if (pmap_initialized && (pg = PHYS_TO_VM_PAGE(pa))) {
+ if (!pve && !(pve = pmap_pv_alloc())) {
+ if (flags & PMAP_CANFAIL) {
+ simple_unlock(&pg->mdpage.pvh_lock);
+ simple_unlock(&pmap->pm_lock);
+ return (KERN_RESOURCE_SHORTAGE);
+ }
+ panic("pmap_enter: no pv entries available");
+ }
+ pmap_pv_enter(pg, pve, pmap, va, ptp);
+ } else if (pve)
+ pmap_pv_free(pve);
+ simple_unlock(&pg->mdpage.pvh_lock);
+
+enter:
+ /* preserve old ref & mod */
+ pte = TLB_PAGE(pa) | pmap_prot(pmap, prot);
+ if (wired)
+ pte |= PTE_WIRED;
+ pmap_pte_set(pde, va, pte);
+
+ simple_unlock(&pmap->pm_lock);
+
+ DPRINTF(PDB_FOLLOW|PDB_ENTER, ("pmap_enter: leaving\n"));
+
+ return (0);
+}
+
+void
+pmap_remove(pmap, sva, eva)
+ struct pmap *pmap;
+ vaddr_t sva;
+ vaddr_t eva;
+{
+ struct pv_entry *pve;
+ volatile pt_entry_t *pde;
+ pt_entry_t pte;
+ struct vm_page *pg;
+ vaddr_t pdemask;
+ int batch;
+
+ DPRINTF(PDB_FOLLOW|PDB_REMOVE,
+ ("pmap_remove(%p, 0x%lx, 0x%lx)\n", pmap, sva, eva));
+
+ simple_lock(&pmap->pm_lock);
+
+ for (batch = 0, pdemask = 1; sva < eva; sva += PAGE_SIZE) {
+ if (pdemask != (sva & PDE_MASK)) {
+ pdemask = sva & PDE_MASK;
+ if (!(pde = pmap_pde_get(pmap->pm_pdir, sva))) {
+ sva += ~PDE_MASK + 1 - PAGE_SIZE;
+ continue;
+ }
+ batch = pdemask == sva && sva + ~PDE_MASK + 1 <= eva;
+ }
+
+ if ((pte = pmap_pte_get(pde, sva))) {
+
+ /* TODO measure here the speed tradeoff
+ * for flushing whole PT vs per-page
+ * in case of non-complete pde fill
+ */
+ pmap_pte_flush(pmap, sva, pte);
+ if (pte & PTE_WIRED)
+ pmap->pm_stats.wired_count--;
+ pmap->pm_stats.resident_count--;
+
+ /* iff properly accounted pde will be dropped anyway */
+ if (!batch)
+ pmap_pte_set(pde, sva, 0);
+
+ if (pmap_initialized &&
+ (pg = PHYS_TO_VM_PAGE(PTE_PAGE(pte)))) {
+
+ simple_lock(&pg->mdpage.pvh_lock);
+ pg->mdpage.pvh_attrs |= pmap_pvh_attrs(pte);
+ if ((pve = pmap_pv_remove(pg, pmap, sva)))
+ pmap_pv_free(pve);
+ simple_unlock(&pg->mdpage.pvh_lock);
+ }
+ }
+ }
+
+ simple_unlock(&pmap->pm_lock);
+
+ DPRINTF(PDB_FOLLOW|PDB_REMOVE, ("pmap_remove: leaving\n"));
+}
+
+void
+pmap_write_protect(pmap, sva, eva, prot)
+ struct pmap *pmap;
+ vaddr_t sva;
+ vaddr_t eva;
+ vm_prot_t prot;
+{
+ struct vm_page *pg;
+ volatile pt_entry_t *pde;
+ pt_entry_t pte;
+ u_int tlbprot, pdemask;
+
+ DPRINTF(PDB_FOLLOW|PDB_PMAP,
+ ("pmap_write_protect(%p, %lx, %lx, %x)\n", pmap, sva, eva, prot));
+
+ sva = hppa_trunc_page(sva);
+ tlbprot = pmap_prot(pmap, prot);
+
+ simple_lock(&pmap->pm_lock);
+
+ for (pdemask = 1; sva < eva; sva += PAGE_SIZE) {
+ if (pdemask != (sva & PDE_MASK)) {
+ pdemask = sva & PDE_MASK;
+ if (!(pde = pmap_pde_get(pmap->pm_pdir, sva))) {
+ sva += ~PDE_MASK + 1 - PAGE_SIZE;
+ continue;
+ }
+ }
+ if ((pte = pmap_pte_get(pde, sva))) {
+
+ DPRINTF(PDB_PMAP,
+ ("pmap_write_protect: va=0x%lx pte=0x%lx\n",
+ sva, pte));
+ /*
+ * Determine if mapping is changing.
+ * If not, nothing to do.
+ */
+ if ((pte & PTE_ACC_MASK) == tlbprot)
+ continue;
+
+ pg = PHYS_TO_VM_PAGE(PTE_PAGE(pte));
+ simple_lock(&pg->mdpage.pvh_lock);
+ pg->mdpage.pvh_attrs |= pmap_pvh_attrs(pte);
+ simple_unlock(&pg->mdpage.pvh_lock);
+
+ pmap_pte_flush(pmap, sva, pte);
+ pte &= ~PTE_ACC_MASK;
+ pte |= tlbprot;
+ pmap_pte_set(pde, sva, pte);
+ }
+ }
+
+ simple_unlock(&pmap->pm_lock);
+}
+
+void
+pmap_page_remove(pg)
+ struct vm_page *pg;
+{
+ struct pv_entry *pve, *ppve;
+
+ DPRINTF(PDB_FOLLOW|PDB_PV, ("pmap_page_remove(%p)\n", pg));
+
+ if (pg->mdpage.pvh_list == NULL)
+ return;
+
+ simple_lock(&pg->mdpage.pvh_lock);
+ for (pve = pg->mdpage.pvh_list; pve;
+ pve = (ppve = pve)->pv_next, pmap_pv_free(ppve)) {
+ struct pmap *pmap = pve->pv_pmap;
+ vaddr_t va = pve->pv_va;
+ volatile pt_entry_t *pde;
+ pt_entry_t pte;
+
+ simple_lock(&pmap->pm_lock);
+
+ pde = pmap_pde_get(pmap->pm_pdir, va);
+ pte = pmap_pte_get(pde, va);
+ pg->mdpage.pvh_attrs |= pmap_pvh_attrs(pte);
+
+ pmap_pte_flush(pmap, va, pte);
+ if (pte & PTE_WIRED)
+ pmap->pm_stats.wired_count--;
+ pmap->pm_stats.resident_count--;
+
+ pmap_pte_set(pde, va, 0);
+ simple_unlock(&pmap->pm_lock);
+ }
+ pg->mdpage.pvh_list = NULL;
+ simple_unlock(&pg->mdpage.pvh_lock);
+
+ DPRINTF(PDB_FOLLOW|PDB_PV, ("pmap_page_remove: leaving\n"));
+
+}
+
+void
+pmap_unwire(pmap, va)
+ struct pmap *pmap;
+ vaddr_t va;
+{
+ volatile pt_entry_t *pde;
+ pt_entry_t pte = 0;
+
+ DPRINTF(PDB_FOLLOW|PDB_PMAP, ("pmap_unwire(%p, 0x%lx)\n", pmap, va));
+
+ simple_lock(&pmap->pm_lock);
+ if ((pde = pmap_pde_get(pmap->pm_pdir, va))) {
+ pte = pmap_pte_get(pde, va);
+
+ if (pte & PTE_WIRED) {
+ pte &= ~PTE_WIRED;
+ pmap->pm_stats.wired_count--;
+ pmap_pte_set(pde, va, pte);
+ }
+ }
+ simple_unlock(&pmap->pm_lock);
+
+ DPRINTF(PDB_FOLLOW|PDB_PMAP, ("pmap_unwire: leaving\n"));
+
+#ifdef DIAGNOSTIC
+ if (!pte)
+ panic("pmap_unwire: invalid va 0x%lx", va);
+#endif
+}
+
+boolean_t
+pmap_changebit(struct vm_page *pg, pt_entry_t set, pt_entry_t clear)
+{
+ struct pv_entry *pve;
+ pt_entry_t res;
+
+ DPRINTF(PDB_FOLLOW|PDB_BITS,
+ ("pmap_changebit(%p, %lx, %lx)\n", pg, set, clear));
+
+ simple_lock(&pg->mdpage.pvh_lock);
+ res = pg->mdpage.pvh_attrs = 0;
+ for(pve = pg->mdpage.pvh_list; pve; pve = pve->pv_next) {
+ struct pmap *pmap = pve->pv_pmap;
+ vaddr_t va = pve->pv_va;
+ volatile pt_entry_t *pde;
+ pt_entry_t opte, pte;
+
+ simple_lock(&pmap->pm_lock);
+ if ((pde = pmap_pde_get(pmap->pm_pdir, va))) {
+ opte = pte = pmap_pte_get(pde, va);
+#ifdef PMAPDEBUG
+ if (!pte) {
+ printf("pmap_changebit: zero pte for 0x%lx\n",
+ va);
+ continue;
+ }
+#endif
+ pte &= ~clear;
+ pte |= set;
+ pg->mdpage.pvh_attrs |= pmap_pvh_attrs(pte);
+ res |= pmap_pvh_attrs(opte);
+
+ if (opte != pte) {
+ pmap_pte_flush(pmap, va, opte);
+ pmap_pte_set(pde, va, pte);
+ }
+ }
+ simple_unlock(&pmap->pm_lock);
+ }
+ simple_unlock(&pg->mdpage.pvh_lock);
+
+ return ((res & (clear | set)) != 0);
+}
+
+boolean_t
+pmap_testbit(struct vm_page *pg, pt_entry_t bit)
+{
+ struct pv_entry *pve;
+ pt_entry_t pte;
+
+ DPRINTF(PDB_FOLLOW|PDB_BITS, ("pmap_testbit(%p, %lx)\n", pg, bit));
+
+ simple_lock(&pg->mdpage.pvh_lock);
+ for(pve = pg->mdpage.pvh_list; !(pg->mdpage.pvh_attrs & bit) && pve;
+ pve = pve->pv_next) {
+ simple_lock(&pve->pv_pmap->pm_lock);
+ pte = pmap_vp_find(pve->pv_pmap, pve->pv_va);
+ simple_unlock(&pve->pv_pmap->pm_lock);
+ pg->mdpage.pvh_attrs |= pmap_pvh_attrs(pte);
+ }
+ simple_unlock(&pg->mdpage.pvh_lock);
+
+ return ((pg->mdpage.pvh_attrs & bit) != 0);
+}
+
+boolean_t
+pmap_extract(pmap, va, pap)
+ struct pmap *pmap;
+ vaddr_t va;
+ paddr_t *pap;
+{
+ pt_entry_t pte;
+
+ DPRINTF(PDB_FOLLOW|PDB_EXTRACT, ("pmap_extract(%p, %lx)\n", pmap, va));
+
+ simple_lock(&pmap->pm_lock);
+ pte = pmap_vp_find(pmap, va);
+ simple_unlock(&pmap->pm_lock);
+
+ if (pte) {
+ if (pap)
+ *pap = PTE_PAGE(pte) | (va & PAGE_MASK);
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+void
+pmap_activate(struct proc *p)
+{
+ struct pmap *pmap = p->p_vmspace->vm_map.pmap;
+ struct pcb *pcb = &p->p_addr->u_pcb;
+
+ pcb->pcb_space = pmap->pm_space;
+ pcb->pcb_uva = (vaddr_t)p->p_addr;
+}
+
+void
+pmap_deactivate(struct proc *p)
+{
+
+}
+
+static __inline void
+pmap_flush_page(struct vm_page *pg, int purge)
+{
+ struct pv_entry *pve;
+
+ /* purge cache for all possible mappings for the pa */
+ simple_lock(&pg->mdpage.pvh_lock);
+ for(pve = pg->mdpage.pvh_list; pve; pve = pve->pv_next)
+ if (purge)
+ pdcache(pve->pv_pmap->pm_space, pve->pv_va, PAGE_SIZE);
+ else
+ fdcache(pve->pv_pmap->pm_space, pve->pv_va, PAGE_SIZE);
+ simple_unlock(&pg->mdpage.pvh_lock);
+}
+
+void
+pmap_zero_page(struct vm_page *pg)
+{
+ paddr_t pa = VM_PAGE_TO_PHYS(pg);
+
+ DPRINTF(PDB_FOLLOW|PDB_PHYS, ("pmap_zero_page(%lx)\n", pa));
+
+ pmap_flush_page(pg, 1);
+ bzero((void *)pa, PAGE_SIZE);
+ fdcache(HPPA_SID_KERNEL, pa, PAGE_SIZE);
+}
+
+void
+pmap_copy_page(struct vm_page *srcpg, struct vm_page *dstpg)
+{
+ paddr_t spa = VM_PAGE_TO_PHYS(srcpg);
+ paddr_t dpa = VM_PAGE_TO_PHYS(dstpg);
+ DPRINTF(PDB_FOLLOW|PDB_PHYS, ("pmap_copy_page(%lx, %lx)\n", spa, dpa));
+
+ pmap_flush_page(srcpg, 0);
+ pmap_flush_page(dstpg, 1);
+ bcopy((void *)spa, (void *)dpa, PAGE_SIZE);
+ pdcache(HPPA_SID_KERNEL, spa, PAGE_SIZE);
+ fdcache(HPPA_SID_KERNEL, dpa, PAGE_SIZE);
+}
+
+void
+pmap_kenter_pa(va, pa, prot)
+ vaddr_t va;
+ paddr_t pa;
+ vm_prot_t prot;
+{
+ volatile pt_entry_t *pde;
+ pt_entry_t pte, opte;
+
+ DPRINTF(PDB_FOLLOW|PDB_ENTER,
+ ("pmap_kenter_pa(%lx, %lx, %x)\n", va, pa, prot));
+
+ simple_lock(&pmap->pm_lock);
+
+ if (!(pde = pmap_pde_get(pmap_kernel()->pm_pdir, va)) &&
+ !(pde = pmap_pde_alloc(pmap_kernel(), va, NULL)))
+ panic("pmap_kenter_pa: cannot allocate pde for va=0x%lx", va);
+ opte = pmap_pte_get(pde, va);
+ pte = TLB_PAGE(pa) | PTE_WIRED | PTE_REFTRAP |
+ pmap_prot(pmap_kernel(), prot);
+ if (pa >= 0xf0000000ULL /* TODO (HPPA_IOBEGIN & HPPA_PHYSMAP) */)
+ pte |= PTE_UNCACHABLE | PTE_ORDER;
+ DPRINTF(PDB_ENTER, ("pmap_kenter_pa: pde %p va %lx pte %lx\n",
+ pde, va, pte));
+ pmap_pte_set(pde, va, pte);
+ pmap_kernel()->pm_stats.wired_count++;
+ pmap_kernel()->pm_stats.resident_count++;
+ if (opte)
+ pmap_pte_flush(pmap_kernel(), va, opte);
+
+#ifdef PMAPDEBUG
+ {
+ struct vm_page *pg;
+
+ if (pmap_initialized && (pg = PHYS_TO_VM_PAGE(PTE_PAGE(pte)))) {
+
+ simple_lock(&pg->mdpage.pvh_lock);
+ if (pmap_check_alias(pg->mdpage.pvh_list, va, pte))
+ Debugger();
+ simple_unlock(&pg->mdpage.pvh_lock);
+ }
+ }
+#endif
+ simple_unlock(&pmap->pm_lock);
+
+ DPRINTF(PDB_FOLLOW|PDB_ENTER, ("pmap_kenter_pa: leaving\n"));
+}
+
+void
+pmap_kremove(va, size)
+ vaddr_t va;
+ vsize_t size;
+{
+ struct pv_entry *pve;
+ vaddr_t eva, pdemask;
+ volatile pt_entry_t *pde;
+ pt_entry_t pte;
+ struct vm_page *pg;
+
+ DPRINTF(PDB_FOLLOW|PDB_REMOVE,
+ ("pmap_kremove(%lx, %lx)\n", va, size));
+#ifdef PMAPDEBUG
+ if (va < ptoa(physmem)) {
+ printf("pmap_kremove(%lx, %lx): unmapping physmem\n", va, size);
+ return;
+ }
+#endif
+
+ simple_lock(&pmap->pm_lock);
+
+ for (pdemask = 1, eva = va + size; va < eva; va += PAGE_SIZE) {
+ if (pdemask != (va & PDE_MASK)) {
+ pdemask = va & PDE_MASK;
+ if (!(pde = pmap_pde_get(pmap_kernel()->pm_pdir, va))) {
+ va += ~PDE_MASK + 1 - PAGE_SIZE;
+ continue;
+ }
+ }
+ if (!(pte = pmap_pte_get(pde, va))) {
+#ifdef DEBUG
+ printf("pmap_kremove: unmapping unmapped 0x%lx\n", va);
+#endif
+ continue;
+ }
+
+ pmap_pte_flush(pmap_kernel(), va, pte);
+ pmap_pte_set(pde, va, 0);
+ if (pmap_initialized && (pg = PHYS_TO_VM_PAGE(PTE_PAGE(pte)))) {
+
+ simple_lock(&pg->mdpage.pvh_lock);
+ pg->mdpage.pvh_attrs |= pmap_pvh_attrs(pte);
+ /* just in case we have enter/kenter mismatch */
+ if ((pve = pmap_pv_remove(pg, pmap_kernel(), va)))
+ pmap_pv_free(pve);
+ simple_unlock(&pg->mdpage.pvh_lock);
+ }
+ }
+
+ simple_unlock(&pmap->pm_lock);
+
+ DPRINTF(PDB_FOLLOW|PDB_REMOVE, ("pmap_kremove: leaving\n"));
+}
diff --git a/sys/arch/hppa64/hppa64/process_machdep.c b/sys/arch/hppa64/hppa64/process_machdep.c
new file mode 100644
index 00000000000..564af417d85
--- /dev/null
+++ b/sys/arch/hppa64/hppa64/process_machdep.c
@@ -0,0 +1,116 @@
+/* $OpenBSD: process_machdep.c,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/ptrace.h>
+#include <sys/user.h>
+
+int
+process_read_regs(p, regs)
+ struct proc *p;
+ struct reg *regs;
+{
+ struct trapframe *tf = p->p_md.md_regs;
+
+ regs->r_regs[0] = tf->tf_sar;
+ bcopy(&tf->tf_r1, &regs->r_regs[1], 31*8);
+ regs->r_pc = tf->tf_iioq[0];
+ regs->r_npc = tf->tf_iioq[1];
+
+ return (0);
+}
+
+int
+process_read_fpregs(p, fpregs)
+ struct proc *p;
+ struct fpreg *fpregs;
+{
+ extern paddr_t fpu_curpcb;
+ extern u_int fpu_enable;
+
+ if (p->p_md.md_regs->tf_cr30 == fpu_curpcb) {
+ mtctl(fpu_enable, CR_CCR);
+ fpu_save((vaddr_t)p->p_addr->u_pcb.pcb_fpregs);
+ mtctl(0, CR_CCR);
+ }
+ bcopy(p->p_addr->u_pcb.pcb_fpregs, fpregs, 32*8);
+
+ return (0);
+}
+
+#ifdef PTRACE
+
+int
+process_write_regs(p, regs)
+ struct proc *p;
+ struct reg *regs;
+{
+ struct trapframe *tf = p->p_md.md_regs;
+
+ tf->tf_sar = regs->r_regs[0];
+ bcopy(&regs->r_regs[1], &tf->tf_r1, 31*8);
+ tf->tf_iioq[0] = regs->r_pc | 3;
+ tf->tf_iioq[1] = regs->r_npc | 3;
+
+ return (0);
+}
+
+int
+process_write_fpregs(p, fpregs)
+ struct proc *p;
+ struct fpreg *fpregs;
+{
+ extern paddr_t fpu_curpcb;
+
+ if (p->p_md.md_regs->tf_cr30 == fpu_curpcb) {
+ fpu_exit();
+ fpu_curpcb = 0;
+ }
+
+ bcopy(fpregs, p->p_addr->u_pcb.pcb_fpregs, 32 * 8);
+
+ return (0);
+}
+
+int
+process_sstep(p, sstep)
+ struct proc *p;
+ int sstep;
+{
+ if (sstep)
+ return (EINVAL);
+
+ return (0);
+}
+
+int
+process_set_pc(p, addr)
+ struct proc *p;
+ caddr_t addr;
+{
+ p->p_md.md_regs->tf_iioq[1] = 4 +
+ (p->p_md.md_regs->tf_iioq[0] = (register_t)addr | 3);
+
+ return (0);
+}
+
+#endif /* PTRACE */
diff --git a/sys/arch/hppa64/hppa64/sys_machdep.c b/sys/arch/hppa64/hppa64/sys_machdep.c
new file mode 100644
index 00000000000..d905414aa7c
--- /dev/null
+++ b/sys/arch/hppa64/hppa64/sys_machdep.c
@@ -0,0 +1,58 @@
+/* $OpenBSD: sys_machdep.c,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)sys_machdep.c 8.2 (Berkeley) 1/13/94
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
+
+int
+sys_sysarch(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct sys_sysarch_args /* {
+ syscallarg(int) op;
+ syscallarg(char *) parms;
+ } */ *uap = v;
+ int error = 0;
+
+ switch (SCARG(uap, op)) {
+ default:
+ error = EINVAL;
+ break;
+ }
+ return (error);
+}
diff --git a/sys/arch/hppa64/hppa64/trap.c b/sys/arch/hppa64/hppa64/trap.c
new file mode 100644
index 00000000000..e0046725ad1
--- /dev/null
+++ b/sys/arch/hppa64/hppa64/trap.c
@@ -0,0 +1,723 @@
+/* $OpenBSD: trap.c,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define TRAPDEBUG
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/syscall.h>
+#include <sys/ktrace.h>
+#include <sys/proc.h>
+#include <sys/signalvar.h>
+#include <sys/user.h>
+
+#include <net/netisr.h>
+
+#include "systrace.h"
+#include <dev/systrace.h>
+
+#include <uvm/uvm.h>
+
+#include <machine/autoconf.h>
+#include <machine/psl.h>
+
+#include <machine/db_machdep.h> /* XXX always needed for inst_store() */
+#ifdef DDB
+#ifdef TRAPDEBUG
+#include <ddb/db_output.h>
+#endif
+#endif
+
+const char *trap_type[] = {
+ "invalid",
+ "HPMC",
+ "power failure",
+ "recovery counter",
+ "external interrupt",
+ "LPMC",
+ "ITLB miss fault",
+ "instruction protection",
+ "Illegal instruction",
+ "break instruction",
+ "privileged operation",
+ "privileged register",
+ "overflow",
+ "conditional",
+ "assist exception",
+ "DTLB miss",
+ "ITLB non-access miss",
+ "DTLB non-access miss",
+ "data protection/rights/alignment",
+ "data break",
+ "TLB dirty",
+ "page reference",
+ "assist emulation",
+ "higher-priv transfer",
+ "lower-priv transfer",
+ "taken branch",
+ "data access rights",
+ "data protection",
+ "unaligned data ref",
+};
+int trap_types = sizeof(trap_type)/sizeof(trap_type[0]);
+
+int want_resched, astpending;
+
+#define frame_regmap(tf,r) (((register_t *)(tf))[hppa64_regmap[(r)]])
+u_char hppa64_regmap[32] = {
+ offsetof(struct trapframe, tf_pad[0]) / 8, /* r0 XXX */
+ offsetof(struct trapframe, tf_r1) / 8,
+ offsetof(struct trapframe, tf_rp) / 8,
+ offsetof(struct trapframe, tf_r3) / 8,
+ offsetof(struct trapframe, tf_r4) / 8,
+ offsetof(struct trapframe, tf_r5) / 8,
+ offsetof(struct trapframe, tf_r6) / 8,
+ offsetof(struct trapframe, tf_r7) / 8,
+ offsetof(struct trapframe, tf_r8) / 8,
+ offsetof(struct trapframe, tf_r9) / 8,
+ offsetof(struct trapframe, tf_r10) / 8,
+ offsetof(struct trapframe, tf_r11) / 8,
+ offsetof(struct trapframe, tf_r12) / 8,
+ offsetof(struct trapframe, tf_r13) / 8,
+ offsetof(struct trapframe, tf_r14) / 8,
+ offsetof(struct trapframe, tf_r15) / 8,
+ offsetof(struct trapframe, tf_r16) / 8,
+ offsetof(struct trapframe, tf_r17) / 8,
+ offsetof(struct trapframe, tf_r18) / 8,
+ offsetof(struct trapframe, tf_args[7]) / 8,
+ offsetof(struct trapframe, tf_args[6]) / 8,
+ offsetof(struct trapframe, tf_args[5]) / 8,
+ offsetof(struct trapframe, tf_args[4]) / 8,
+ offsetof(struct trapframe, tf_args[3]) / 8,
+ offsetof(struct trapframe, tf_args[2]) / 8,
+ offsetof(struct trapframe, tf_args[1]) / 8,
+ offsetof(struct trapframe, tf_args[0]) / 8,
+ offsetof(struct trapframe, tf_dp) / 8,
+ offsetof(struct trapframe, tf_ret0) / 8,
+ offsetof(struct trapframe, tf_ret1) / 8,
+ offsetof(struct trapframe, tf_sp) / 8,
+ offsetof(struct trapframe, tf_r31) / 8,
+};
+
+void
+userret(struct proc *p, register_t pc, u_quad_t oticks)
+{
+ int sig;
+
+ /* take pending signals */
+ while ((sig = CURSIG(p)) != 0)
+ postsig(sig);
+
+ p->p_priority = p->p_usrpri;
+ if (astpending) {
+ astpending = 0;
+ if (p->p_flag & P_OWEUPC) {
+ p->p_flag &= ~P_OWEUPC;
+ ADDUPROF(p);
+ }
+ }
+ if (want_resched) {
+ /*
+ * We're being preempted.
+ */
+ preempt(NULL);
+ while ((sig = CURSIG(p)) != 0)
+ postsig(sig);
+ }
+
+ /*
+ * If profiling, charge recent system time to the trapped pc.
+ */
+ if (p->p_flag & P_PROFIL) {
+ extern int psratio;
+
+ addupc_task(p, pc, (int)(p->p_sticks - oticks) * psratio);
+ }
+
+ p->p_cpu->ci_schedstate.spc_curpriority = p->p_priority;
+}
+
+void
+trap(type, frame)
+ int type;
+ struct trapframe *frame;
+{
+ extern int cpl; /* from locore.o */
+ struct proc *p = curproc;
+ vaddr_t va;
+ struct vm_map *map;
+ struct vmspace *vm;
+ register vm_prot_t vftype;
+ register pa_space_t space;
+ union sigval sv;
+ u_int opcode;
+ int ret, trapnum;
+ const char *tts;
+ vm_fault_t fault = VM_FAULT_INVALID;
+#ifdef DIAGNOSTIC
+ long oldcpl;
+#endif
+
+ trapnum = type & ~T_USER;
+ opcode = frame->tf_iir;
+ if (trapnum <= T_EXCEPTION || trapnum == T_HIGHERPL ||
+ trapnum == T_LOWERPL || trapnum == T_TAKENBR ||
+ trapnum == T_IDEBUG || trapnum == T_PERFMON) {
+ va = frame->tf_iioq[0];
+ space = frame->tf_iisq[0];
+ vftype = UVM_PROT_EXEC;
+ } else {
+ va = frame->tf_ior;
+ space = frame->tf_isr;
+ if (va == frame->tf_iioq[0])
+ vftype = UVM_PROT_EXEC;
+ else if (inst_store(opcode))
+ vftype = UVM_PROT_WRITE;
+ else
+ vftype = UVM_PROT_READ;
+ }
+
+ if (frame->tf_flags & TFF_LAST)
+ p->p_md.md_regs = frame;
+
+ if (trapnum > trap_types)
+ tts = "reserved";
+ else
+ tts = trap_type[trapnum];
+
+#ifdef TRAPDEBUG
+ if (trapnum != T_INTERRUPT && trapnum != T_IBREAK)
+ db_printf("trap: %x, %s for %x:%lx at %x:%lx, fl=%x, fp=%p\n",
+ type, tts, space, va, frame->tf_iisq[0],
+ frame->tf_iioq[0], frame->tf_flags, frame);
+ else if (trapnum == T_IBREAK)
+ db_printf("trap: break instruction %x:%x at %x:%lx, fp=%p\n",
+ opcode & 0x1f, (opcode >> 13) & 0x1fff,
+ frame->tf_iisq[0], frame->tf_iioq[0], frame);
+
+ {
+ extern int etext;
+ if (frame < (struct trapframe *)&etext) {
+ printf("trap: bogus frame ptr %p\n", frame);
+ goto dead_end;
+ }
+ }
+#endif
+ if (trapnum != T_INTERRUPT) {
+ uvmexp.traps++;
+ /* TODO mtctl(frame->tf_eiem, CR_EIEM); */
+ }
+
+ switch (type) {
+ case T_NONEXIST:
+ case T_NONEXIST | T_USER:
+ /* we've got screwed up by the central scrutinizer */
+ printf("trap: elvis has just left the building!\n");
+ goto dead_end;
+
+ case T_RECOVERY:
+ case T_RECOVERY | T_USER:
+ /* XXX will implement later */
+ printf("trap: handicapped");
+ goto dead_end;
+
+#ifdef DIAGNOSTIC
+ case T_EXCEPTION:
+ panic("FPU/SFU emulation botch");
+
+ /* these just can't happen ever */
+ case T_PRIV_OP:
+ case T_PRIV_REG:
+ /* these just can't make it to the trap() ever */
+ case T_HPMC:
+ case T_HPMC | T_USER:
+#endif
+ case T_IBREAK:
+ case T_DATALIGN:
+ case T_DBREAK:
+ dead_end:
+#ifdef DDB
+ if (kdb_trap (type, va, frame)) {
+ if (type == T_IBREAK) {
+ /* skip break instruction */
+ frame->tf_iioq[0] = frame->tf_iioq[1];
+ frame->tf_iioq[1] += 4;
+ }
+ return;
+ }
+#else
+ if (type == T_DATALIGN)
+ panic ("trap: %s at 0x%x", tts, va);
+ else
+ panic ("trap: no debugger for \"%s\" (%d)", tts, type);
+#endif
+ break;
+
+ case T_IBREAK | T_USER:
+ case T_DBREAK | T_USER:
+ /* pass to user debugger */
+ trapsignal(p, SIGTRAP, type &~ T_USER, TRAP_BRKPT, sv);
+ break;
+
+ case T_EXCEPTION | T_USER: {
+ u_int64_t *fpp = (u_int64_t *)frame->tf_cr30;
+ u_int32_t *pex;
+ int i, flt;
+
+ pex = (u_int32_t *)&fpp[0];
+ for (i = 0, pex++; i < 7 && !*pex; i++, pex++);
+ flt = 0;
+ if (i < 7) {
+ u_int32_t stat = HPPA_FPU_OP(*pex);
+ if (stat & HPPA_FPU_UNMPL)
+ flt = FPE_FLTINV;
+ else if (stat & (HPPA_FPU_V << 1))
+ flt = FPE_FLTINV;
+ else if (stat & (HPPA_FPU_Z << 1))
+ flt = FPE_FLTDIV;
+ else if (stat & (HPPA_FPU_I << 1))
+ flt = FPE_FLTRES;
+ else if (stat & (HPPA_FPU_O << 1))
+ flt = FPE_FLTOVF;
+ else if (stat & (HPPA_FPU_U << 1))
+ flt = FPE_FLTUND;
+ /* still left: under/over-flow w/ inexact */
+
+ /* cleanup exceptions (XXX deliver all ?) */
+ while (i++ < 7)
+ *pex++ = 0;
+ }
+ /* reset the trap flag, as if there was none */
+ fpp[0] &= ~(((u_int64_t)HPPA_FPU_T) << 32);
+ /* flush out, since load is done from phys, only 4 regs */
+ fdcache(HPPA_SID_KERNEL, (vaddr_t)fpp, 8 * 4);
+
+ sv.sival_int = va;
+ trapsignal(p, SIGFPE, type &~ T_USER, flt, sv);
+ }
+ break;
+
+ case T_EMULATION:
+ panic("trap: emulation trap in the kernel");
+ break;
+
+ case T_EMULATION | T_USER:
+ sv.sival_int = va;
+ trapsignal(p, SIGILL, type &~ T_USER, ILL_COPROC, sv);
+ break;
+
+ case T_OVERFLOW | T_USER:
+ sv.sival_int = va;
+ trapsignal(p, SIGFPE, type &~ T_USER, FPE_INTOVF, sv);
+ break;
+
+ case T_CONDITION | T_USER:
+ sv.sival_int = va;
+ trapsignal(p, SIGFPE, type &~ T_USER, FPE_INTDIV, sv);
+ break;
+
+ case T_PRIV_OP | T_USER:
+ sv.sival_int = va;
+ trapsignal(p, SIGILL, type &~ T_USER, ILL_PRVOPC, sv);
+ break;
+
+ case T_PRIV_REG | T_USER:
+ sv.sival_int = va;
+ trapsignal(p, SIGILL, type &~ T_USER, ILL_PRVREG, sv);
+ break;
+
+ /* these should never got here */
+ case T_HIGHERPL | T_USER:
+ case T_LOWERPL | T_USER:
+ sv.sival_int = va;
+ trapsignal(p, SIGSEGV, vftype, SEGV_ACCERR, sv);
+ break;
+
+ case T_IPROT | T_USER:
+ case T_DPROT | T_USER:
+ sv.sival_int = va;
+ trapsignal(p, SIGSEGV, vftype, SEGV_ACCERR, sv);
+ break;
+
+ case T_ITLBMISSNA:
+ case T_ITLBMISSNA | T_USER:
+ case T_DTLBMISSNA:
+ case T_DTLBMISSNA | T_USER:
+ if (space == HPPA_SID_KERNEL)
+ map = kernel_map;
+ else {
+ vm = p->p_vmspace;
+ map = &vm->vm_map;
+ }
+
+ /* dig probei?,[rw] insns */
+ if ((opcode & 0xfc001f80) == 0x04001180) {
+ int pl;
+
+ if (opcode & 0x2000)
+ pl = (opcode >> 16) & 3;
+ else
+ pl = frame_regmap(frame,
+ (opcode >> 16) & 0x1f) & 3;
+
+ if ((type & T_USER && space == HPPA_SID_KERNEL) ||
+ (type & T_USER && !pl) ||
+ (type & T_USER && va >= VM_MAXUSER_ADDRESS) ||
+ uvm_fault(map, hppa_trunc_page(va), fault,
+ opcode & 0x40? UVM_PROT_WRITE : UVM_PROT_READ)) {
+ frame_regmap(frame, opcode & 0x1f) = 0;
+ frame->tf_ipsw |= PSL_N;
+ }
+ } else if (type & T_USER) {
+ sv.sival_int = va;
+ trapsignal(p, SIGILL, type & ~T_USER, ILL_ILLTRP, sv);
+ } else
+ panic("trap: %s @ 0x%x:0x%x for 0x%x:0x%x irr 0x%08x\n",
+ tts, frame->tf_iisq[0], frame->tf_iioq[0],
+ space, va, opcode);
+ break;
+
+ case T_TLB_DIRTY:
+ case T_TLB_DIRTY | T_USER:
+ case T_DATACC:
+ case T_DATACC | T_USER:
+ fault = VM_FAULT_PROTECT;
+ case T_ITLBMISS:
+ case T_ITLBMISS | T_USER:
+ case T_DTLBMISS:
+ case T_DTLBMISS | T_USER:
+ /*
+ * it could be a kernel map for exec_map faults
+ */
+ if (space == HPPA_SID_KERNEL)
+ map = kernel_map;
+ else {
+ vm = p->p_vmspace;
+ map = &vm->vm_map;
+ }
+
+ /*
+ * user faults out of user addr space are always a fail,
+ * this happens on va >= VM_MAXUSER_ADDRESS, where
+ * space id will be zero and therefore cause
+ * a misbehave lower in the code.
+ *
+ * also check that faulted space id matches the curproc.
+ */
+ if ((type & T_USER && va >= VM_MAXUSER_ADDRESS) ||
+ (type & T_USER && map->pmap->pm_space != space)) {
+ sv.sival_int = va;
+ trapsignal(p, SIGSEGV, vftype, SEGV_ACCERR, sv);
+ break;
+ }
+
+printf("here\n");
+ ret = uvm_fault(map, hppa_trunc_page(va), fault, vftype);
+
+ /*
+ * If this was a stack access we keep track of the maximum
+ * accessed stack size. Also, if uvm_fault gets a protection
+ * failure it is due to accessing the stack region outside
+ * the current limit and we need to reflect that as an access
+ * error.
+ */
+ if (space != HPPA_SID_KERNEL &&
+ va < (vaddr_t)vm->vm_minsaddr) {
+ if (ret == 0)
+ uvm_grow(p, va);
+ else if (ret == EACCES)
+ ret = EFAULT;
+ }
+
+ if (ret != 0) {
+ if (type & T_USER) {
+ sv.sival_int = va;
+ trapsignal(p, SIGSEGV, vftype,
+ ret == EACCES? SEGV_ACCERR : SEGV_MAPERR,
+ sv);
+ } else {
+ if (p && p->p_addr->u_pcb.pcb_onfault) {
+ frame->tf_iioq[1] = 4 +
+ (frame->tf_iioq[0] =
+ p->p_addr->u_pcb.pcb_onfault);
+#ifdef DDB
+ frame->tf_iir = 0;
+#endif
+ } else {
+ panic("trap: "
+ "uvm_fault(%p, %lx, %d, %d): %d",
+ map, va, fault, vftype, ret);
+ }
+ }
+ }
+ break;
+
+ case T_DATALIGN | T_USER:
+ sv.sival_int = va;
+ trapsignal(p, SIGBUS, vftype, BUS_ADRALN, sv);
+ break;
+
+ case T_INTERRUPT:
+ case T_INTERRUPT | T_USER:
+/* cpu_intr(frame); */
+printf("eirr 0x%08x\n", mfctl(CR_EIRR));
+ break;
+
+ case T_CONDITION:
+ panic("trap: divide by zero in the kernel");
+ break;
+
+ case T_ILLEGAL:
+ case T_ILLEGAL | T_USER:
+ /* see if it's a SPOP1,,0 */
+ if ((opcode & 0xfffffe00) == 0x10000200) {
+ frame_regmap(frame, opcode & 0x1f) = 0;
+ frame->tf_ipsw |= PSL_N;
+ break;
+ }
+ if (type & T_USER) {
+ sv.sival_int = va;
+ trapsignal(p, SIGILL, type &~ T_USER, ILL_ILLOPC, sv);
+ break;
+ }
+ /* FALLTHROUGH */
+
+ case T_LOWERPL:
+ case T_DPROT:
+ case T_IPROT:
+ case T_OVERFLOW:
+ case T_HIGHERPL:
+ case T_TAKENBR:
+ case T_POWERFAIL:
+ case T_LPMC:
+ case T_PAGEREF:
+ case T_DATAPID:
+ case T_DATAPID | T_USER:
+ if (0 /* T-chip */) {
+ break;
+ }
+ /* FALLTHROUGH to unimplemented */
+ default:
+#if 1
+if (kdb_trap (type, va, frame))
+ return;
+#endif
+ panic("trap: unimplemented \'%s\' (%d)", tts, trapnum);
+ }
+
+#ifdef DIAGNOSTIC
+ if (cpl != oldcpl)
+ printf("WARNING: SPL (%d) NOT LOWERED ON "
+ "TRAP (%d) EXIT\n", cpl, trapnum);
+#endif
+
+ if (trapnum != T_INTERRUPT)
+ splx(cpl); /* process softints */
+
+ /*
+ * in case we were interrupted from the syscall gate page
+ * treat this as we were not realy running user code no more
+ * for weird things start to happen on return to the userland
+ * and also see a note in locore.S:TLABEL(all)
+ */
+ if ((type & T_USER) &&
+ (frame->tf_iioq[0] & ~PAGE_MASK) != SYSCALLGATE)
+ userret(p, frame->tf_iioq[0], 0);
+}
+
+void
+child_return(arg)
+ void *arg;
+{
+ struct proc *p = (struct proc *)arg;
+ struct trapframe *tf = p->p_md.md_regs;
+
+ /*
+ * Set up return value registers as libc:fork() expects
+ */
+ tf->tf_ret0 = 0;
+ tf->tf_ret1 = 1; /* ischild */
+ tf->tf_r1 = 0; /* errno */
+
+ userret(p, tf->tf_iioq[0], 0);
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_SYSRET))
+ ktrsysret(p, SYS_fork, 0, 0);
+#endif
+}
+
+
+/*
+ * call actual syscall routine
+ */
+void
+syscall(struct trapframe *frame)
+{
+ extern int cpl; /* from locore.o */
+ register struct proc *p = curproc;
+ register const struct sysent *callp;
+ int retq, nsys, code, argsize, argoff, oerror, error;
+ register_t args[8], rval[2];
+#ifdef DIAGNOSTIC
+ long oldcpl;
+#endif
+
+ /* TODO syscall */
+
+ uvmexp.syscalls++;
+
+ if (!USERMODE(frame->tf_iioq[0]))
+ panic("syscall");
+
+ p->p_md.md_regs = frame;
+ nsys = p->p_emul->e_nsysent;
+ callp = p->p_emul->e_sysent;
+
+ argoff = 4; retq = 0;
+ switch (code = frame->tf_r1) {
+ case SYS_syscall:
+ code = frame->tf_args[0];
+ args[0] = frame->tf_args[1];
+ args[1] = frame->tf_args[2];
+ args[2] = frame->tf_args[3];
+ argoff = 3;
+ break;
+ case SYS___syscall:
+ if (callp != sysent)
+ break;
+ /*
+ * this works, because quads get magically swapped
+ * due to the args being laid backwards on the stack
+ * and then copied in words
+ */
+ code = frame->tf_args[0];
+ args[0] = frame->tf_args[2];
+ args[1] = frame->tf_args[3];
+ argoff = 2;
+ retq = 1;
+ break;
+ default:
+ args[0] = frame->tf_args[0];
+ args[1] = frame->tf_args[1];
+ args[2] = frame->tf_args[2];
+ args[3] = frame->tf_args[3];
+ break;
+ }
+
+ if (code < 0 || code >= nsys)
+ callp += p->p_emul->e_nosys; /* bad syscall # */
+ else
+ callp += code;
+
+ oerror = error = 0;
+ if ((argsize = callp->sy_argsize)) {
+ int i;
+
+/* TODO syscallargs */
+
+ /*
+ * coming from syscall() or __syscall we must be
+ * having one of those w/ a 64 bit arguments,
+ * which needs a word swap due to the order
+ * of the arguments on the stack.
+ * this assumes that none of 'em are called
+ * by their normal syscall number, maybe a regress
+ * test should be used, to watch the behaviour.
+ */
+ if (!error && argoff < 4) {
+ int t;
+
+ i = 0;
+ switch (code) {
+ case SYS_lseek: retq = 0;
+ case SYS_truncate:
+ case SYS_ftruncate: i = 2; break;
+ case SYS_preadv:
+ case SYS_pwritev:
+ case SYS_pread:
+ case SYS_pwrite: i = 4; break;
+ case SYS_mmap: i = 6; break;
+ }
+
+ if (i) {
+ t = args[i];
+ args[i] = args[i + 1];
+ args[i + 1] = t;
+ }
+ }
+ }
+
+#ifdef SYSCALL_DEBUG
+ scdebug_call(p, code, args);
+#endif
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_SYSCALL))
+ ktrsyscall(p, code, callp->sy_argsize, args);
+#endif
+ if (error)
+ goto bad;
+
+ rval[0] = 0;
+ rval[1] = frame->tf_ret1;
+#if NSYSTRACE > 0
+ if (ISSET(p->p_flag, P_SYSTRACE))
+ oerror = error = systrace_redirect(code, p, args, rval);
+ else
+#endif
+ oerror = error = (*callp->sy_call)(p, args, rval);
+ p = curproc;
+ frame = p->p_md.md_regs;
+ switch (error) {
+ case 0:
+ frame->tf_ret0 = rval[0];
+ frame->tf_ret1 = rval[!retq];
+ frame->tf_r1 = 0;
+ break;
+ case ERESTART:
+ frame->tf_iioq[0] -= 12;
+ frame->tf_iioq[1] -= 12;
+ case EJUSTRETURN:
+ break;
+ default:
+ bad:
+ if (p->p_emul->e_errno)
+ error = p->p_emul->e_errno[error];
+ frame->tf_r1 = error;
+ frame->tf_ret0 = error;
+ frame->tf_ret1 = 0;
+ break;
+ }
+#ifdef SYSCALL_DEBUG
+ scdebug_ret(p, code, oerror, rval);
+#endif
+ userret(p, frame->tf_iioq[1], 0);
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_SYSRET))
+ ktrsysret(p, code, oerror, rval[0]);
+#endif
+#ifdef DIAGNOSTIC
+ if (cpl != oldcpl) {
+ printf("WARNING: SPL (0x%x) NOT LOWERED ON "
+ "syscall(0x%x, 0x%x, 0x%x, 0x%x...) EXIT, PID %d\n",
+ cpl, code, args[0], args[1], args[2], p->p_pid);
+ cpl = oldcpl;
+ }
+#endif
+ splx(cpl); /* process softints */
+}
diff --git a/sys/arch/hppa64/hppa64/vm_machdep.c b/sys/arch/hppa64/hppa64/vm_machdep.c
new file mode 100644
index 00000000000..53700d03818
--- /dev/null
+++ b/sys/arch/hppa64/hppa64/vm_machdep.c
@@ -0,0 +1,307 @@
+/* $OpenBSD: vm_machdep.c,v 1.1 2005/04/01 10:40:47 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/signalvar.h>
+#include <sys/malloc.h>
+#include <sys/buf.h>
+#include <sys/vnode.h>
+#include <sys/user.h>
+#include <sys/ptrace.h>
+#include <sys/exec.h>
+#include <sys/core.h>
+
+#include <machine/psl.h>
+#include <machine/pmap.h>
+#include <machine/pcb.h>
+
+#include <uvm/uvm.h>
+
+
+/*
+ * Dump the machine specific header information at the start of a core dump.
+ */
+int
+cpu_coredump(p, vp, cred, core)
+ struct proc *p;
+ struct vnode *vp;
+ struct ucred *cred;
+ struct core *core;
+{
+ struct md_coredump md_core;
+ struct coreseg cseg;
+ off_t off;
+ int error;
+
+ CORE_SETMAGIC(*core, COREMAGIC, MID_HPPA20, 0);
+ core->c_hdrsize = ALIGN(sizeof(*core));
+ core->c_seghdrsize = ALIGN(sizeof(cseg));
+ core->c_cpusize = sizeof(md_core);
+
+ process_read_regs(p, &md_core.md_reg);
+ process_read_fpregs(p, &md_core.md_fpreg);
+
+ CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_HPPA20, CORE_CPU);
+ cseg.c_addr = 0;
+ cseg.c_size = core->c_cpusize;
+
+#define write(vp, addr, n) \
+ vn_rdwr(UIO_WRITE, (vp), (caddr_t)(addr), (n), off, \
+ UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, NULL, p)
+
+ off = core->c_hdrsize;
+ if ((error = write(vp, &cseg, core->c_seghdrsize)))
+ return error;
+ off += core->c_seghdrsize;
+ if ((error = write(vp, &md_core, sizeof md_core)))
+ return error;
+
+#undef write
+ core->c_nseg++;
+
+ return error;
+}
+
+/*
+ * Move pages from one kernel virtual address to another.
+ * Both addresses are assumed to reside in the Sysmap.
+ */
+void
+pagemove(from, to, size)
+ register caddr_t from, to;
+ size_t size;
+{
+ paddr_t pa;
+
+ while (size > 0) {
+ if (pmap_extract(pmap_kernel(), (vaddr_t)from, &pa) == FALSE)
+ panic("pagemove");
+ pmap_kremove((vaddr_t)from, PAGE_SIZE);
+ pmap_kenter_pa((vaddr_t)to, pa, UVM_PROT_RW);
+ from += PAGE_SIZE;
+ to += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
+ pmap_update(pmap_kernel());
+}
+
+void
+cpu_swapin(p)
+ struct proc *p;
+{
+ struct trapframe *tf = p->p_md.md_regs;
+ paddr_t pa;
+
+ /*
+ * Stash the physical for the pcb of U for later perusal
+ */
+ if (!pmap_extract(pmap_kernel(), (vaddr_t)p->p_addr, &pa))
+ panic("pmap_extract(%p) failed", p->p_addr);
+
+ tf->tf_cr30 = pa;
+}
+
+void
+cpu_swapout(p)
+ struct proc *p;
+{
+ extern paddr_t fpu_curpcb; /* from locore.S */
+ extern u_int fpu_enable;
+ struct trapframe *tf = p->p_md.md_regs;
+
+ if (tf->tf_cr30 == fpu_curpcb) {
+ mtctl(fpu_enable, CR_CCR);
+ fpu_save(fpu_curpcb);
+ fpu_curpcb = 0;
+ mtctl(0, CR_CCR);
+ }
+}
+
+void
+cpu_fork(p1, p2, stack, stacksize, func, arg)
+ struct proc *p1, *p2;
+ void *stack;
+ size_t stacksize;
+ void (*func)(void *);
+ void *arg;
+{
+ extern paddr_t fpu_curpcb; /* from locore.S */
+ extern u_int fpu_enable;
+ struct pcb *pcbp;
+ struct trapframe *tf;
+ register_t sp, osp;
+
+#ifdef DIAGNOSTIC
+ if (round_page(sizeof(struct user) + sizeof(*tf)) > PAGE_SIZE)
+ panic("USPACE too small for user");
+#endif
+ if (p1->p_md.md_regs->tf_cr30 == fpu_curpcb) {
+ mtctl(fpu_enable, CR_CCR);
+ fpu_save(fpu_curpcb);
+ mtctl(0, CR_CCR);
+ }
+
+ pcbp = &p2->p_addr->u_pcb;
+ bcopy(&p1->p_addr->u_pcb, pcbp, sizeof(*pcbp));
+ /* space is cached for the copy{in,out}'s pleasure */
+ pcbp->pcb_space = p2->p_vmspace->vm_map.pmap->pm_space;
+ pcbp->pcb_uva = (vaddr_t)p2->p_addr;
+ /* reset any of the pending FPU exceptions from parent */
+ pcbp->pcb_fpregs[0] = HPPA_FPU_FORK(pcbp->pcb_fpregs[0]);
+ pcbp->pcb_fpregs[1] = 0;
+ pcbp->pcb_fpregs[2] = 0;
+ pcbp->pcb_fpregs[3] = 0;
+ fdcache(HPPA_SID_KERNEL, (vaddr_t)&pcbp->pcb_fpregs[0], 8 * 4);
+
+ sp = (register_t)p2->p_addr + PAGE_SIZE;
+ p2->p_md.md_regs = tf = (struct trapframe *)sp;
+ sp += sizeof(struct trapframe);
+ bcopy(p1->p_md.md_regs, tf, sizeof(*tf));
+
+ /*
+ * cpu_swapin() is supposed to fill out all the PAs
+ * we gonna need in locore
+ */
+ cpu_swapin(p2);
+
+ tf->tf_sr0 = tf->tf_sr1 = tf->tf_sr2 = tf->tf_sr3 =
+ tf->tf_sr4 = tf->tf_sr5 = tf->tf_sr6 =
+ tf->tf_iisq[0] = tf->tf_iisq[1] =
+ p2->p_vmspace->vm_map.pmap->pm_space;
+ tf->tf_pidr1 = tf->tf_pidr2 = pmap_sid2pid(tf->tf_sr0);
+
+ /*
+ * theoretically these could be inherited from the father,
+ * but just in case.
+ */
+ tf->tf_sr7 = HPPA_SID_KERNEL;
+ tf->tf_eiem = mfctl(CR_EIEM);
+ tf->tf_ipsw = PSL_C | PSL_Q | PSL_P | PSL_D | PSL_I /* | PSL_L */;
+
+ /*
+ * If specified, give the child a different stack.
+ */
+ if (stack != NULL)
+ tf->tf_sp = (register_t)stack;
+
+ /*
+ * Build stack frames for the cpu_switch & co.
+ */
+ osp = sp + HPPA_FRAME_SIZE;
+ *(register_t*)(osp - HPPA_FRAME_SIZE) = 0;
+ *(register_t*)(osp + HPPA_FRAME_RP) = (register_t)&switch_trampoline;
+ *(register_t*)(osp) = (osp - HPPA_FRAME_SIZE);
+
+ sp = osp + HPPA_FRAME_SIZE + 20*8; /* frame + calee-save registers */
+ *(register_t*)(sp - HPPA_FRAME_SIZE + 0) = (register_t)arg;
+ *(register_t*)(sp - HPPA_FRAME_SIZE + 8) = KERNMODE(func);
+ *(register_t*)(sp - HPPA_FRAME_SIZE + 16) = 0; /* cpl */
+ pcbp->pcb_ksp = sp;
+ fdcache(HPPA_SID_KERNEL, (vaddr_t)p2->p_addr, sp - (vaddr_t)p2->p_addr);
+}
+
+void
+cpu_exit(p)
+ struct proc *p;
+{
+ extern paddr_t fpu_curpcb; /* from locore.S */
+ struct trapframe *tf = p->p_md.md_regs;
+
+ if (fpu_curpcb == tf->tf_cr30) {
+ fpu_exit();
+ fpu_curpcb = 0;
+ }
+
+ exit2(p);
+ cpu_switch(p);
+}
+
+void
+cpu_wait(p)
+ struct proc *p;
+{
+}
+
+/*
+ * Map an IO request into kernel virtual address space.
+ */
+void
+vmapbuf(bp, len)
+ struct buf *bp;
+ vsize_t len;
+{
+ struct pmap *pm = vm_map_pmap(&bp->b_proc->p_vmspace->vm_map);
+ vaddr_t kva, uva;
+ vsize_t size, off;
+
+#ifdef DIAGNOSTIC
+ if ((bp->b_flags & B_PHYS) == 0)
+ panic("vmapbuf");
+#endif
+ bp->b_saveaddr = bp->b_data;
+ uva = trunc_page((vaddr_t)bp->b_data);
+ off = (vaddr_t)bp->b_data - uva;
+ size = round_page(off + len);
+
+ /*
+ * We do it on our own here to be able to specify an offset to uvm_map
+ * so that we can get all benefits of PMAP_PREFER.
+ * - art@
+ */
+ kva = uvm_km_valloc_prefer_wait(kernel_map, size, uva);
+ fdcache(pm->pm_space, uva, size);
+ bp->b_data = (caddr_t)(kva + off);
+ while (size > 0) {
+ paddr_t pa;
+
+ if (pmap_extract(pm, uva, &pa) == FALSE)
+ panic("vmapbuf: null page frame");
+ else
+ pmap_kenter_pa(kva, pa, UVM_PROT_RW);
+ uva += PAGE_SIZE;
+ kva += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
+ pmap_update(pmap_kernel());
+}
+
+/*
+ * Unmap IO request from the kernel virtual address space.
+ */
+void
+vunmapbuf(bp, len)
+ struct buf *bp;
+ vsize_t len;
+{
+ vaddr_t addr, off;
+
+#ifdef DIAGNOSTIC
+ if ((bp->b_flags & B_PHYS) == 0)
+ panic("vunmapbuf");
+#endif
+ addr = trunc_page((vaddr_t)bp->b_data);
+ off = (vaddr_t)bp->b_data - addr;
+ len = round_page(off + len);
+ uvm_km_free_wakeup(kernel_map, addr, len);
+ bp->b_data = bp->b_saveaddr;
+ bp->b_saveaddr = NULL;
+}
diff --git a/sys/arch/hppa64/hppa64/wscons_machdep.c b/sys/arch/hppa64/hppa64/wscons_machdep.c
new file mode 100644
index 00000000000..a491c5fbd04
--- /dev/null
+++ b/sys/arch/hppa64/hppa64/wscons_machdep.c
@@ -0,0 +1,81 @@
+/* $OpenBSD: wscons_machdep.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/conf.h>
+
+#include <dev/cons.h>
+
+#include "wsdisplay.h"
+#if NWSDISPLAY > 0
+#include <dev/wscons/wsdisplayvar.h>
+#endif
+
+#include "wskbd.h"
+#if NWSKBD > 0
+#include <dev/wscons/wskbdvar.h>
+#endif
+
+cons_decl(ws);
+
+void
+wscnprobe(struct consdev *cp)
+{
+ /*
+ * Due to various device probe restrictions, the wscons console
+ * can never be enabled early during boot.
+ * It will be enabled as soon as enough wscons components get
+ * attached.
+ * So do nothing there, the switch will occur in
+ * wsdisplay_emul_attach() later.
+ */
+}
+
+void
+wscninit(struct consdev *cp)
+{
+}
+
+void
+wscnputc(dev_t dev, int i)
+{
+#if NWSDISPLAY > 0
+ wsdisplay_cnputc(dev, i);
+#endif
+}
+
+int
+wscngetc(dev_t dev)
+{
+#if NWSKBD > 0
+ return (wskbd_cngetc(dev));
+#else
+ return (0);
+#endif
+}
+
+void
+wscnpollc(dev_t dev, int on)
+{
+#if NWSKBD > 0
+ wskbd_cnpollc(dev, on);
+#endif
+}
diff --git a/sys/arch/hppa64/include/ansi.h b/sys/arch/hppa64/include/ansi.h
new file mode 100644
index 00000000000..7e0df957749
--- /dev/null
+++ b/sys/arch/hppa64/include/ansi.h
@@ -0,0 +1,79 @@
+/* $OpenBSD: ansi.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)ansi.h 8.2 (Berkeley) 1/4/94
+ */
+
+#ifndef _MACHINE_ANSI_H_
+#define _MACHINE_ANSI_H_
+
+/*
+ * Types which are fundamental to the implementation and may appear in
+ * more than one standard header are defined here. Standard headers
+ * then use:
+ * #ifdef _BSD_SIZE_T_
+ * typedef _BSD_SIZE_T_ size_t;
+ * #undef _BSD_SIZE_T_
+ * #endif
+ */
+#define _BSD_CLOCK_T_ int /* clock() */
+#define _BSD_PTRDIFF_T_ long int /* ptr1 - ptr2 */
+#define _BSD_SIZE_T_ long unsigned int /* sizeof() */
+#define _BSD_SSIZE_T_ long int /* byte count or error */
+#define _BSD_TIME_T_ int /* time() */
+#define _BSD_VA_LIST_ __builtin_va_list
+#define _BSD_CLOCKID_T_ int
+#define _BSD_TIMER_T_ int
+
+/*
+ * Runes (wchar_t) is declared to be an ``int'' instead of the more natural
+ * ``unsigned long'' or ``long''. Two things are happening here. It is not
+ * unsigned so that EOF (-1) can be naturally assigned to it and used. Also,
+ * it looks like 10646 will be a 31 bit standard. This means that if your
+ * ints cannot hold 32 bits, you will be in trouble. The reason an int was
+ * chosen over a long is that the is*() and to*() routines take ints (says
+ * ANSI C), but they use _RUNE_T_ instead of int. By changing it here, you
+ * lose a bit of ANSI conformance, but your programs will still work.
+ *
+ * Note that _WCHAR_T_ and _RUNE_T_ must be of the same type. When wchar_t
+ * and rune_t are typedef'd, _WCHAR_T_ will be undef'd, but _RUNE_T remains
+ * defined for ctype.h.
+ */
+#define _BSD_WCHAR_T_ int /* wchar_t */
+#define _BSD_WINT_T_ int /* wint_t */
+#define _BSD_RUNE_T_ int /* rune_t */
+
+/*
+ * We describe off_t here so its declaration can be visible to
+ * stdio without pulling in all of <sys/type.h>, thus appeasing ANSI.
+ */
+#define _BSD_OFF_T_ long long /* file offset */
+
+#endif /* _MACHINE_ANSI_H_ */
diff --git a/sys/arch/hppa64/include/asm.h b/sys/arch/hppa64/include/asm.h
new file mode 100644
index 00000000000..ed1ca9acafe
--- /dev/null
+++ b/sys/arch/hppa64/include/asm.h
@@ -0,0 +1,70 @@
+/* $OpenBSD: asm.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 1990,1991,1994 The University of Utah and
+ * the Computer Systems Laboratory (CSL). All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software is hereby
+ * granted provided that (1) source code retains these copyright, permission,
+ * and disclaimer notices, and (2) redistributions including binaries
+ * reproduce the notices in supporting documentation, and (3) all advertising
+ * materials mentioning features or use of this software display the following
+ * acknowledgement: ``This product includes software developed by the
+ * Computer Systems Laboratory at the University of Utah.''
+ *
+ * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
+ * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
+ * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * CSL requests users of this software to return to csl-dist@cs.utah.edu any
+ * improvements that they make and grant CSL redistribution rights.
+ *
+ * Utah $Hdr: asm.h 1.8 94/12/14$
+ */
+
+#ifndef _MACHINE_ASM_H_
+#define _MACHINE_ASM_H_
+
+/*
+ * hppa assembler definitions
+ */
+
+arg7 .reg %r19
+arg6 .reg %r20
+arg5 .reg %r21
+arg4 .reg %r22
+ap .reg %r29
+
+#ifdef __STDC__
+#define __CONCAT(a,b) a ## b
+#else
+#define __CONCAT(a,b) a/**/b
+#endif
+
+#ifdef PROF
+#define _PROF_PROLOGUE \
+ stw %rp, HPPA_FRAME_CRP(%sr0,%sp) !\
+ ldil L%_mcount,%r1 !\
+ ble R%_mcount(%sr0,%r1) !\
+ ldo HPPA_FRAME_SIZE(%sp),%sp !\
+ ldw PPA_FRAME_CRP(%sr0,%sp),%rp
+#else
+#define _PROF_PROLOGUE
+#endif
+
+#define LEAF_ENTRY(x) ! .text ! .align 4 !\
+ .export x, entry ! .label x ! .proc !\
+ .callinfo frame=0,no_calls,save_rp !\
+ .entry ! _PROF_PROLOGUE
+
+#define ENTRY(x,n) ! .text ! .align 4 !\
+ .export x, entry ! .label x ! .proc !\
+ .callinfo frame=n,calls, save_rp, save_sp !\
+ .entry ! _PROF_PROLOGUE
+
+#define ALTENTRY(x) ! .export x, entry ! .label x
+#define EXIT(x) ! .exit ! .procend ! .size x, .-x
+
+#define BSS(n,s) ! .data ! .label n ! .comm s
+
+#endif /* _MACHINE_ASM_H_ */
diff --git a/sys/arch/hppa64/include/autoconf.h b/sys/arch/hppa64/include/autoconf.h
new file mode 100644
index 00000000000..2d40eb5e236
--- /dev/null
+++ b/sys/arch/hppa64/include/autoconf.h
@@ -0,0 +1,53 @@
+/* $OpenBSD: autoconf.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <machine/bus.h>
+#include <machine/pdc.h>
+
+struct confargs {
+ const char *ca_name; /* device name/description */
+ struct iodc_data ca_type; /* iodc-specific type descrition */
+ bus_space_tag_t ca_iot; /* io tag */
+ bus_dma_tag_t ca_dmatag; /* DMA tag */
+ hppa_hpa_t ca_hpa; /* module HPA */
+ u_int ca_hpasz; /* module HPA size (if avail) */
+};
+
+/* this is used for hppa_knownmodules table
+ * describing known to this port modules,
+ * system boards, cpus, fpus and busses
+ */
+struct hppa_mod_info {
+ int mi_type;
+ int mi_sv;
+ const char *mi_name;
+};
+
+extern void (*cold_hook)(int);
+#define HPPA_COLD_COLD 0
+#define HPPA_COLD_HOT 1
+#define HPPA_COLD_OFF 2
+
+struct device;
+
+const char *hppa_mod_info(int, int);
+void pdc_patscan(struct device *, struct confargs *, int);
+int mbprint(void *, const char *);
+
+void dumpconf(void);
diff --git a/sys/arch/hppa64/include/bus.h b/sys/arch/hppa64/include/bus.h
new file mode 100644
index 00000000000..bfd7606dbaf
--- /dev/null
+++ b/sys/arch/hppa64/include/bus.h
@@ -0,0 +1,410 @@
+/* $OpenBSD: bus.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _MACHINE_BUS_H_
+#define _MACHINE_BUS_H_
+
+/* addresses in bus space */
+typedef u_long bus_addr_t;
+typedef u_long bus_size_t;
+
+/* access methods for bus space */
+typedef u_long bus_space_handle_t;
+
+struct hppa64_bus_space_tag {
+ void *hbt_cookie;
+
+ int (*hbt_map)(void *v, bus_addr_t addr, bus_size_t size,
+ int flags, bus_space_handle_t *bshp);
+ void (*hbt_unmap)(void *v, bus_space_handle_t bsh, bus_size_t size);
+ int (*hbt_subregion)(void *v, bus_space_handle_t bsh,
+ bus_size_t offset, bus_size_t size,
+ bus_space_handle_t *nbshp);
+ int (*hbt_alloc)(void *v, bus_addr_t rstart, bus_addr_t rend,
+ bus_size_t size, bus_size_t align, bus_size_t boundary,
+ int flags, bus_addr_t *addrp, bus_space_handle_t *bshp);
+ void (*hbt_free)(void *, bus_space_handle_t, bus_size_t);
+ void (*hbt_barrier)(void *v, bus_space_handle_t h,
+ bus_size_t o, bus_size_t l, int op);
+ u_int8_t (*hbt_r1)(void *, bus_space_handle_t, bus_size_t);
+ u_int16_t (*hbt_r2)(void *, bus_space_handle_t, bus_size_t);
+ u_int32_t (*hbt_r4)(void *, bus_space_handle_t, bus_size_t);
+ u_int64_t (*hbt_r8)(void *, bus_space_handle_t, bus_size_t);
+
+ void (*hbt_w1)(void *, bus_space_handle_t, bus_size_t, u_int8_t);
+ void (*hbt_w2)(void *, bus_space_handle_t, bus_size_t, u_int16_t);
+ void (*hbt_w4)(void *, bus_space_handle_t, bus_size_t, u_int32_t);
+ void (*hbt_w8)(void *, bus_space_handle_t, bus_size_t, u_int64_t);
+
+ void (*hbt_rm_1)(void *v, bus_space_handle_t h,
+ bus_size_t o, u_int8_t *a, bus_size_t c);
+ void (*hbt_rm_2)(void *v, bus_space_handle_t h,
+ bus_size_t o, u_int16_t *a, bus_size_t c);
+ void (*hbt_rm_4)(void *v, bus_space_handle_t h,
+ bus_size_t o, u_int32_t *a, bus_size_t c);
+ void (*hbt_rm_8)(void *v, bus_space_handle_t h,
+ bus_size_t o, u_int64_t *a, bus_size_t c);
+
+ void (*hbt_wm_1)(void *v, bus_space_handle_t h, bus_size_t o,
+ const u_int8_t *a, bus_size_t c);
+ void (*hbt_wm_2)(void *v, bus_space_handle_t h, bus_size_t o,
+ const u_int16_t *a, bus_size_t c);
+ void (*hbt_wm_4)(void *v, bus_space_handle_t h, bus_size_t o,
+ const u_int32_t *a, bus_size_t c);
+ void (*hbt_wm_8)(void *v, bus_space_handle_t h, bus_size_t o,
+ const u_int64_t *a, bus_size_t c);
+
+ void (*hbt_sm_1)(void *v, bus_space_handle_t h, bus_size_t o,
+ u_int8_t vv, bus_size_t c);
+ void (*hbt_sm_2)(void *v, bus_space_handle_t h, bus_size_t o,
+ u_int16_t vv, bus_size_t c);
+ void (*hbt_sm_4)(void *v, bus_space_handle_t h, bus_size_t o,
+ u_int32_t vv, bus_size_t c);
+ void (*hbt_sm_8)(void *v, bus_space_handle_t h, bus_size_t o,
+ u_int64_t vv, bus_size_t c);
+
+ void (*hbt_rrm_2)(void *v, bus_space_handle_t h,
+ bus_size_t o, u_int8_t *a, bus_size_t c);
+ void (*hbt_rrm_4)(void *v, bus_space_handle_t h,
+ bus_size_t o, u_int8_t *a, bus_size_t c);
+ void (*hbt_rrm_8)(void *v, bus_space_handle_t h,
+ bus_size_t o, u_int8_t *a, bus_size_t c);
+
+ void (*hbt_wrm_2)(void *v, bus_space_handle_t h,
+ bus_size_t o, const u_int8_t *a, bus_size_t c);
+ void (*hbt_wrm_4)(void *v, bus_space_handle_t h,
+ bus_size_t o, const u_int8_t *a, bus_size_t c);
+ void (*hbt_wrm_8)(void *v, bus_space_handle_t h,
+ bus_size_t o, const u_int8_t *a, bus_size_t c);
+
+ void (*hbt_rr_1)(void *v, bus_space_handle_t h,
+ bus_size_t o, u_int8_t *a, bus_size_t c);
+ void (*hbt_rr_2)(void *v, bus_space_handle_t h,
+ bus_size_t o, u_int16_t *a, bus_size_t c);
+ void (*hbt_rr_4)(void *v, bus_space_handle_t h,
+ bus_size_t o, u_int32_t *a, bus_size_t c);
+ void (*hbt_rr_8)(void *v, bus_space_handle_t h,
+ bus_size_t o, u_int64_t *a, bus_size_t c);
+
+ void (*hbt_wr_1)(void *v, bus_space_handle_t h,
+ bus_size_t o, const u_int8_t *a, bus_size_t c);
+ void (*hbt_wr_2)(void *v, bus_space_handle_t h,
+ bus_size_t o, const u_int16_t *a, bus_size_t c);
+ void (*hbt_wr_4)(void *v, bus_space_handle_t h,
+ bus_size_t o, const u_int32_t *a, bus_size_t c);
+ void (*hbt_wr_8)(void *v, bus_space_handle_t h,
+ bus_size_t o, const u_int64_t *a, bus_size_t c);
+
+ void (*hbt_rrr_2)(void *v, bus_space_handle_t h,
+ bus_size_t o, u_int8_t *a, bus_size_t c);
+ void (*hbt_rrr_4)(void *v, bus_space_handle_t h,
+ bus_size_t o, u_int8_t *a, bus_size_t c);
+ void (*hbt_rrr_8)(void *v, bus_space_handle_t h,
+ bus_size_t o, u_int8_t *a, bus_size_t c);
+
+ void (*hbt_wrr_2)(void *v, bus_space_handle_t h,
+ bus_size_t o, const u_int8_t *a, bus_size_t c);
+ void (*hbt_wrr_4)(void *v, bus_space_handle_t h,
+ bus_size_t o, const u_int8_t *a, bus_size_t c);
+ void (*hbt_wrr_8)(void *v, bus_space_handle_t h,
+ bus_size_t o, const u_int8_t *a, bus_size_t c);
+
+ void (*hbt_sr_1)(void *v, bus_space_handle_t h,
+ bus_size_t o, u_int8_t vv, bus_size_t c);
+ void (*hbt_sr_2)(void *v, bus_space_handle_t h,
+ bus_size_t o, u_int16_t vv, bus_size_t c);
+ void (*hbt_sr_4)(void *v, bus_space_handle_t h,
+ bus_size_t o, u_int32_t vv, bus_size_t c);
+ void (*hbt_sr_8)(void *v, bus_space_handle_t h,
+ bus_size_t o, u_int64_t vv, bus_size_t c);
+
+ void (*hbt_cp_1)(void *v, bus_space_handle_t h1, bus_size_t o1,
+ bus_space_handle_t h2, bus_size_t o2, bus_size_t c);
+ void (*hbt_cp_2)(void *v, bus_space_handle_t h1, bus_size_t o1,
+ bus_space_handle_t h2, bus_size_t o2, bus_size_t c);
+ void (*hbt_cp_4)(void *v, bus_space_handle_t h1, bus_size_t o1,
+ bus_space_handle_t h2, bus_size_t o2, bus_size_t c);
+ void (*hbt_cp_8)(void *v, bus_space_handle_t h1, bus_size_t o1,
+ bus_space_handle_t h2, bus_size_t o2, bus_size_t c);
+};
+typedef struct hppa64_bus_space_tag *bus_space_tag_t;
+
+/* flags for bus space map functions */
+#define BUS_SPACE_MAP_CACHEABLE 0x0001
+#define BUS_SPACE_MAP_LINEAR 0x0002
+#define BUS_SPACE_MAP_READONLY 0x0004
+#define BUS_SPACE_MAP_PREFETCHABLE 0x0008
+
+/* bus access routines */
+
+#define bus_space_map(t,a,c,ca,hp) \
+ (((t)->hbt_map)((t)->hbt_cookie,(a),(c),(ca),(hp)))
+#define bus_space_unmap(t,h,c) \
+ (((t)->hbt_unmap)((t)->hbt_cookie,(h),(c)))
+#define bus_space_subregion(t,h,o,c,hp) \
+ (((t)->hbt_subregion)((t)->hbt_cookie,(h),(o),(c),(hp)))
+#define bus_space_alloc(t,b,e,c,al,bn,ca,ap,hp) \
+ (((t)->hbt_alloc)((t)->hbt_cookie,(b),(e),(c),(al),(bn),(ca),(ap),(hp)))
+#define bus_space_free(t,h,c) \
+ (((t)->hbt_free)((t)->hbt_cookie,(h),(c)))
+
+#define BUS_SPACE_BARRIER_READ 0
+#define BUS_SPACE_BARRIER_WRITE 1
+
+#define bus_space_barrier(t,h,o,l,op) \
+ ((t)->hbt_barrier((t)->hbt_cookie, (h), (o), (l), (op)))
+#define bus_space_vaddr(t,h) ((vaddr_t)(h))
+
+#define bus_space_read_1(t,h,o) (((t)->hbt_r1)((t)->hbt_cookie,(h),(o)))
+#define bus_space_read_2(t,h,o) (((t)->hbt_r2)((t)->hbt_cookie,(h),(o)))
+#define bus_space_read_4(t,h,o) (((t)->hbt_r4)((t)->hbt_cookie,(h),(o)))
+#define bus_space_read_8(t,h,o) (((t)->hbt_r8)((t)->hbt_cookie,(h),(o)))
+
+#define bus_space_write_1(t,h,o,v) (((t)->hbt_w1)((t)->hbt_cookie,(h),(o),(v)))
+#define bus_space_write_2(t,h,o,v) (((t)->hbt_w2)((t)->hbt_cookie,(h),(o),(v)))
+#define bus_space_write_4(t,h,o,v) (((t)->hbt_w4)((t)->hbt_cookie,(h),(o),(v)))
+#define bus_space_write_8(t,h,o,v) (((t)->hbt_w8)((t)->hbt_cookie,(h),(o),(v)))
+
+#define bus_space_read_multi_1(t,h,o,a,c) \
+ (((t)->hbt_rm_1)((t)->hbt_cookie, (h), (o), (a), (c)))
+#define bus_space_read_multi_2(t,h,o,a,c) \
+ (((t)->hbt_rm_2)((t)->hbt_cookie, (h), (o), (a), (c)))
+#define bus_space_read_multi_4(t,h,o,a,c) \
+ (((t)->hbt_rm_4)((t)->hbt_cookie, (h), (o), (a), (c)))
+#define bus_space_read_multi_8(t,h,o,a,c) \
+ (((t)->hbt_rm_8)((t)->hbt_cookie, (h), (o), (a), (c)))
+
+#define bus_space_write_multi_1(t,h,o,a,c) \
+ (((t)->hbt_wm_1)((t)->hbt_cookie, (h), (o), (a), (c)))
+#define bus_space_write_multi_2(t,h,o,a,c) \
+ (((t)->hbt_wm_2)((t)->hbt_cookie, (h), (o), (a), (c)))
+#define bus_space_write_multi_4(t,h,o,a,c) \
+ (((t)->hbt_wm_4)((t)->hbt_cookie, (h), (o), (a), (c)))
+#define bus_space_write_multi_8(t,h,o,a,c) \
+ (((t)->hbt_wm_8)((t)->hbt_cookie, (h), (o), (a), (c)))
+
+#define bus_space_set_multi_1(t,h,o,v,c) \
+ (((t)->hbt_sm_1)((t)->hbt_cookie, (h), (o), (v), (c)))
+#define bus_space_set_multi_2(t,h,o,v,c) \
+ (((t)->hbt_sm_2)((t)->hbt_cookie, (h), (o), (v), (c)))
+#define bus_space_set_multi_4(t,h,o,v,c) \
+ (((t)->hbt_sm_4)((t)->hbt_cookie, (h), (o), (v), (c)))
+#define bus_space_set_multi_8(t,h,o,v,c) \
+ (((t)->hbt_sm_8)((t)->hbt_cookie, (h), (o), (v), (c)))
+
+#define bus_space_read_raw_multi_2(t, h, o, a, c) \
+ (((t)->hbt_rrm_2)((t)->hbt_cookie, (h), (o), (a), (c)))
+#define bus_space_read_raw_multi_4(t, h, o, a, c) \
+ (((t)->hbt_rrm_4)((t)->hbt_cookie, (h), (o), (a), (c)))
+#define bus_space_read_raw_multi_8(t, h, o, a, c) \
+ (((t)->hbt_rrm_8)((t)->hbt_cookie, (h), (o), (a), (c)))
+
+#define bus_space_write_raw_multi_2(t, h, o, a, c) \
+ (((t)->hbt_wrm_2)((t)->hbt_cookie, (h), (o), (a), (c)))
+#define bus_space_write_raw_multi_4(t, h, o, a, c) \
+ (((t)->hbt_wrm_4)((t)->hbt_cookie, (h), (o), (a), (c)))
+#define bus_space_write_raw_multi_8(t, h, o, a, c) \
+ (((t)->hbt_wrm_8)((t)->hbt_cookie, (h), (o), (a), (c)))
+
+#define bus_space_read_region_1(t, h, o, a, c) \
+ (((t)->hbt_rr_1)((t)->hbt_cookie, (h), (o), (a), (c)))
+#define bus_space_read_region_2(t, h, o, a, c) \
+ (((t)->hbt_rr_2)((t)->hbt_cookie, (h), (o), (a), (c)))
+#define bus_space_read_region_4(t, h, o, a, c) \
+ (((t)->hbt_rr_4)((t)->hbt_cookie, (h), (o), (a), (c)))
+#define bus_space_read_region_8(t, h, o, a, c) \
+ (((t)->hbt_rr_8)((t)->hbt_cookie, (h), (o), (a), (c)))
+
+#define bus_space_write_region_1(t, h, o, a, c) \
+ (((t)->hbt_wr_1)((t)->hbt_cookie, (h), (o), (a), (c)))
+#define bus_space_write_region_2(t, h, o, a, c) \
+ (((t)->hbt_wr_2)((t)->hbt_cookie, (h), (o), (a), (c)))
+#define bus_space_write_region_4(t, h, o, a, c) \
+ (((t)->hbt_wr_4)((t)->hbt_cookie, (h), (o), (a), (c)))
+#define bus_space_write_region_8(t, h, o, a, c) \
+ (((t)->hbt_wr_8)((t)->hbt_cookie, (h), (o), (a), (c)))
+
+#define bus_space_read_raw_region_2(t, h, o, a, c) \
+ (((t)->hbt_rrr_2)((t)->hbt_cookie, (h), (o), (a), (c)))
+#define bus_space_read_raw_region_4(t, h, o, a, c) \
+ (((t)->hbt_rrr_4)((t)->hbt_cookie, (h), (o), (a), (c)))
+#define bus_space_read_raw_region_8(t, h, o, a, c) \
+ (((t)->hbt_rrr_8)((t)->hbt_cookie, (h), (o), (a), (c)))
+
+#define bus_space_write_raw_region_2(t, h, o, a, c) \
+ (((t)->hbt_wrr_2)((t)->hbt_cookie, (h), (o), (a), (c)))
+#define bus_space_write_raw_region_4(t, h, o, a, c) \
+ (((t)->hbt_wrr_4)((t)->hbt_cookie, (h), (o), (a), (c)))
+#define bus_space_write_raw_region_8(t, h, o, a, c) \
+ (((t)->hbt_wrr_8)((t)->hbt_cookie, (h), (o), (a), (c)))
+
+#define bus_space_set_region_1(t, h, o, v, c) \
+ (((t)->hbt_sr_1)((t)->hbt_cookie, (h), (o), (v), (c)))
+#define bus_space_set_region_2(t, h, o, v, c) \
+ (((t)->hbt_sr_2)((t)->hbt_cookie, (h), (o), (v), (c)))
+#define bus_space_set_region_4(t, h, o, v, c) \
+ (((t)->hbt_sr_4)((t)->hbt_cookie, (h), (o), (v), (c)))
+#define bus_space_set_region_8(t, h, o, v, c) \
+ (((t)->hbt_sr_8)((t)->hbt_cookie, (h), (o), (v), (c)))
+
+#define bus_space_copy_1(t, h1, o1, h2, o2, c) \
+ (((t)->hbt_cp_1)((t)->hbt_cookie, (h1), (o1), (h2), (o2), (c)))
+#define bus_space_copy_2(t, h1, o1, h2, o2, c) \
+ (((t)->hbt_cp_2)((t)->hbt_cookie, (h1), (o1), (h2), (o2), (c)))
+#define bus_space_copy_4(t, h1, o1, h2, o2, c) \
+ (((t)->hbt_cp_4)((t)->hbt_cookie, (h1), (o1), (h2), (o2), (c)))
+#define bus_space_copy_8(t, h1, o1, h2, o2, c) \
+ (((t)->hbt_cp_8)((t)->hbt_cookie, (h1), (o1), (h2), (o2), (c)))
+#define BUS_DMA_WAITOK 0x000 /* safe to sleep (pseudo-flag) */
+#define BUS_DMA_NOWAIT 0x001 /* not safe to sleep */
+#define BUS_DMA_ALLOCNOW 0x002 /* perform resource allocation now */
+#define BUS_DMA_COHERENT 0x004 /* hint: map memory DMA coherent */
+#define BUS_DMAMEM_NOSYNC 0x010
+#define BUS_DMA_BUS1 0x020 /* placeholders for bus functions... */
+#define BUS_DMA_BUS2 0x040
+#define BUS_DMA_BUS3 0x080
+#define BUS_DMA_BUS4 0x100
+#define BUS_DMA_STREAMING 0x200 /* hint: sequential, unidirectional */
+#define BUS_DMA_READ 0x400 /* mapping is device -> memory only */
+#define BUS_DMA_WRITE 0x800 /* mapping is memory -> device only */
+
+/* Forwards needed by prototypes below. */
+struct mbuf;
+struct proc;
+struct uio;
+
+/* Operations performed by bus_dmamap_sync(). */
+#define BUS_DMASYNC_POSTREAD 0x01
+#define BUS_DMASYNC_POSTWRITE 0x02
+#define BUS_DMASYNC_PREREAD 0x04
+#define BUS_DMASYNC_PREWRITE 0x08
+
+typedef const struct hppa64_bus_dma_tag *bus_dma_tag_t;
+typedef struct hppa64_bus_dmamap *bus_dmamap_t;
+
+/*
+ * bus_dma_segment_t
+ *
+ * Describes a single contiguous DMA transaction. Values
+ * are suitable for programming into DMA registers.
+ */
+struct hppa64_bus_dma_segment {
+ vaddr_t _ds_va; /* needed for syncing */
+
+ bus_addr_t ds_addr; /* DMA address */
+ bus_size_t ds_len; /* length of transfer */
+};
+typedef struct hppa64_bus_dma_segment bus_dma_segment_t;
+
+/*
+ * bus_dma_tag_t
+ *
+ * A machine-dependent opaque type describing the implementation of
+ * DMA for a given bus.
+ */
+
+struct hppa64_bus_dma_tag {
+ void *_cookie; /* cookie used in the guts */
+
+ /*
+ * DMA mapping methods.
+ */
+ int (*_dmamap_create)(void *, bus_size_t, int,
+ bus_size_t, bus_size_t, int, bus_dmamap_t *);
+ void (*_dmamap_destroy)(void *, bus_dmamap_t);
+ int (*_dmamap_load)(void *, bus_dmamap_t, void *,
+ bus_size_t, struct proc *, int);
+ int (*_dmamap_load_mbuf)(void *, bus_dmamap_t,
+ struct mbuf *, int);
+ int (*_dmamap_load_uio)(void *, bus_dmamap_t,
+ struct uio *, int);
+ int (*_dmamap_load_raw)(void *, bus_dmamap_t,
+ bus_dma_segment_t *, int, bus_size_t, int);
+ void (*_dmamap_unload)(void *, bus_dmamap_t);
+ void (*_dmamap_sync)(void *, bus_dmamap_t, bus_addr_t,
+ bus_size_t, int);
+
+ /*
+ * DMA memory utility functions.
+ */
+ int (*_dmamem_alloc)(void *, bus_size_t, bus_size_t,
+ bus_size_t, bus_dma_segment_t *, int, int *, int);
+ void (*_dmamem_free)(void *, bus_dma_segment_t *, int);
+ int (*_dmamem_map)(void *, bus_dma_segment_t *,
+ int, size_t, caddr_t *, int);
+ void (*_dmamem_unmap)(void *, caddr_t, size_t);
+ paddr_t (*_dmamem_mmap)(void *, bus_dma_segment_t *,
+ int, off_t, int, int);
+};
+
+#define bus_dmamap_create(t, s, n, m, b, f, p) \
+ (*(t)->_dmamap_create)((t)->_cookie, (s), (n), (m), (b), (f), (p))
+#define bus_dmamap_destroy(t, p) \
+ (*(t)->_dmamap_destroy)((t)->_cookie, (p))
+#define bus_dmamap_load(t, m, b, s, p, f) \
+ (*(t)->_dmamap_load)((t)->_cookie, (m), (b), (s), (p), (f))
+#define bus_dmamap_load_mbuf(t, m, b, f) \
+ (*(t)->_dmamap_load_mbuf)((t)->_cookie, (m), (b), (f))
+#define bus_dmamap_load_uio(t, m, u, f) \
+ (*(t)->_dmamap_load_uio)((t)->_cookie, (m), (u), (f))
+#define bus_dmamap_load_raw(t, m, sg, n, s, f) \
+ (*(t)->_dmamap_load_raw)((t)->_cookie, (m), (sg), (n), (s), (f))
+#define bus_dmamap_unload(t, p) \
+ (*(t)->_dmamap_unload)((t)->_cookie, (p))
+#define bus_dmamap_sync(t, p, a, l, o) \
+ (void)((t)->_dmamap_sync ? \
+ (*(t)->_dmamap_sync)((t)->_cookie, (p), (a), (l), (o)) : (void)0)
+
+#define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \
+ (*(t)->_dmamem_alloc)((t)->_cookie, (s), (a), (b), (sg), (n), (r), (f))
+#define bus_dmamem_free(t, sg, n) \
+ (*(t)->_dmamem_free)((t)->_cookie, (sg), (n))
+#define bus_dmamem_map(t, sg, n, s, k, f) \
+ (*(t)->_dmamem_map)((t)->_cookie, (sg), (n), (s), (k), (f))
+#define bus_dmamem_unmap(t, k, s) \
+ (*(t)->_dmamem_unmap)((t)->_cookie, (k), (s))
+#define bus_dmamem_mmap(t, sg, n, o, p, f) \
+ (*(t)->_dmamem_mmap)((t)->_cookie, (sg), (n), (o), (p), (f))
+
+/*
+ * bus_dmamap_t
+ *
+ * Describes a DMA mapping.
+ */
+struct hppa64_bus_dmamap {
+ /*
+ * PRIVATE MEMBERS: not for use by machine-independent code.
+ */
+ bus_size_t _dm_size; /* largest DMA transfer mappable */
+ int _dm_segcnt; /* number of segs this map can map */
+ bus_size_t _dm_maxsegsz; /* largest possible segment */
+ bus_size_t _dm_boundary; /* don't cross this */
+ int _dm_flags; /* misc. flags */
+
+ void *_dm_cookie; /* cookie for bus-specific functions */
+
+ /*
+ * PUBLIC MEMBERS: these are used by machine-independent code.
+ */
+ bus_size_t dm_mapsize; /* size of the mapping */
+ int dm_nsegs; /* # valid segments in mapping */
+ bus_dma_segment_t dm_segs[1]; /* segments; variable length */
+};
+
+#endif /* _MACHINE_BUS_H_ */
diff --git a/sys/arch/hppa64/include/cdefs.h b/sys/arch/hppa64/include/cdefs.h
new file mode 100644
index 00000000000..8e7e74a501b
--- /dev/null
+++ b/sys/arch/hppa64/include/cdefs.h
@@ -0,0 +1,39 @@
+/* $OpenBSD: cdefs.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+/* $NetBSD: cdefs.h,v 1.5 1996/10/12 18:08:12 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#ifndef _MACHINE_CDEFS_H_
+#define _MACHINE_CDEFS_H_
+
+#define __weak_alias(alias,sym) \
+ __asm__(".export " __STRING(alias) ", entry\n\t.weak " __STRING(alias) "\n\t" __STRING(alias) " = " __STRING(sym))
+#define __warn_references(sym,msg) \
+ __asm__(".section .gnu.warning." __STRING(sym) "\n\t.ascii \"" msg "\"\n\t.text")
+
+#endif /* !_MACHINE_CDEFS_H_ */
diff --git a/sys/arch/hppa64/include/conf.h b/sys/arch/hppa64/include/conf.h
new file mode 100644
index 00000000000..cbe367c02f5
--- /dev/null
+++ b/sys/arch/hppa64/include/conf.h
@@ -0,0 +1,38 @@
+/* $OpenBSD: conf.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _MACHINE_CONF_H_
+#define _MACHINE_CONF_H_
+
+#include <sys/conf.h>
+struct tty;
+struct termios;
+
+cdev_decl(pdc);
+int pdcparam(struct tty *, struct termios *);
+void pdcstart(struct tty *);
+
+#define mmread mmrw
+#define mmwrite mmrw
+cdev_decl(mm);
+
+cdev_decl(fd);
+bdev_decl(fd);
+
+#endif /* _MACHINE_CONF_H_ */
diff --git a/sys/arch/hppa64/include/cpu.h b/sys/arch/hppa64/include/cpu.h
new file mode 100644
index 00000000000..41aec18205d
--- /dev/null
+++ b/sys/arch/hppa64/include/cpu.h
@@ -0,0 +1,303 @@
+/* $OpenBSD: cpu.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * Copyright (c) 1988-1994, The University of Utah and
+ * the Computer Systems Laboratory at the University of Utah (CSL).
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software is hereby
+ * granted provided that (1) source code retains these copyright, permission,
+ * and disclaimer notices, and (2) redistributions including binaries
+ * reproduce the notices in supporting documentation, and (3) all advertising
+ * materials mentioning features or use of this software display the following
+ * acknowledgement: ``This product includes software developed by the
+ * Computer Systems Laboratory at the University of Utah.''
+ *
+ * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
+ * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
+ * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * CSL requests users of this software to return to csl-dist@cs.utah.edu any
+ * improvements that they make and grant CSL redistribution rights.
+ *
+ * Utah $Hdr: cpu.h 1.19 94/12/16$
+ */
+
+#ifndef _MACHINE_CPU_H_
+#define _MACHINE_CPU_H_
+
+#include <machine/trap.h>
+#include <machine/frame.h>
+
+/*
+ * COPR/SFUs
+ */
+#define HPPA_FPUS 0xc0
+#define HPPA_FPUVER(w) (((w) & 0x003ff800) >> 11)
+#define HPPA_FPU_OP(w) ((w) >> 26)
+#define HPPA_FPU_UNMPL 0x01 /* exception reg, the rest is << 1 */
+#define HPPA_FPU_ILL 0x80 /* software-only */
+#define HPPA_FPU_I 0x01
+#define HPPA_FPU_U 0x02
+#define HPPA_FPU_O 0x04
+#define HPPA_FPU_Z 0x08
+#define HPPA_FPU_V 0x10
+#define HPPA_FPU_D 0x20
+#define HPPA_FPU_T 0x40
+#define HPPA_FPU_XMASK 0x7f
+#define HPPA_FPU_T_POS 25 /* 32bit reg! */
+#define HPPA_FPU_RM 0x00000600
+#define HPPA_FPU_CQ 0x00fff800
+#define HPPA_FPU_C 0x04000000
+#define HPPA_FPU_FLSH 27
+#define HPPA_FPU_INIT (0)
+#define HPPA_FPU_FORK(s) ((s) & ~((u_int64_t)(HPPA_FPU_XMASK)<<32))
+#define HPPA_PMSFUS 0x20 /* ??? */
+
+/*
+ * Interrupts stuff
+ */
+#define IPL_NONE 0
+#define IPL_SOFTCLOCK 1
+#define IPL_SOFTNET 2
+#define IPL_BIO 3
+#define IPL_NET 4
+#define IPL_SOFTTTY 5
+#define IPL_TTY 6
+#define IPL_VM 7
+#define IPL_AUDIO 8
+#define IPL_CLOCK 9
+#define IPL_SCHED 9
+#define IPL_STATCLOCK 10
+#define IPL_HIGH 11
+
+#define NIPL 12
+
+#define IST_NONE 0
+#define IST_PULSE 1
+#define IST_EDGE 2
+#define IST_LEVEL 3
+
+#define spllowersoftclock() spllower(IPL_SOFTCLOCK)
+#define splsoftclock() splraise(IPL_SOFTCLOCK)
+#define splsoftnet() splraise(IPL_SOFTNET)
+#define splbio() splraise(IPL_BIO)
+#define splnet() splraise(IPL_NET)
+#define splsofttty() splraise(IPL_SOFTTTY)
+#define spltty() splraise(IPL_TTY)
+#define splvm() splraise(IPL_VM)
+#define splimp() splvm()
+#define splaudio() splraise(IPL_AUDIO)
+#define splclock() splraise(IPL_CLOCK)
+#define splsched() splraise(IPL_SCHED)
+#define splstatclock() splraise(IPL_STATCLOCK)
+#define splhigh() splraise(IPL_HIGH)
+#define spl0() spllower(IPL_NONE)
+#define splx(c) spllower(c)
+
+#define setsoftast() (astpending = 1)
+#define setsoftclock() /* TODO */
+#define setsoftnet() /* TODO */
+#define setsofttty() /* TODO */
+
+#ifndef _LOCORE
+#include <sys/time.h>
+#include <sys/sched.h>
+
+struct cpu_info {
+ struct proc *ci_curproc;
+ struct pcb *ci_cpcb;
+ struct cpu_info *ci_next;
+
+ struct proc *ci_fpproc;
+ int ci_number;
+ struct schedstate_percpu ci_schedstate; /* scheduler state */
+
+ /* DEBUG/DIAGNOSTIC stuff */
+ u_long ci_spin_locks; /* # of spin locks held */
+ u_long ci_simple_locks;/* # of simple locks held */
+
+ /* Spinning up the CPU */
+ void (*ci_spinup)(void); /* spinup routine */
+ void *ci_initstack;
+};
+
+struct cpu_info *curcpu(void);
+#define cpu_number() (curcpu()->ci_number)
+#define CPU_IS_PRIMARY(ci) ((ci)->ci_number == 0)
+#define CPU_INFO_ITERATOR int
+#define CPU_INFO_FOREACH(cii,ci) \
+ cii = 0, ci = curcpu(); ci != NULL; ci = ci->ci_next
+#define CPU_INFO_UNIT(ci) ((ci)->ci_number)
+
+#ifdef DIAGNOSTIC
+void splassert_fail(int, int, const char *);
+extern int splassert_ctl;
+void splassert_check(int, const char *);
+#define splassert(__wantipl) do { \
+ if (__predict_false(splassert_ctl > 0)) { \
+ splassert_check(__wantipl, __func__); \
+ } \
+} while (0)
+#else
+#define splassert(__wantipl) do { /* nada */ } while (0)
+#endif /* DIAGNOSTIC */
+
+/* types */
+enum hppa_cpu_type {
+ hpcxu, hpcxu2, hpcxw
+};
+extern enum hppa_cpu_type cpu_type;
+extern const char *cpu_typename;
+extern int cpu_hvers;
+#endif
+
+/*
+ * Exported definitions unique to hp700/PA-RISC cpu support.
+ */
+
+#define HPPA_PGALIAS 0x0000000000100000UL
+#define HPPA_PGAMASK 0xfffffffffff00000UL
+#define HPPA_PGAOFF 0x00000000000fffffUL
+
+#define HPPA_PHYSMAP 0x000001ffffffffffUL
+#define HPPA_IOBEGIN 0xfffffff000000000UL
+#define HPPA_IOLEN 0x0000001000000000UL
+#define HPPA_PHYSEND 0xffffffffffffffffUL
+#define HPPA_IOADDR 0xfffffff100000000UL
+#define HPPA_IOBCAST 0xfffffffffffc0000UL
+#define HPPA_LBCAST 0xfffffffffffc0000UL
+#define HPPA_GBCAST 0xfffffffffffe0000UL
+#define HPPA_FPADDR 0xfffffffffff80000UL
+#define HPPA_FLEX_MASK 0xfffffffffffc0000UL
+#define HPPA_DMA_ENABLE 0x00000001
+#define HPPA_SPA_ENABLE 0x00000020
+#define HPPA_NMODSPBUS 64
+
+#define clockframe trapframe
+#define CLKF_PC(framep) ((framep)->tf_iioq[0])
+#define CLKF_INTR(framep) ((framep)->tf_flags & TFF_INTR)
+#define CLKF_USERMODE(framep) ((framep)->tf_flags & T_USER)
+#define CLKF_SYSCALL(framep) ((framep)->tf_flags & TFF_SYS)
+
+#define signotify(p) (setsoftast())
+#define need_resched(ci) (want_resched = 1, setsoftast())
+#define need_proftick(p) ((p)->p_flag |= P_OWEUPC, setsoftast())
+
+#ifndef _LOCORE
+#ifdef _KERNEL
+
+extern int want_resched, astpending;
+
+#define DELAY(x) delay(x)
+
+int splraise(int cpl);
+int spllower(int cpl);
+
+void delay(u_int us);
+void hppa_init(paddr_t start);
+void trap(int type, struct trapframe *frame);
+int spcopy(pa_space_t ssp, const void *src,
+ pa_space_t dsp, void *dst, size_t size);
+int spstrcpy(pa_space_t ssp, const void *src,
+ pa_space_t dsp, void *dst, size_t size, size_t *rsize);
+int copy_on_fault(void);
+void switch_trampoline(void);
+int cpu_dumpsize(void);
+int cpu_dump(void);
+
+#ifdef USELEDS
+#define PALED_NETSND 0x01
+#define PALED_NETRCV 0x02
+#define PALED_DISK 0x04
+#define PALED_HEARTBEAT 0x08
+#define PALED_LOADMASK 0xf0
+
+#define PALED_DATA 0x01
+#define PALED_STROBE 0x02
+
+extern volatile u_int8_t *machine_ledaddr;
+extern int machine_ledword, machine_leds;
+
+static __inline void
+ledctl(int on, int off, int toggle)
+{
+ if (machine_ledaddr) {
+ int r;
+
+ if (on)
+ machine_leds |= on;
+ if (off)
+ machine_leds &= ~off;
+ if (toggle)
+ machine_leds ^= toggle;
+
+ r = ~machine_leds; /* it seems they should be reversed */
+
+ if (machine_ledword)
+ *machine_ledaddr = r;
+ else {
+ register int b;
+ for (b = 0x80; b; b >>= 1) {
+ *machine_ledaddr = (r & b)? PALED_DATA : 0;
+ DELAY(1);
+ *machine_ledaddr = ((r & b)? PALED_DATA : 0) |
+ PALED_STROBE;
+ }
+ }
+ }
+}
+#endif
+
+void fpu_save(vaddr_t va);
+void fpu_exit(void);
+void ficache(pa_space_t sp, vaddr_t va, vsize_t size);
+void fdcache(pa_space_t sp, vaddr_t va, vsize_t size);
+void pdcache(pa_space_t sp, vaddr_t va, vsize_t size);
+void ficacheall(void);
+void fdcacheall(void);
+void pitlb(pa_space_t sp, vaddr_t va);
+void pdtlb(pa_space_t sp, vaddr_t va);
+void ptlball(void);
+void mtctl(register_t val, int reg);
+register_t mfctl(int reg);
+hppa_hpa_t cpu_gethpa(int n);
+void sync_caches(void);
+#endif
+
+/*
+ * Boot arguments stuff
+ */
+
+#define BOOTARG_LEN (NBPG)
+#define BOOTARG_OFF (0x10000)
+
+/*
+ * CTL_MACHDEP definitions.
+ */
+#define CPU_CONSDEV 1 /* dev_t: console terminal device */
+#define CPU_MAXID 1 /* number of valid machdep ids */
+
+#define CTL_MACHDEP_NAMES { \
+ { 0, 0 }, \
+ { "console_device", CTLTYPE_STRUCT }, \
+}
+#endif
+
+#endif /* _MACHINE_CPU_H_ */
diff --git a/sys/arch/hppa64/include/db_machdep.h b/sys/arch/hppa64/include/db_machdep.h
new file mode 100644
index 00000000000..9c90cab7611
--- /dev/null
+++ b/sys/arch/hppa64/include/db_machdep.h
@@ -0,0 +1,107 @@
+/* $OpenBSD: db_machdep.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _MACHINE_DB_MACHDEP_H_
+#define _MACHINE_DB_MACHDEP_H_
+
+#include <uvm/uvm_extern.h>
+
+#define DB_ELF_SYMBOLS
+#define DB_ELFSIZE 64
+
+/* types the generic ddb module needs */
+typedef vaddr_t db_addr_t;
+typedef long db_expr_t;
+
+typedef struct trapframe db_regs_t;
+extern db_regs_t ddb_regs;
+#define DDB_REGS (&ddb_regs)
+
+#define PC_REGS(regs) ((db_addr_t)(regs)->tf_iioq[0])
+#define SET_PC_REGS(r,pc) ((r)->tf_iioq[0] = (pc), (r)->tf_iioq[1] = (pc) + 4)
+
+/* Breakpoint related definitions */
+#define BKPT_INST 0x00010000 /* break 0,8 */
+#define BKPT_SIZE sizeof(int)
+#define BKPT_SET(inst) BKPT_INST
+
+#define IS_BREAKPOINT_TRAP(type, code) ((type) == T_IBREAK)
+#define IS_WATCHPOINT_TRAP(type, code) ((type) == T_DBREAK)
+
+#define FIXUP_PC_AFTER_BREAK(regs) ((regs)->tf_iioq[0] -= sizeof(int))
+
+#define DB_VALID_BREAKPOINT(addr) db_valid_breakpoint(addr)
+
+/* TODO 64bit insns */
+
+static __inline int inst_call(u_int ins) {
+ return (ins & 0xfc00e000) == 0xe8000000 ||
+ (ins & 0xfc00e000) == 0xe8004000 ||
+ (ins & 0xfc000000) == 0xe4000000;
+}
+static __inline int inst_branch(u_int ins) {
+ return (ins & 0xf0000000) == 0xe0000000 ||
+ (ins & 0xf0000000) == 0xc0000000 ||
+ (ins & 0xf0000000) == 0xa0000000 ||
+ (ins & 0xf0000000) == 0x80000000;
+}
+static __inline int inst_load(u_int ins) {
+ return (ins & 0xf0000000) == 0x40000000 ||
+ (ins & 0xf4000200) == 0x24000000 ||
+ (ins & 0xfc000200) == 0x0c000000 ||
+ (ins & 0xfc001fc0) != 0x0c0011c0;
+}
+static __inline int inst_store(u_int ins) {
+ return (ins & 0xf0000000) == 0x60000000 || /* st */
+ (ins & 0xf4000200) == 0x24000200 || /* fst/cst */
+ (ins & 0xfc000200) == 0x0c000200 || /* stby */
+ (ins & 0xfc0003c0) == 0x0c0001c0; /* ldcw */
+}
+static __inline int inst_return(u_int ins) {
+ return (ins & 0xfc00e000) == 0xe800c000 ||
+ (ins & 0xfc000000) == 0xe0000000;
+}
+static __inline int inst_trap_return(u_int ins) {
+ return (ins & 0xfc001fc0) == 0x00000ca0;
+}
+
+#if 0
+#define db_clear_single_step(r) ((r)->tf_flags &= ~(PSL_Z))
+#define db_set_single_step(r) ((r)->tf_flags |= (PSL_Z))
+#else
+#define SOFTWARE_SSTEP 1
+#define SOFTWARE_SSTEP_EMUL 1
+
+static __inline db_addr_t
+next_instr_address(db_addr_t addr, int b) {
+ return (addr + 4);
+}
+
+#define branch_taken(ins,pc,f,regs) branch_taken1(ins, pc, regs)
+static __inline db_addr_t
+branch_taken1(int ins, db_addr_t pc, db_regs_t *regs) {
+ return (pc);
+}
+
+#endif
+
+int db_valid_breakpoint(db_addr_t);
+int kdb_trap(int, int, db_regs_t *);
+
+#endif /* _MACHINE_DB_MACHDEP_H_ */
diff --git a/sys/arch/hppa64/include/disklabel.h b/sys/arch/hppa64/include/disklabel.h
new file mode 100644
index 00000000000..423637e6644
--- /dev/null
+++ b/sys/arch/hppa64/include/disklabel.h
@@ -0,0 +1,375 @@
+/* $OpenBSD: disklabel.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+/* $NetBSD: disklabel.h,v 1.1 1995/02/13 23:07:34 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994 Christopher G. Demetriou
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR 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 _MACHINE_DISKLABEL_H_
+#define _MACHINE_DISKLABEL_H_
+
+enum disklabel_tag { DLT_ALPHA, DLT_I386, DLT_AMIGA, DLT_HPPA };
+
+/*
+ * What disklabels are we probing for, and in which order?
+ */
+#ifndef LABELPROBES
+#define LABELPROBES DLT_ALPHA, DLT_I386, DLT_AMIGA, DLT_HPPA
+#endif
+
+#define ALPHA_LABELSECTOR 0 /* sector containing label */
+#define ALPHA_LABELOFFSET 64 /* offset of label in sector */
+#define I386_LABELSECTOR 1 /* sector containing label */
+#define I386_LABELOFFSET 0 /* offset of label in sector */
+#define AMIGA_LABELSECTOR 0 /* sector containing label */
+#define AMIGA_LABELOFFSET 64 /* offset of label in sector */
+#define HPPA_LABELSECTOR 1 /* sector containing label */
+#define HPPA_LABELOFFSET 0 /* offset of label in sector */
+
+#define LABELSECTOR HPPA_LABELSECTOR
+#define LABELOFFSET HPPA_LABELOFFSET
+
+#define MAXPARTITIONS 16 /* number of partitions */
+#define RAW_PART 2 /* raw partition: xx?c */
+
+/* DOS partition table -- located in boot block */
+#define DOSBBSECTOR 0 /* DOS boot block relative sector # */
+#define DOSPARTOFF 446
+#define DOSACTIVE 0x80
+#define NDOSPART 4
+#define DOSMBR_SIGNATURE 0xaa55
+#define DOSMBR_SIGNATURE_OFF 0x1fe
+
+struct dos_partition {
+ u_int8_t dp_flag; /* bootstrap flags */
+ u_int8_t dp_shd; /* starting head */
+ u_int8_t dp_ssect; /* starting sector */
+ u_int8_t dp_scyl; /* starting cylinder */
+ u_int8_t dp_typ; /* partition type (see below) */
+ u_int8_t dp_ehd; /* end head */
+ u_int8_t dp_esect; /* end sector */
+ u_int8_t dp_ecyl; /* end cylinder */
+ u_int32_t dp_start; /* absolute starting sector number */
+ u_int32_t dp_size; /* partition size in sectors */
+};
+
+/* Known DOS partition types. */
+#define DOSPTYP_UNUSED 0x00 /* Unused partition */
+#define DOSPTYP_FAT12 0x01 /* 12-bit FAT */
+#define DOSPTYP_FAT16S 0x04 /* 16-bit FAT, less than 32M */
+#define DOSPTYP_EXTEND 0x05 /* Extended; contains sub-partitions */
+#define DOSPTYP_FAT16B 0x06 /* 16-bit FAT, more than 32M */
+#define DOSPTYP_FAT32 0x0b /* 32-bit FAT */
+#define DOSPTYP_FAT32L 0x0c /* 32-bit FAT, LBA-mapped */
+#define DOSPTYP_FAT16L 0x0e /* 16-bit FAT, LBA-mapped */
+#define DOSPTYP_ONTRACK 0x54
+#define DOSPTYP_LINUX 0x83 /* That other thing */
+#define DOSPTYP_FREEBSD 0xa5 /* FreeBSD partition type */
+#define DOSPTYP_OPENBSD 0xa6 /* OpenBSD partition type */
+#define DOSPTYP_NETBSD 0xa9 /* NetBSD partition type */
+
+/* Isolate the relevant bits to get sector and cylinder. */
+#define DPSECT(s) ((s) & 0x3f)
+#define DPCYL(c, s) ((c) + (((s) & 0xc0) << 2))
+
+/*
+ * describes ados Rigid Disk Blocks
+ * which are used to partition a drive
+ */
+#define RDBNULL ((u_int32_t)0xffffffff)
+
+/*
+ * you will find rdblock somewhere in [0, RDBMAXBLOCKS)
+ */
+#define RDB_MAXBLOCKS 16
+
+struct rdblock {
+ u_int32_t id; /* 'RDSK' */
+ u_int32_t nsumlong; /* number of longs in check sum */
+ u_int32_t chksum; /* simple additive with wrap checksum */
+ u_int32_t hostid; /* scsi target of host */
+ u_int32_t nbytes; /* size of disk blocks */
+ u_int32_t flags;
+ u_int32_t badbhead; /* linked list of badblocks */
+ u_int32_t partbhead; /* linked list of partblocks */
+ u_int32_t fsbhead; /* " " of fsblocks */
+ u_int32_t driveinit;
+ u_int32_t resv1[6]; /* RDBNULL */
+ u_int32_t ncylinders; /* number of cylinders on drive */
+ u_int32_t nsectors; /* number of sectors per track */
+ u_int32_t nheads; /* number of tracks per cylinder */
+ u_int32_t interleave;
+ u_int32_t park; /* only used with st506 i.e. not */
+ u_int32_t resv2[3];
+ u_int32_t wprecomp; /* start cyl for write precomp */
+ u_int32_t reducedwrite; /* start cyl for reduced write current */
+ u_int32_t steprate; /* driver step rate in ?s */
+ u_int32_t resv3[5];
+ u_int32_t rdblowb; /* lowblock of range for rdb's */
+ u_int32_t rdbhighb; /* high block of range for rdb's */
+ u_int32_t lowcyl; /* low cylinder of partition area */
+ u_int32_t highcyl; /* upper cylinder of partition area */
+ u_int32_t secpercyl; /* number of sectors per cylinder */
+ u_int32_t parkseconds; /* zero if no park needed */
+ u_int32_t resv4[2];
+ char diskvendor[8]; /* inquiry stuff */
+ char diskproduct[16]; /* inquiry stuff */
+ char diskrevision[4]; /* inquiry stuff */
+ char contvendor[8]; /* inquiry stuff */
+ char contproduct[16]; /* inquiry stuff */
+ char contrevision[4]; /* inquiry stuff */
+#if never_use_secsize
+ u_int32_t resv5[0];
+#endif
+};
+
+
+#define RDBF_LAST 0x1 /* last drive available */
+#define RDBF_LASTLUN 0x2 /* last LUN available */
+#define RDBF_LASTUNIT 0x4 /* last target available */
+#define RDBF_NORESELECT 0x8 /* do not use reselect */
+#define RDBF_DISKID 0x10 /* disk id is valid ?? */
+#define RDBF_CTRLID 0x20 /* ctrl id is valid ?? */
+#define RDBF_SYNC 0x40 /* drive supports SCSI synchronous mode */
+
+struct ados_environ {
+ u_int32_t tabsize; /* 0: environ table size */
+ u_int32_t sizeblock; /* 1: n long words in a block */
+ u_int32_t secorg; /* 2: not used must be zero */
+ u_int32_t numheads; /* 3: number of surfaces */
+ u_int32_t secperblk; /* 4: must be 1 */
+ u_int32_t secpertrk; /* 5: blocks per track */
+ u_int32_t resvblocks; /* 6: reserved blocks at start */
+ u_int32_t prefac; /* 7: must be 0 */
+ u_int32_t interleave; /* 8: normally 1 */
+ u_int32_t lowcyl; /* 9: low cylinder of partition */
+ u_int32_t highcyl; /* 10: upper cylinder of partition */
+ u_int32_t numbufs; /* 11: ados: number of buffers */
+ u_int32_t membuftype; /* 12: ados: type of bufmem */
+ u_int32_t maxtrans; /* 13: maxtrans the ctrlr supports */
+ u_int32_t mask; /* 14: mask for valid address */
+ u_int32_t bootpri; /* 15: boot priority for autoboot */
+ u_int32_t dostype; /* 16: filesystem type */
+ u_int32_t baud; /* 17: serial handler baud rate */
+ u_int32_t control; /* 18: control word for fs */
+ u_int32_t bootblocks; /* 19: blocks containing boot code */
+ u_int32_t fsize; /* 20: file system block size */
+ u_int32_t frag; /* 21: allowable frags per block */
+ u_int32_t cpg; /* 22: cylinders per group */
+};
+
+struct partblock {
+ u_int32_t id; /* 'PART' */
+ u_int32_t nsumlong; /* number of longs in check sum */
+ u_int32_t chksum; /* simple additive with wrap checksum */
+ u_int32_t hostid; /* scsi target of host */
+ u_int32_t next; /* next in chain */
+ u_int32_t flags; /* see below */
+ u_int32_t resv1[3];
+ u_char partname[32]; /* (BCPL) part name (may not be unique) */
+ u_int32_t resv2[15];
+ struct ados_environ e;
+#if never_use_secsize
+ u_int32_t extra[9]; /* 8 for extra added to environ */
+#endif
+};
+
+#define PBF_BOOTABLE 0x1 /* partition is bootable */
+#define PBF_NOMOUNT 0x2 /* partition should be mounted */
+
+struct badblock {
+ u_int32_t id; /* 'BADB' */
+ u_int32_t nsumlong; /* number of longs in check sum */
+ u_int32_t chksum; /* simple additive with wrap checksum */
+ u_int32_t hostid; /* scsi target of host */
+ u_int32_t next; /* next in chain */
+ u_int32_t resv;
+ struct badblockent {
+ u_int32_t badblock;
+ u_int32_t goodblock;
+ } badtab[0]; /* 61 for secsize == 512 */
+};
+
+struct fsblock {
+ u_int32_t id; /* 'FSHD' */
+ u_int32_t nsumlong; /* number of longs in check sum */
+ u_int32_t chksum; /* simple additive with wrap checksum */
+ u_int32_t hostid; /* scsi target of host */
+ u_int32_t next; /* next in chain */
+ u_int32_t flags;
+ u_int32_t resv1[2];
+ u_int32_t dostype; /* this is a file system for this type */
+ u_int32_t version; /* version of this fs */
+ u_int32_t patchflags; /* describes which functions to replace */
+ u_int32_t type; /* zero */
+ u_int32_t task; /* zero */
+ u_int32_t lock; /* zero */
+ u_int32_t handler; /* zero */
+ u_int32_t stacksize; /* to use when loading handler */
+ u_int32_t priority; /* to run the fs at. */
+ u_int32_t startup; /* zero */
+ u_int32_t lsegblocks; /* linked list of lsegblocks of fs code */
+ u_int32_t globalvec; /* bcpl vector not used mostly */
+#if never_use_secsize
+ u_int32_t resv2[44];
+#endif
+};
+
+struct lsegblock {
+ u_int32_t id; /* 'LSEG' */
+ u_int32_t nsumlong; /* number of longs in check sum */
+ u_int32_t chksum; /* simple additive with wrap checksum */
+ u_int32_t hostid; /* scsi target of host */
+ u_int32_t next; /* next in chain */
+ u_int32_t loaddata[0]; /* load segment data, 123 for secsize == 512 */
+};
+
+#define RDBLOCK_ID 0x5244534b /* 'RDSK' */
+#define PARTBLOCK_ID 0x50415254 /* 'PART' */
+#define BADBLOCK_ID 0x42414442 /* 'BADB' */
+#define FSBLOCK_ID 0x46534844 /* 'FSHD' */
+#define LSEGBLOCK_ID 0x4c534547 /* 'LSEG' */
+
+/*
+ * volume header for "LIF" format volumes
+ */
+struct lifvol {
+ short vol_id;
+ char vol_label[6];
+ u_int vol_addr;
+ short vol_oct;
+ short vol_dummy;
+ u_int vol_dirsize;
+ short vol_version;
+ short vol_zero;
+ u_int vol_number;
+ u_int vol_lastvol;
+ u_int vol_length;
+ char vol_toc[6];
+ char vol_dummy1[198];
+
+ u_int ipl_addr;
+ u_int ipl_size;
+ u_int ipl_entry;
+
+ u_int vol_dummy2;
+};
+
+struct lifdir {
+ char dir_name[10];
+ u_short dir_type;
+ u_int dir_addr;
+ u_int dir_length;
+ char dir_toc[6];
+ short dir_flag;
+ u_int dir_implement;
+};
+
+struct lif_load {
+ int address;
+ int count;
+};
+
+#define HPUX_MAGIC 0x8b7f6a3c
+#define HPUX_MAXPART 16
+struct hpux_label {
+ int32_t hl_magic1;
+ u_int32_t hl_magic;
+ int32_t hl_version;
+ struct {
+ int32_t hlp_blah[2];
+ int32_t hlp_start;
+ int32_t hlp_length;
+ } hl_parts[HPUX_MAXPART];
+ u_int8_t hl_flags[HPUX_MAXPART];
+#define HPUX_PART_ROOT 0x10
+#define HPUX_PART_SWAP 0x14
+#define HPUX_PART_BOOT 0x32
+ int32_t hl_blah[3*16];
+ u_int16_t hl_boot;
+ u_int16_t hl_reserved;
+ int32_t hl_magic2;
+};
+
+#define LIF_VOL_ID -32768
+#define LIF_VOL_OCT 4096
+#define LIF_DIR_SWAP 0x5243
+#define LIF_DIR_HPLBL 0xa271
+#define LIF_DIR_FS 0xcd38
+#define LIF_DIR_IOMAP 0xcd60
+#define LIF_DIR_HPUX 0xcd80
+#define LIF_DIR_ISL 0xce00
+#define LIF_DIR_PAD 0xcffe
+#define LIF_DIR_AUTO 0xcfff
+#define LIF_DIR_EST 0xd001
+#define LIF_DIR_TYPE 0xe942
+
+#define LIF_DIR_FLAG 0x8001 /* dont ask me! */
+#define LIF_SECTSIZE 256
+
+#define LIF_NUMDIR 16
+
+#define LIF_VOLSTART 0
+#define LIF_VOLSIZE sizeof(struct lifvol)
+#define LIF_DIRSTART 2048
+#define LIF_DIRSIZE (LIF_NUMDIR * sizeof(struct lifdir))
+#define LIF_FILESTART 8192
+
+#define btolifs(b) (((b) + (LIF_SECTSIZE - 1)) / LIF_SECTSIZE)
+#define lifstob(s) ((s) * LIF_SECTSIZE)
+#define lifstodb(s) ((s) * LIF_SECTSIZE / DEV_BSIZE)
+
+#include <sys/dkbad.h>
+struct cpu_disklabel {
+ enum disklabel_tag labeltag;
+ int labelsector;
+ union {
+ struct {
+ } _alpha;
+ struct {
+ struct dos_partition dosparts[NDOSPART];
+ struct dkbad bad;
+ } _i386;
+ struct {
+ u_int32_t rdblock; /* RDBNULL -> inval. */
+ u_int32_t pblist[MAXPARTITIONS];/* pblock number */
+ int pbindex[MAXPARTITIONS]; /* index of pblock */
+ int valid; /* valid? */
+ } _amiga;
+ struct {
+ struct lifvol lifvol;
+ struct lifdir lifdir[LIF_NUMDIR];
+ struct hpux_label hplabel;
+ } _hppa;
+ } u;
+};
+
+#define DKBAD(x) ((x)->u._i386.bad)
+
+#endif /* _MACHINE_DISKLABEL_H_ */
diff --git a/sys/arch/hppa64/include/endian.h b/sys/arch/hppa64/include/endian.h
new file mode 100644
index 00000000000..3138bcc84d8
--- /dev/null
+++ b/sys/arch/hppa64/include/endian.h
@@ -0,0 +1,28 @@
+/* $OpenBSD: endian.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HPPA64_ENDIAN_H_
+#define _HPPA64_ENDIAN_H_
+
+#define BYTE_ORDER BIG_ENDIAN
+#include <sys/endian.h>
+
+#define __STRICT_ALIGNMENT
+
+#endif /* !_HPPA64_ENDIAN_H_ */
diff --git a/sys/arch/hppa64/include/exec.h b/sys/arch/hppa64/include/exec.h
new file mode 100644
index 00000000000..3b2ccc70267
--- /dev/null
+++ b/sys/arch/hppa64/include/exec.h
@@ -0,0 +1,113 @@
+/* $OpenBSD: exec.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 1994, The University of Utah and
+ * the Computer Systems Laboratory at the University of Utah (CSL).
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software is hereby
+ * granted provided that (1) source code retains these copyright, permission,
+ * and disclaimer notices, and (2) redistributions including binaries
+ * reproduce the notices in supporting documentation, and (3) all advertising
+ * materials mentioning features or use of this software display the following
+ * acknowledgement: ``This product includes software developed by the
+ * Computer Systems Laboratory at the University of Utah.''
+ *
+ * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
+ * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
+ * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * CSL requests users of this software to return to csl-dist@cs.utah.edu any
+ * improvements that they make and grant CSL redistribution rights.
+ *
+ * Utah $Hdr: exec.h 1.3 94/12/16$
+ */
+
+#ifndef _MACHINE_EXEC_H_
+#define _MACHINE_EXEC_H_
+
+#define cpu_exec_aout_makecmds(p, epp) ENOEXEC
+
+/* Size of a page in an object file. */
+#define __LDPGSZ 4096
+
+#define ARCH_ELFSIZE 64
+
+#define ELF_TARG_CLASS ELFCLASS64
+#define ELF_TARG_DATA ELFDATA2MSB
+#define ELF_TARG_MACH EM_PARISC
+
+#define NATIVE_EXEC_ELF
+#define _NLIST_DO_ELF
+#define _KERN_DO_ELF
+
+/*
+ * the following MD ELF values defenitions are from the:
+ * "Processor-Specific ELF Supplement for PA-RISC.
+ * Including HP and HP-UX Extensions. Version 1.43. October 6, 1997"
+ * http://devrsrc1.external.hp.com/STK/partner/elf-pa.pdf
+ *
+ */
+
+/* parisc-specific elf flags */
+#define EF_PARISC_TRAPNIL 0x00010000 /* trap on NULL derefs */
+#define EF_PARISC_EXT 0x00020000 /* program uses arch exts */
+#define EF_PARISC_LSB 0x00040000 /* program expects LSB mode */
+#define EF_PARISC_WIDE 0x00080000 /* program expects wide mode */
+#define EF_PARISC_NO_KABP 0x00100000 /* don't allow kernel assisted
+ branch prediction */
+#define EF_PARISC_LAZYSWAP 0x00200000 /* allow lazy swap allocation
+ for dynamically allocated
+ program segments */
+#define EF_PARISC_ARCH 0x0000ffff /* architecture version */
+#define EFA_PARISC_1_0 0x020B
+#define EFA_PARISC_1_1 0x0210
+#define EFA_PARISC_2_0 0x0214
+
+/* legend: 0 - pa7000, 1 - pa7100, 2 - pa7200, 3 - pa7100LC, 4 - pa8000 */
+#define PARISC_AE_QWSI 0x00000001 /* 0 : enable quadword stores */
+#define PARISC_AE_FPLSU 0x00000002 /* 1: fp load/store to I/O space */
+#define PARISC_AE_RSQRT 0x00000004 /* 0 : reciprocal sqrt */
+#define PARISC_AE_FDCG 0x00000008 /* 0,1: fdc includes graph flushes */
+#define PARISC_AE_HPAR 0x00000010 /* 3,4: half-word add/sub/av */
+#define PARISC_AE_BSW 0x00000020 /* 3,4: half-word shift-add */
+#define PARISC_AE_HPSA 0x00000040 /* 3 : byte-swapping stores */
+#define PARISC_AE_DPR0 0x00000080 /* 2,4: data prefetch via ld to r0 */
+
+#define SHN_PARISC_ANSI_COMMON 0xff00
+#define SHN_PARISC_HUGE_COMMON 0xff01
+
+/* sh_type */
+#define SHT_PARISC_EXT 0x70000000 /* contains product-specific
+ extension bits */
+#define SHT_PARISC_UNWIND 0x70000001 /* contains unwind table enries
+ sh_info contains index of
+ the code section to which
+ unwind entries apply */
+#define SHT_PARISC_DOC 0x70000002 /* contains debug info for -O */
+#define SHT_PARISC_ANNOT 0x70000003 /* contains code annotations */
+
+/* sh_flags */
+#define SHF_PARISC_SBP 0x80000000 /* contains code compiled for
+ static branch prediction */
+#define SHF_PARISC_HUGE 0x40000000 /* should be allocated far from gp */
+#define SHF_PARISC_SHORT 0x20000000 /* should be allocated near from gp */
+
+#define ELF_PARISC_ARCHEXT ".PARISC.archext"
+#define ELF_PARISC_MILLI ".PARISC.milli"
+#define ELF_PARISC_UNWIND ".PARISC.unwind"
+#define ELF_PARISC_UNWIND_INFO ".PARISC.unwind_info"
+#define ELF_PARISC_SDATA ".sdata"
+#define ELF_PARISC_NOBITS ".sbss"
+
+#define STT_PARISC_MILLI 13 /* entry point of a millicode routine */
+
+#define PT_PARISC_ARCHEXT 0x70000000 /* segment contains
+ .PARISC.archext section */
+#define PT_PARISC_UNWIND 0x70000001 /* segment contains
+ .unwind section */
+
+#define PF_PARISC_SBP 0x08000000 /* segment contains code
+ compiled for static branch prediction */
+
+#endif /* _MACHINE_EXEC_H_ */
diff --git a/sys/arch/hppa64/include/float.h b/sys/arch/hppa64/include/float.h
new file mode 100644
index 00000000000..4260471309c
--- /dev/null
+++ b/sys/arch/hppa64/include/float.h
@@ -0,0 +1,76 @@
+/* $OpenBSD: float.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)float.h 7.1 (Berkeley) 5/8/90
+ */
+
+#ifndef _HPPA_FLOAT_H_
+#define _HPPA_FLOAT_H_
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+int __flt_rounds(void);
+__END_DECLS
+
+#define FLT_RADIX 2
+#define FLT_ROUNDS __flt_rounds()
+
+#define FLT_MANT_DIG 24
+#define FLT_EPSILON 1.19209290E-07F
+#define FLT_DIG 6
+#define FLT_MIN_EXP (-125)
+#define FLT_MIN 1.17549435E-38F
+#define FLT_MIN_10_EXP (-37)
+#define FLT_MAX_EXP 128
+#define FLT_MAX 3.40282347E+38F
+#define FLT_MAX_10_EXP 38
+
+#define DBL_MANT_DIG 53
+#define DBL_EPSILON 2.2204460492503131E-16
+#define DBL_DIG 15
+#define DBL_MIN_EXP (-1021)
+#define DBL_MIN 2.2250738585072014E-308
+#define DBL_MIN_10_EXP (-307)
+#define DBL_MAX_EXP 1024
+#define DBL_MAX 1.7976931348623157E+308
+#define DBL_MAX_10_EXP 308
+
+#define LDBL_MANT_DIG 113
+#define LDBL_EPSILON 1.9259299443872358530559779425849273E-34L
+#define LDBL_DIG 33
+#define LDBL_MIN_EXP (-16381)
+#define LDBL_MIN 3.3621031431120935062626778173217526026E-4932L
+#define LDBL_MIN_10_EXP (-4931)
+#define LDBL_MAX_EXP 16384
+#define LDBL_MAX 1.1897314953572317650857593266280070162E4932L
+#define LDBL_MAX_10_EXP 4932
+
+#endif /* _MACHINE_FLOAT_H_ */
diff --git a/sys/arch/hppa64/include/frame.h b/sys/arch/hppa64/include/frame.h
new file mode 100644
index 00000000000..3be63ffa0a5
--- /dev/null
+++ b/sys/arch/hppa64/include/frame.h
@@ -0,0 +1,113 @@
+/* $OpenBSD: frame.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _MACHINE_FRAME_H_
+#define _MACHINE_FRAME_H_
+
+/*
+ * Call frame definitions
+ */
+#define HPPA_FRAME_SIZE (128)
+#define HPPA_FRAME_PSP (-8)
+#define HPPA_FRAME_RP (-16)
+
+/*
+ * Macros to decode processor status word.
+ */
+#define HPPA_PC_PRIV_MASK 3
+#define HPPA_PC_PRIV_KERN 0
+#define HPPA_PC_PRIV_USER 3
+#define USERMODE(pc) ((((register_t)pc) & HPPA_PC_PRIV_MASK) != HPPA_PC_PRIV_KERN)
+#define KERNMODE(pc) (((register_t)pc) & ~HPPA_PC_PRIV_MASK)
+
+/*
+ *
+ */
+#define HPPA_SID_MAX 0x7ffffe00
+#define HPPA_SID_KERNEL 0
+#define HPPA_PID_KERNEL 2
+
+#ifndef _LOCORE
+/*
+ * the trapframe is divided into two parts:
+ * one is saved while we are in the physical mode (beginning of the trap),
+ * and should be kept as small as possible, since all the interrupts will
+ * be lost during this phase, also it must be 64-bytes aligned, per
+ * pa-risc stack conventions, and its dependencies in the code (;
+ * the other part is filled out when we are already in the virtual mode,
+ * are able to catch interrupts (they are kept pending) and perform
+ * other trap activities (like tlb misses).
+ */
+struct trapframe {
+ unsigned long tf_flags;
+ unsigned long tf_r1;
+ unsigned long tf_rp;
+ unsigned long tf_r3;
+ unsigned long tf_r4;
+ unsigned long tf_r5;
+ unsigned long tf_r6;
+ unsigned long tf_r7;
+ unsigned long tf_r8;
+ unsigned long tf_r9;
+ unsigned long tf_r10;
+ unsigned long tf_r11;
+ unsigned long tf_r12;
+ unsigned long tf_r13;
+ unsigned long tf_r14;
+ unsigned long tf_r15;
+ unsigned long tf_r16;
+ unsigned long tf_r17;
+ unsigned long tf_r18;
+ unsigned long tf_args[8];
+ unsigned long tf_dp; /* r27 */
+ unsigned long tf_ret0;
+ unsigned long tf_ret1;
+ unsigned long tf_sp;
+ unsigned long tf_r31;
+ unsigned long tf_sr0;
+ unsigned long tf_sr1;
+ unsigned long tf_sr2;
+ unsigned long tf_sr3;
+ unsigned long tf_sr4;
+ unsigned long tf_sr5;
+ unsigned long tf_sr6;
+ unsigned long tf_sr7;
+ unsigned long tf_rctr;
+ unsigned long tf_ccr; /* cr10 */
+ unsigned long tf_iioq[2];
+ unsigned long tf_iisq[2];
+ unsigned long tf_pidr1;
+ unsigned long tf_pidr2;
+ unsigned long tf_eiem;
+ unsigned long tf_eirr;
+ unsigned long tf_ior;
+ unsigned long tf_isr;
+ unsigned long tf_iir;
+ unsigned long tf_ipsw;
+ unsigned long tf_ci; /* cr24 */
+ unsigned long tf_vtop; /* cr25 */
+ unsigned long tf_cr30; /* pa(u) */
+ unsigned long tf_cr27; /* user curthread */
+ unsigned long tf_sar;
+
+ unsigned long tf_pad[5];
+};
+#endif /* !_LOCORE */
+
+#endif /* !_MACHINE_FRAME_H_ */
diff --git a/sys/arch/hppa64/include/ieee.h b/sys/arch/hppa64/include/ieee.h
new file mode 100644
index 00000000000..dfd8044fd80
--- /dev/null
+++ b/sys/arch/hppa64/include/ieee.h
@@ -0,0 +1,137 @@
+/* $OpenBSD: ieee.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Lawrence Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)ieee.h 8.1 (Berkeley) 6/11/93
+ */
+
+/*
+ * ieee.h defines the machine-dependent layout of the machine's IEEE
+ * floating point. It does *not* define (yet?) any of the rounding
+ * mode bits, exceptions, and so forth.
+ */
+
+/*
+ * Define the number of bits in each fraction and exponent.
+ *
+ * k k+1
+ * Note that 1.0 x 2 == 0.1 x 2 and that denorms are represented
+ *
+ * (-exp_bias+1)
+ * as fractions that look like 0.fffff x 2 . This means that
+ *
+ * -126
+ * the number 0.10000 x 2 , for instance, is the same as the normalized
+ *
+ * -127 -128
+ * float 1.0 x 2 . Thus, to represent 2 , we need one leading zero
+ *
+ * -129
+ * in the fraction; to represent 2 , we need two, and so on. This
+ *
+ * (-exp_bias-fracbits+1)
+ * implies that the smallest denormalized number is 2
+ *
+ * for whichever format we are talking about: for single precision, for
+ *
+ * -126 -149
+ * instance, we get .00000000000000000000001 x 2 , or 1.0 x 2 , and
+ *
+ * -149 == -127 - 23 + 1.
+ */
+#define SNG_EXPBITS 8
+#define SNG_FRACBITS 23
+
+#define DBL_EXPBITS 11
+#define DBL_FRACBITS 52
+
+#ifdef notyet
+#define E80_EXPBITS 15
+#define E80_FRACBITS 64
+#endif
+
+#define EXT_EXPBITS 15
+#define EXT_FRACBITS 112
+
+struct ieee_single {
+ u_int sng_sign:1;
+ u_int sng_exp:8;
+ u_int sng_frac:23;
+};
+
+struct ieee_double {
+ u_int dbl_sign:1;
+ u_int dbl_exp:11;
+ u_int dbl_frach:20;
+ u_int dbl_fracl;
+};
+
+struct ieee_ext {
+ u_int ext_sign:1;
+ u_int ext_exp:15;
+ u_int ext_frach:16;
+ u_int ext_frachm;
+ u_int ext_fraclm;
+ u_int ext_fracl;
+};
+
+/*
+ * Floats whose exponent is in [1..INFNAN) (of whatever type) are
+ * `normal'. Floats whose exponent is INFNAN are either Inf or NaN.
+ * Floats whose exponent is zero are either zero (iff all fraction
+ * bits are zero) or subnormal values.
+ *
+ * A NaN is a `signalling NaN' if its QUIETNAN bit is clear in its
+ * high fraction; if the bit is set, it is a `quiet NaN'.
+ */
+#define SNG_EXP_INFNAN 255
+#define DBL_EXP_INFNAN 2047
+#define EXT_EXP_INFNAN 32767
+
+#if 0
+#define SNG_QUIETNAN (1 << 22)
+#define DBL_QUIETNAN (1 << 19)
+#define EXT_QUIETNAN (1 << 15)
+#endif
+
+/*
+ * Exponent biases.
+ */
+#define SNG_EXP_BIAS 127
+#define DBL_EXP_BIAS 1023
+#define EXT_EXP_BIAS 16383
diff --git a/sys/arch/hppa64/include/ieeefp.h b/sys/arch/hppa64/include/ieeefp.h
new file mode 100644
index 00000000000..d33f6ac542e
--- /dev/null
+++ b/sys/arch/hppa64/include/ieeefp.h
@@ -0,0 +1,24 @@
+/* $OpenBSD: ieeefp.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Written by Miodrag Vallat. Public domain.
+ */
+
+#ifndef _HPPA64_IEEEFP_H_
+#define _HPPA64_IEEEFP_H_
+
+typedef int fp_except;
+#define FP_X_INV 0x10 /* invalid operation exception */
+#define FP_X_DZ 0x08 /* divide-by-zero exception */
+#define FP_X_OFL 0x04 /* overflow exception */
+#define FP_X_UFL 0x02 /* underflow exception */
+#define FP_X_IMP 0x01 /* imprecise (loss of precision) */
+
+typedef enum {
+ FP_RN=0, /* round to nearest representable number */
+ FP_RZ=1, /* round to zero (truncate) */
+ FP_RP=2, /* round toward positive infinity */
+ FP_RM=3 /* round toward negative infinity */
+} fp_rnd;
+
+#endif /* _HPPA64_IEEEFP_H_ */
diff --git a/sys/arch/hppa64/include/internal_types.h b/sys/arch/hppa64/include/internal_types.h
new file mode 100644
index 00000000000..2ceb6165937
--- /dev/null
+++ b/sys/arch/hppa64/include/internal_types.h
@@ -0,0 +1,7 @@
+/* $OpenBSD: internal_types.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+/* Public domain */
+
+#ifndef _MACHINE_INTERNAL_TYPES_H_
+#define _MACHINE_INTERNAL_TYPES_H_
+
+#endif
diff --git a/sys/arch/hppa64/include/iomod.h b/sys/arch/hppa64/include/iomod.h
new file mode 100644
index 00000000000..04b20060d5f
--- /dev/null
+++ b/sys/arch/hppa64/include/iomod.h
@@ -0,0 +1,3 @@
+/* $OpenBSD: iomod.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+#include <arch/hppa/include/iomod.h>
diff --git a/sys/arch/hppa64/include/kcore.h b/sys/arch/hppa64/include/kcore.h
new file mode 100644
index 00000000000..3f652493bee
--- /dev/null
+++ b/sys/arch/hppa64/include/kcore.h
@@ -0,0 +1,28 @@
+/* $OpenBSD: kcore.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _MACHINE_KCORE_H_
+#define _MACHINE_KCORE_H_
+
+typedef
+struct cpu_kcore_hdr {
+ int dummy;
+} cpu_kcore_hdr_t;
+
+#endif /* _MACHINE_KCORE_H_ */
diff --git a/sys/arch/hppa64/include/limits.h b/sys/arch/hppa64/include/limits.h
new file mode 100644
index 00000000000..bc4736a98e1
--- /dev/null
+++ b/sys/arch/hppa64/include/limits.h
@@ -0,0 +1,55 @@
+/* $OpenBSD: limits.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)limits.h 8.3 (Berkeley) 1/4/94
+ */
+
+#ifndef _MACHINE_LIMITS_H_
+#define _MACHINE_LIMITS_H_
+
+#define MB_LEN_MAX 32 /* Allow 31 bit UTF2 */
+
+#if !defined(_ANSI_SOURCE)
+#define SIZE_MAX ULONG_MAX /* max value for a size_t */
+#define SSIZE_MAX LONG_MAX /* max value for a ssize_t */
+
+#if !defined(_POSIX_SOURCE)
+#define SIZE_T_MAX ULONG_MAX /* max value for a size_t */
+
+/* GCC requires that quad constants be written as expressions. */
+#define UQUAD_MAX ((u_quad_t)0-1) /* max value for a uquad_t */
+ /* max value for a quad_t */
+#define QUAD_MAX ((quad_t)(UQUAD_MAX >> 1))
+#define QUAD_MIN (-QUAD_MAX-1) /* min value for a quad_t */
+
+#endif /* !_POSIX_SOURCE */
+#endif /* !_ANSI_SOURCE */
+
+#endif /* _MACHINE_LIMITS_H_ */
diff --git a/sys/arch/hppa64/include/loadfile_machdep.h b/sys/arch/hppa64/include/loadfile_machdep.h
new file mode 100644
index 00000000000..3ce4f899109
--- /dev/null
+++ b/sys/arch/hppa64/include/loadfile_machdep.h
@@ -0,0 +1,83 @@
+/* $OpenBSD: loadfile_machdep.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*-
+ * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas and Jason R. Thorpe.
+ *
+ * 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 the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 _HPPA64_LOADFILE_MACHDEP_H_
+#define _HPPA64_LOADFILE_MACHDEP_H_
+
+#define BOOT_ELF
+#define ELFSIZE 64
+
+#define LOAD_KERNEL LOAD_ALL
+#define COUNT_KERNEL COUNT_ALL
+
+#ifdef _STANDALONE
+
+#define LOADADDR(a) ((a) + offset)
+#define ALIGNENTRY(a) 0
+#define READ(f, b, c) pread((f), (void *)LOADADDR(b), (c))
+#define BCOPY(s, d, c) vpbcopy((s), (void *)LOADADDR(d), (c))
+#define BZERO(d, c) pbzero((void *)LOADADDR(d), (c))
+#define WARN(a) (void)(printf a, \
+ printf((errno ? ": %s\n" : "\n"), \
+ strerror(errno)))
+#define PROGRESS(a) (void) printf a
+#define ALLOC(a) alloc(a)
+#define FREE(a, b) free(a, b)
+
+#define vpbcopy bcopy
+#define pbzero bzero
+#define pread read
+
+#else
+
+#define LOADADDR(a) (((u_long)(a)) + offset)
+#define ALIGNENTRY(a) ((u_long)(a))
+#define READ(f, b, c) read((f), (void *)LOADADDR(b), (c))
+#define BCOPY(s, d, c) memcpy((void *)LOADADDR(d), (void *)(s), (c))
+#define BZERO(d, c) memset((void *)LOADADDR(d), 0, (c))
+#define WARN(a) warn a
+#define PROGRESS(a) /* nothing */
+#define ALLOC(a) malloc(a)
+#define FREE(a, b) free(a)
+
+ssize_t vread(int, u_long, u_long *, size_t);
+void vcopy(u_long, u_long, u_long *, size_t);
+void vzero(u_long, u_long *, size_t);
+
+#endif
+#endif /* ! _HPPA64_LOADFILE_MACHDEP_H_ */
diff --git a/sys/arch/hppa64/include/nvm.h b/sys/arch/hppa64/include/nvm.h
new file mode 100644
index 00000000000..d050076e88b
--- /dev/null
+++ b/sys/arch/hppa64/include/nvm.h
@@ -0,0 +1,74 @@
+/* $OpenBSD: nvm.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 1990, 1994 The University of Utah and
+ * the Computer Systems Laboratory at the University of Utah (CSL).
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software is hereby
+ * granted provided that (1) source code retains these copyright, permission,
+ * and disclaimer notices, and (2) redistributions including binaries
+ * reproduce the notices in supporting documentation, and (3) all advertising
+ * materials mentioning features or use of this software display the following
+ * acknowledgement: ``This product includes software developed by the
+ * Computer Systems Laboratory at the University of Utah.''
+ *
+ * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
+ * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
+ * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * CSL requests users of this software to return to csl-dist@cs.utah.edu any
+ * improvements that they make and grant CSL redistribution rights.
+ *
+ * Utah $Hdr: nvm.h 1.4 94/12/14$
+ * Author: Jeff Forys, University of Utah CSL
+ */
+
+#ifndef _MACHINE_NVM_H_
+#define _MACHINE_NVM_H_
+
+/*
+ * The PDC provides access to Non-Volatile Memory (NVM). If this
+ * is implemented (it's HVERSION dependent), the first 256 bytes
+ * are formatted as follows:
+ *
+ * 0x000 +----------------------------+
+ * | Implementation information |
+ * 0x024 +----------------------------+
+ * | |
+ * | IPL information |
+ * | |
+ * 0x080 +----------------------------+
+ * | |
+ * | |
+ * | OS Panic information |
+ * | |
+ * | |
+ * 0x100 +----------------------------+
+ *
+ * It appears that there are at least 256 bytes of NVM, and only
+ * the "OS Panic information" is not architected. This means that
+ * we can use locations 0x80 - 0xFF for saving information across
+ * boots (e.g. boot flags and boot device). I think we should use
+ * the higher portions of this space first, to avoid conflicting
+ * with possible future HP-PA plans for the NVM.
+ *
+ * The PDC requires that NVM be read/written to in word multiples.
+ */
+
+/*
+ * Boot flags and boot device (0xF4 - 0xFF).
+ */
+
+#define NVM_BOOTDATA 0xF4 /* location of bootdata in NVM */
+#define NVM_BOOTMAGIC 0xACCEDE /* magic used for bootdata cksum */
+#define NVM_BOOTCKSUM(bd) \
+ ((unsigned int) NVM_BOOTMAGIC + (bd).flags + (bd).device)
+
+struct bootdata {
+ unsigned int cksum; /* NVM_BOOTMAGIC + flags + device */
+ unsigned int flags; /* boot flags */
+ unsigned int device; /* boot device */
+};
+
+#endif /* _MACHINE_NVM_H_ */
diff --git a/sys/arch/hppa64/include/param.h b/sys/arch/hppa64/include/param.h
new file mode 100644
index 00000000000..a5a9b428918
--- /dev/null
+++ b/sys/arch/hppa64/include/param.h
@@ -0,0 +1,131 @@
+/* $OpenBSD: param.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 1988-1994, The University of Utah and
+ * the Computer Systems Laboratory at the University of Utah (CSL).
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software is hereby
+ * granted provided that (1) source code retains these copyright, permission,
+ * and disclaimer notices, and (2) redistributions including binaries
+ * reproduce the notices in supporting documentation, and (3) all advertising
+ * materials mentioning features or use of this software display the following
+ * acknowledgement: ``This product includes software developed by the
+ * Computer Systems Laboratory at the University of Utah.''
+ *
+ * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
+ * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
+ * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * CSL requests users of this software to return to csl-dist@cs.utah.edu any
+ * improvements that they make and grant CSL redistribution rights.
+ *
+ * Utah $Hdr: param.h 1.18 94/12/16$
+ */
+
+#include <machine/cpu.h>
+
+/*
+ * Machine dependent constants for PA-RISC.
+ */
+
+#define _MACHINE hppa64
+#define MACHINE "hppa64"
+#define _MACHINE_ARCH hppa64
+#define MACHINE_ARCH "hppa64"
+#define MID_MACHINE MID_HPPA20
+
+/*
+ * Round p (pointer or byte index) up to a correctly-aligned value for all
+ * data types (int, long, ...). The result is u_int and must be cast to
+ * any desired pointer type.
+ */
+#define ALIGNBYTES 7
+#define ALIGN(p) (((u_long)(p) + ALIGNBYTES) &~ ALIGNBYTES)
+#define ALIGNED_POINTER(p,t) ((((u_long)(p)) & (sizeof(t) - 1)) == 0)
+
+#define PAGE_SIZE 4096
+#define PAGE_MASK (PAGE_SIZE-1)
+#define PAGE_SHIFT 12
+
+#define NBPG 4096 /* bytes/page */
+#define PGOFSET (NBPG-1) /* byte offset into page */
+#define PGSHIFT 12 /* LOG2(NBPG) */
+
+#define KERNBASE 0x00000000 /* start of kernel virtual */
+#define BTOPKERNBASE ((u_long)KERNBASE >> PAGE_SHIFT)
+
+#define DEV_BSIZE 512
+#define DEV_BSHIFT 9 /* log2(DEV_BSIZE) */
+#define BLKDEV_IOSIZE 2048
+#define MAXPHYS (64 * 1024) /* max raw I/O transfer size */
+
+#define MACHINE_STACK_GROWS_UP 1 /* stack grows to higher addresses */
+
+#define SSIZE (4) /* initial stack size/NBPG */
+#define SINCR (1) /* increment of stack/NBPG */
+
+#define USPACE (4 * NBPG) /* pages for user struct and kstack */
+#define USPACE_ALIGN (0) /* u-area alignment 0-none */
+
+#ifndef MSGBUFSIZE
+#define MSGBUFSIZE 2*NBPG /* default message buffer size */
+#endif
+
+/*
+ * Constants related to network buffer management.
+ * MCLBYTES must be no larger than the software page size, and,
+ * on machines that exchange pages of input or output buffers with mbuf
+ * clusters (MAPPED_MBUFS), MCLBYTES must also be an integral multiple
+ * of the hardware page size.
+ */
+#define MSIZE 256 /* size of an mbuf */
+#define MCLSHIFT 11
+#define MCLBYTES (1 << MCLSHIFT) /* large enough for ether MTU */
+#define MCLOFSET (MCLBYTES - 1)
+#define NMBCLUSTERS 4096 /* map size, max cluster allocation */
+
+/*
+ * Minimum and maximum sizes of the kernel malloc arena in PAGE_SIZE-sized
+ * logical pages.
+ */
+#define NKMEMPAGES_MIN_DEFAULT ((4 * 1024 * 1024) >> PAGE_SHIFT)
+#define NKMEMPAGES_MAX_DEFAULT ((64 * 1024 * 1024) >> PAGE_SHIFT)
+
+/* pages ("clicks") (4096 bytes) to disk blocks */
+#define ctod(x) ((x) << (PAGE_SHIFT - DEV_BSHIFT))
+#define dtoc(x) ((x) >> (PAGE_SHIFT - DEV_BSHIFT))
+
+/* pages to bytes */
+#define ctob(x) ((x) << PAGE_SHIFT)
+#define btoc(x) (((x) + PAGE_MASK) >> PAGE_SHIFT)
+
+#define btodb(x) ((x) >> DEV_BSHIFT)
+#define dbtob(x) ((x) << DEV_BSHIFT)
+
+/*
+ * Map a ``block device block'' to a file system block.
+ * This should be device dependent, and should use the bsize
+ * field from the disk label.
+ * For now though just use DEV_BSIZE.
+ */
+#define bdbtofsb(bn) ((bn) / (BLKDEV_IOSIZE/DEV_BSIZE))
+
+/*
+ * Mach derived conversion macros
+ */
+#define hppa_round_page(x) ((((unsigned long)(x)) + NBPG - 1) & ~(NBPG-1))
+#define hppa_trunc_page(x) ((unsigned long)(x) & ~(NBPG-1))
+
+#define btop(x) ((unsigned long)(x) >> PAGE_SHIFT)
+#define ptob(x) ((unsigned long)(x) << PAGE_SHIFT)
+
+#ifndef _LOCORE
+#define CONADDR conaddr
+#define CONUNIT conunit
+#define COM_FREQ 7372800
+extern hppa_hpa_t conaddr;
+extern int conunit;
+#endif
+
+#define __SWAP_BROKEN
diff --git a/sys/arch/hppa64/include/pcb.h b/sys/arch/hppa64/include/pcb.h
new file mode 100644
index 00000000000..ab366a4d14e
--- /dev/null
+++ b/sys/arch/hppa64/include/pcb.h
@@ -0,0 +1,44 @@
+/* $OpenBSD: pcb.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _MACHINE_PCB_H_
+#define _MACHINE_PCB_H_
+
+#include <machine/reg.h>
+
+struct pcb {
+ u_int64_t pcb_fpregs[HPPA_NFPREGS+1]; /* not in the trapframe */
+ u_int64_t pcb_onfault; /* SW copy fault handler */
+ vaddr_t pcb_uva; /* KVA for U-area */
+ u_int64_t pcb_ksp; /* kernel sp for ctxsw */
+ pa_space_t pcb_space; /* copy pmap_space, for asm's sake */
+
+#if 0 /* imaginary part that is after user but in the same page */
+ u_int32_t pcb_pad[53+768];
+ u_int64_t pcb_frame[64]; /* the very end */
+#endif
+};
+
+struct md_coredump {
+ struct reg md_reg;
+ struct fpreg md_fpreg;
+};
+
+
+#endif /* _MACHINE_PCB_H_ */
diff --git a/sys/arch/hppa64/include/pci_machdep.h b/sys/arch/hppa64/include/pci_machdep.h
new file mode 100644
index 00000000000..9e122ad90ab
--- /dev/null
+++ b/sys/arch/hppa64/include/pci_machdep.h
@@ -0,0 +1,82 @@
+/* $OpenBSD: pci_machdep.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _MACHINE_PCI_MACHDEP_H_
+#define _MACHINE_PCI_MACHDEP_H_
+
+/*
+ * Types provided to machine-independent PCI code
+ */
+typedef struct hppa64_pci_chipset_tag *pci_chipset_tag_t;
+typedef u_int pcitag_t;
+typedef u_long pci_intr_handle_t;
+
+struct pci_attach_args;
+
+struct hppa64_pci_chipset_tag {
+ void *_cookie;
+ void (*pc_attach_hook)(struct device *,
+ struct device *, struct pcibus_attach_args *);
+ int (*pc_bus_maxdevs)(void *, int);
+ pcitag_t (*pc_make_tag)(void *, int, int, int);
+ void (*pc_decompose_tag)(void *, pcitag_t, int *,
+ int *, int *);
+ pcireg_t (*pc_conf_read)(void *, pcitag_t, int);
+ void (*pc_conf_write)(void *, pcitag_t, int, pcireg_t);
+
+ int (*pc_intr_map)(struct pci_attach_args *,
+ pci_intr_handle_t *);
+ const char *(*pc_intr_string)(void *, pci_intr_handle_t);
+ void *(*pc_intr_establish)(void *, pci_intr_handle_t,
+ int, int (*)(void *), void *, char *);
+ void (*pc_intr_disestablish)(void *, void *);
+
+ void *(*pc_alloc_parent)(struct device *,
+ struct pci_attach_args *, int);
+};
+
+/*
+ * Functions provided to machine-independent PCI code.
+ */
+#define pci_attach_hook(p, s, pba) \
+ (*(pba)->pba_pc->pc_attach_hook)((p), (s), (pba))
+#define pci_bus_maxdevs(c, b) \
+ (*(c)->pc_bus_maxdevs)((c)->_cookie, (b))
+#define pci_make_tag(c, b, d, f) \
+ (*(c)->pc_make_tag)((c)->_cookie, (b), (d), (f))
+#define pci_decompose_tag(c, t, bp, dp, fp) \
+ (*(c)->pc_decompose_tag)((c)->_cookie, (t), (bp), (dp), (fp))
+#define pci_conf_read(c, t, r) \
+ (*(c)->pc_conf_read)((c)->_cookie, (t), (r))
+#define pci_conf_write(c, t, r, v) \
+ (*(c)->pc_conf_write)((c)->_cookie, (t), (r), (v))
+#define pci_intr_map(p, ihp) \
+ (*(p)->pa_pc->pc_intr_map)((p), (ihp))
+#define pci_intr_line(ih) (ih)
+#define pci_intr_string(c, ih) \
+ (*(c)->pc_intr_string)((c)->_cookie, (ih))
+#define pci_intr_establish(c, ih, l, h, a, nm) \
+ (*(c)->pc_intr_establish)((c)->_cookie, (ih), (l), (h), (a), (nm))
+#define pci_intr_disestablish(c, iv) \
+ (*(c)->pc_intr_disestablish)((c)->_cookie, (iv))
+
+#define pciide_machdep_compat_intr_establish(a, b, c, d, e) (NULL)
+#define pciide_machdep_compat_intr_disestablish(a, b) ((void)(a), (void)(b))
+
+#endif /* _MACHINE_PCI_MACHDEP_H_ */
diff --git a/sys/arch/hppa64/include/pdc.h b/sys/arch/hppa64/include/pdc.h
new file mode 100644
index 00000000000..89034c60e79
--- /dev/null
+++ b/sys/arch/hppa64/include/pdc.h
@@ -0,0 +1,3 @@
+/* $OpenBSD: pdc.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+#include <arch/hppa/include/pdc.h>
diff --git a/sys/arch/hppa64/include/pmap.h b/sys/arch/hppa64/include/pmap.h
new file mode 100644
index 00000000000..1014076b7e2
--- /dev/null
+++ b/sys/arch/hppa64/include/pmap.h
@@ -0,0 +1,117 @@
+/* $OpenBSD: pmap.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _MACHINE_PMAP_H_
+#define _MACHINE_PMAP_H_
+
+#include <machine/pte.h>
+#include <uvm/uvm_pglist.h>
+#include <uvm/uvm_object.h>
+
+struct pmap {
+ simple_lock_data_t pm_lock;
+ int pm_refcount;
+ struct vm_page *pm_ptphint;
+ struct pglist pm_pglist;
+ volatile u_int32_t *pm_pdir; /* page dir (read-only after create) */
+ pa_space_t pm_space; /* space id (read-only after create) */
+
+ struct pmap_statistics pm_stats;
+};
+typedef struct pmap *pmap_t;
+
+struct pv_entry { /* locked by its list's pvh_lock */
+ struct pv_entry *pv_next;
+ struct pmap *pv_pmap; /* the pmap */
+ vaddr_t pv_va; /* the virtual address */
+ struct vm_page *pv_ptp; /* the vm_page of the PTP */
+};
+
+#ifdef _KERNEL
+
+extern struct pmap kernel_pmap_store;
+
+/*
+ * pool quickmaps
+ */
+#define pmap_map_direct(pg) ((vaddr_t)VM_PAGE_TO_PHYS(pg))
+#define pmap_unmap_direct(va) PHYS_TO_VM_PAGE((paddr_t)(va))
+#define __HAVE_PMAP_DIRECT
+
+/*
+ * according to the parisc manual aliased va's should be
+ * different by high 12 bits only.
+ */
+#define PMAP_PREFER(o,h) do { \
+ vaddr_t pmap_prefer_hint; \
+ pmap_prefer_hint = (*(h) & HPPA_PGAMASK) | ((o) & HPPA_PGAOFF); \
+ if (pmap_prefer_hint < *(h)) \
+ pmap_prefer_hint += HPPA_PGALIAS; \
+ *(h) = pmap_prefer_hint; \
+} while(0)
+
+#define PMAP_GROWKERNEL
+#define PMAP_STEAL_MEMORY
+
+#define pmap_sid2pid(s) (((s) + 1) << 1)
+#define pmap_kernel() (&kernel_pmap_store)
+#define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count)
+#define pmap_update(pm) (void)(pm)
+#define pmap_copy(dpmap,spmap,da,len,sa)
+
+#define pmap_clear_modify(pg) pmap_changebit(pg, 0, PTE_DIRTY)
+#define pmap_clear_reference(pg) pmap_changebit(pg, PTE_REFTRAP, 0)
+#define pmap_is_modified(pg) pmap_testbit(pg, PTE_DIRTY)
+#define pmap_is_referenced(pg) pmap_testbit(pg, PTE_REFTRAP)
+#define pmap_phys_address(ppn) ((ppn) << PAGE_SHIFT)
+
+#define pmap_proc_iflush(p,va,len) /* nothing */
+#define pmap_unuse_final(p) /* nothing */
+
+void pmap_bootstrap(vaddr_t);
+boolean_t pmap_changebit(struct vm_page *, pt_entry_t, pt_entry_t);
+boolean_t pmap_testbit(struct vm_page *, pt_entry_t);
+void pmap_write_protect(struct pmap *, vaddr_t, vaddr_t, vm_prot_t);
+void pmap_remove(struct pmap *pmap, vaddr_t sva, vaddr_t eva);
+void pmap_page_remove(struct vm_page *pg);
+
+static __inline void
+pmap_page_protect(struct vm_page *pg, vm_prot_t prot)
+{
+ if ((prot & UVM_PROT_WRITE) == 0) {
+ if (prot & (UVM_PROT_RX))
+ pmap_changebit(pg, 0, PTE_WRITE);
+ else
+ pmap_page_remove(pg);
+ }
+}
+
+static __inline void
+pmap_protect(struct pmap *pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot)
+{
+ if ((prot & UVM_PROT_WRITE) == 0) {
+ if (prot & (UVM_PROT_RX))
+ pmap_write_protect(pmap, sva, eva, prot);
+ else
+ pmap_remove(pmap, sva, eva);
+ }
+}
+
+#endif /* _KERNEL */
+#endif /* _MACHINE_PMAP_H_ */
diff --git a/sys/arch/hppa64/include/proc.h b/sys/arch/hppa64/include/proc.h
new file mode 100644
index 00000000000..1197ef43208
--- /dev/null
+++ b/sys/arch/hppa64/include/proc.h
@@ -0,0 +1,43 @@
+/* $OpenBSD: proc.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)proc.h 7.1 (Berkeley) 5/15/91
+ */
+
+/*
+ * Machine-dependent part of the proc structure for hppa.
+ */
+struct mdproc {
+ struct trapframe *md_regs; /* registers on current frame */
+ long md_flags; /* machine-dependent flags */
+};
+
+/* md_flags */
+
diff --git a/sys/arch/hppa64/include/profile.h b/sys/arch/hppa64/include/profile.h
new file mode 100644
index 00000000000..36e8b335fe7
--- /dev/null
+++ b/sys/arch/hppa64/include/profile.h
@@ -0,0 +1,45 @@
+/* $OpenBSD: profile.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)profile.h 8.1 (Berkeley) 6/11/93
+ */
+
+#define _MCOUNT_DECL void _mcount
+
+#define MCOUNT
+
+#ifdef _KERNEL
+/*
+ * Note that we assume splhigh() and splx() cannot call mcount()
+ * recursively.
+ */
+#define MCOUNT_ENTER s = splhigh()
+#define MCOUNT_EXIT splx(s)
+#endif /* _KERNEL */
diff --git a/sys/arch/hppa64/include/psl.h b/sys/arch/hppa64/include/psl.h
new file mode 100644
index 00000000000..94be150eba0
--- /dev/null
+++ b/sys/arch/hppa64/include/psl.h
@@ -0,0 +1,94 @@
+/* $OpenBSD: psl.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _MACHINE_PSL_H_
+#define _MACHINE_PSL_H_
+
+/*
+ * Rference:
+ * 1. PA-RISC 1.1 Architecture and Instruction Set Manual
+ * Hewlett Packard, 3rd Edition, February 1994; Part Number 09740-90039
+ */
+
+/*
+ * Processor Status Word Bit Positions (in PA-RISC bit order)
+ */
+#define PSL_Y_POS (0)
+#define PSL_Z_POS (1)
+#define PSL_W_POS (4)
+#define PSL_E_POS (5)
+#define PSL_S_POS (6)
+#define PSL_T_POS (7)
+#define PSL_H_POS (8)
+#define PSL_L_POS (9)
+#define PSL_N_POS (10)
+#define PSL_X_POS (11)
+#define PSL_B_POS (12)
+#define PSL_C_POS (13)
+#define PSL_V_POS (14)
+#define PSL_M_POS (15)
+#define PSL_CB_POS (16)
+#define PSL_O_POS (24)
+#define PSL_G_POS (25)
+#define PSL_F_POS (26)
+#define PSL_R_POS (27)
+#define PSL_Q_POS (28)
+#define PSL_P_POS (29)
+#define PSL_D_POS (30)
+#define PSL_I_POS (31)
+
+#define PSL_BITS "\020\001I\002D\003P\004Q\005R\006F\007G\010O" \
+ "\021M\022V\023C\024B\025X\026N\027L\030H" \
+ "\031T\032S\033E\034W\037Z\040Y"
+
+/*
+ * Processor Status Word Bit Values
+ */
+#define PSL_Y (1 << (31-PSL_Y_POS)) /* Data Debug Trap Disable */
+#define PSL_Z (1 << (31-PSL_Z_POS)) /* Instruction Debug Trap Disable */
+#define PSL_W (1 << (31-PSL_W_POS)) /* 64bit address decode enable */
+#define PSL_E (1 << (31-PSL_E_POS)) /* Little Endian Memory Access Enable */
+#define PSL_S (1 << (31-PSL_S_POS)) /* Secure Interval Timer */
+#define PSL_T (1 << (31-PSL_T_POS)) /* Taken Branch Trap Enable */
+#define PSL_H (1 << (31-PSL_H_POS)) /* Higher-privilege xfer Trap Enable */
+#define PSL_L (1 << (31-PSL_L_POS)) /* Lower-privilege xfer Trap Enable */
+#define PSL_N (1 << (31-PSL_N_POS)) /* Nullify */
+#define PSL_X (1 << (31-PSL_X_POS)) /* Data Memory Break Disable */
+#define PSL_B (1 << (31-PSL_B_POS)) /* Taken Branch */
+#define PSL_C (1 << (31-PSL_C_POS)) /* Instruction Address Translation */
+#define PSL_V (1 << (31-PSL_V_POS)) /* Divide Step Correction */
+#define PSL_M (1 << (31-PSL_M_POS)) /* High-priority Machine Check Mask */
+#define PSL_CB (1 << (31-PSL_CB_POS)) /* Carry/Borrow Bits */
+#define PSL_O (1 << (31-PSL_O_POS)) /* Force strong ordering (2.0) */
+#define PSL_G (1 << (31-PSL_G_POS)) /* Debug Trap Enable */
+#define PSL_F (1 << (31-PSL_F_POS)) /* Perfomance Monitor Interrupt */
+#define PSL_R (1 << (31-PSL_R_POS)) /* Recover Counter Enable */
+#define PSL_Q (1 << (31-PSL_Q_POS)) /* Interrupt State Collection Enable */
+#define PSL_P (1 << (31-PSL_P_POS)) /* Protection Identifier Validation */
+#define PSL_D (1 << (31-PSL_D_POS)) /* Data Address Translation Enable */
+#define PSL_I (1 << (31-PSL_I_POS)) /* External Interrupt, Power Failure
+ Interrupt, and Low-Priority Machine
+ Check Interrupt unmask */
+
+/*
+ * Frequently Used PSW Values
+ */
+#define RESET_PSL (PSL_R | PSL_Q | PSL_P | PSL_D | PSL_I)
+
+#endif /* _MACHINE_PSL_H_ */
diff --git a/sys/arch/hppa64/include/pte.h b/sys/arch/hppa64/include/pte.h
new file mode 100644
index 00000000000..4440b2da827
--- /dev/null
+++ b/sys/arch/hppa64/include/pte.h
@@ -0,0 +1,68 @@
+/* $OpenBSD: pte.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _MACHINE_PTE_H_
+#define _MACHINE_PTE_H_
+
+#define SID_MASK (0x1ff)
+#define SID_SHIFT (9)
+#define PIE_MASK (0x1ff80000000UL)
+#define PIE_SHIFT (PDE_SHIFT+10)
+#define PDE_MASK (0x0007fe00000UL)
+#define PDE_SHIFT (PTE_SHIFT+9)
+#define PTE_MASK (0x000001ff000UL)
+#define PTE_SHIFT PAGE_SHIFT
+#define PTE_PAGE(pte) (((pte) & ~PTE_PGMASK) << 7)
+#define TLB_PAGE(pg) (((pg) >> 7) & PTE_PGMASK)
+
+#define PTE_IFLUSH 0x8000000000000000UL /* software */
+#define PTE_DFLUSH 0x4000000000000000UL /* software */
+#define PTE_REFTRAP 0x2000000000000000UL /* used as a ref bit */
+#define PTE_DIRTY 0x1000000000000000UL
+#define PTE_BREAK 0x0800000000000000UL
+#define PTE_GATEWAY 0x04c0000000000000UL
+#define PTE_EXEC 0x0200000000000000UL
+#define PTE_WRITE 0x0100000000000000UL
+#define PTE_READ 0x0000000000000000UL
+#define PTE_USER 0x00f0000000000000UL
+#define PTE_ACC_NONE 0x0730000000000000UL
+#define PTE_ACC_MASK 0x07f0000000000000UL
+#define PTE_UNCACHABLE 0x0008000000000000UL
+#define PTE_ORDER 0x0004000000000000UL
+#define PTE_PREDICT 0x0002000000000000UL
+#define PTE_WIRED 0x0001000000000000UL /* software */
+#define PTE_PGMASK 0x0000001fffffffe0UL
+#define PTE_PG4K 0x0000000000000000UL
+#define PTE_PG16K 0x0000000000000001UL
+#define PTE_PG64K 0x0000000000000002UL
+#define PTE_PG256K 0x0000000000000003UL
+#define PTE_PG1M 0x0000000000000004UL
+#define PTE_PG4M 0x0000000000000005UL
+#define PTE_PG16M 0x0000000000000006UL
+#define PTE_PG64M 0x0000000000000007UL
+
+#define PTE_GETBITS(pte) ((pte) >> 48)
+#define PTE_BITS \
+ "\020\01H\02P\03O\04UC\05U\010W\11X\12G\014B\015D\016REF\017FD\020FI"
+
+#ifndef _LOCORE
+typedef u_int64_t pt_entry_t;
+#endif
+
+#endif /* _MACHINE_PTE_H_ */
diff --git a/sys/arch/hppa64/include/ptrace.h b/sys/arch/hppa64/include/ptrace.h
new file mode 100644
index 00000000000..a48a429b5a1
--- /dev/null
+++ b/sys/arch/hppa64/include/ptrace.h
@@ -0,0 +1,27 @@
+/* $OpenBSD: ptrace.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * MD ptrace definitions
+ */
+#define PT_STEP (PT_FIRSTMACH + 0)
+#define PT_GETREGS (PT_FIRSTMACH + 1)
+#define PT_SETREGS (PT_FIRSTMACH + 2)
+#define PT_GETFPREGS (PT_FIRSTMACH + 3)
+#define PT_SETFPREGS (PT_FIRSTMACH + 4)
diff --git a/sys/arch/hppa64/include/rbus_machdep.h b/sys/arch/hppa64/include/rbus_machdep.h
new file mode 100644
index 00000000000..963e54b89ff
--- /dev/null
+++ b/sys/arch/hppa64/include/rbus_machdep.h
@@ -0,0 +1,34 @@
+/* $OpenBSD: rbus_machdep.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+static __inline int
+md_space_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int flags, bus_space_handle_t *bshp)
+{
+ if (bshp)
+ *(bshp) = bpa;
+
+ return (0);
+}
+
+#define md_space_unmap(t,bsh,s,addrp) do { *(addrp) = (bsh); } while (0)
+
+struct pci_attach_args;
+
+#define rbus_pccbb_parent_mem(d, p) (*(p)->pa_pc->pc_alloc_parent)((d), (p), 0)
+#define rbus_pccbb_parent_io(d, p) (*(p)->pa_pc->pc_alloc_parent)((d), (p), 1)
diff --git a/sys/arch/hppa64/include/reg.h b/sys/arch/hppa64/include/reg.h
new file mode 100644
index 00000000000..ce4cc5add6f
--- /dev/null
+++ b/sys/arch/hppa64/include/reg.h
@@ -0,0 +1,93 @@
+/* $OpenBSD: reg.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * Copyright (c) 1990,1994 The University of Utah and
+ * the Computer Systems Laboratory at the University of Utah (CSL).
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software is hereby
+ * granted provided that (1) source code retains these copyright, permission,
+ * and disclaimer notices, and (2) redistributions including binaries
+ * reproduce the notices in supporting documentation, and (3) all advertising
+ * materials mentioning features or use of this software display the following
+ * acknowledgement: ``This product includes software developed by the
+ * Computer Systems Laboratory at the University of Utah.''
+ *
+ * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
+ * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
+ * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * CSL requests users of this software to return to csl-dist@cs.utah.edu any
+ * improvements that they make and grant CSL redistribution rights.
+ *
+ * Utah $Hdr: regs.h 1.6 94/12/14$
+ * Author: Bob Wheeler, University of Utah CSL
+ */
+
+#ifndef _MACHINE_REG_H_
+#define _MACHINE_REG_H_
+
+/*
+ * constants for registers for use with the following routines:
+ *
+ * void mtctl(reg, value) - move to control register
+ * int mfctl(reg) - move from control register
+ * int mtsp(sreg, value) - move to space register
+ * int mfsr(sreg) - move from space register
+ */
+
+#define CR_RCTR 0
+#define CR_PIDR1 8
+#define CR_PIDR2 9
+#define CR_CCR 10
+#define CR_SAR 11
+#define CR_PIDR3 12
+#define CR_PIDR4 13
+#define CR_IVA 14
+#define CR_EIEM 15
+#define CR_ITMR 16
+#define CR_PCSQ 17
+#define CR_PCOQ 18
+#define CR_IIR 19
+#define CR_ISR 20
+#define CR_IOR 21
+#define CR_IPSW 22
+#define CR_EIRR 23
+#define CR_CPUINFO 24
+#define CR_VTOP 25
+#define CR_UPADDR 30 /* paddr of U-area of curproc */
+#define CR_TR7 31
+
+#define HPPA_NREGS (32)
+#define HPPA_NFPREGS (33) /* 33rd is used for r0 in fpemul */
+
+#ifndef _LOCORE
+
+struct reg {
+ u_int64_t r_regs[HPPA_NREGS]; /* r0 is sar */
+ u_int64_t r_pc;
+ u_int64_t r_npc;
+};
+
+struct fpreg {
+ u_int64_t fpr_regs[HPPA_NFPREGS];
+};
+#endif /* !_LOCORE */
+
+#endif /* _MACHINE_REG_H_ */
diff --git a/sys/arch/hppa64/include/reloc.h b/sys/arch/hppa64/include/reloc.h
new file mode 100644
index 00000000000..6c32cad2433
--- /dev/null
+++ b/sys/arch/hppa64/include/reloc.h
@@ -0,0 +1,123 @@
+/* $OpenBSD: reloc.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _MACHINE_RELOC_H_
+#define _MACHINE_RELOC_H_
+
+/* pa1 compatibility */
+#define RELOC_DLTREL21L RELOC_GPREL21L
+#define RELOC_DLTREL14R RELOC_GPREL14R
+#define RELOC_DLTIND21L RELOC_LTOFF21L
+#define RELOC_DLTIND14R RELOC_LTOFF14R
+#define RELOC_DLTIND14F RELOC_LTOFF14F
+#define RELOC_DLTREL14WR RELOC_GPREL14WR
+#define RELOC_DLTREL14DR RELOC_GPREL14DR
+#define RELOC_DLTIND14WR RELOC_LTOFF14WR
+#define RELOC_DLTIND14DR RELOC_LTOFF14DR
+
+
+enum reloc_type {
+ RELOC_NONE = 0,
+ RELOC_DIR32, /* symbol + addend*/
+ RELOC_DIR21L, /* LR(symbol, addend) */
+ RELOC_DIR17R, /* RR(symbol, addend) */
+ RELOC_DIR17F, /* symbol + addend */
+ RELOC_DIR14R = 6, /* RR(symbol, addend) */
+ RELOC_PCREL32 = 9, /* pa2: symbol - PC - 8 + addend */
+ RELOC_PCREL21L, /* L(symbol - PC - 8 + addend */
+ RELOC_PCREL17R, /* R(symbol - PC - 8 + addend */
+ RELOC_PCREL17F, /* symbol - PC - 8 + addend */
+ RELOC_PCREL17C, /* pa1: symbol - PC - 8 + addend */
+ RELOC_PCREL14R, /* R(symbol - PC - 8 + addend */
+ RELOC_DPREL21L = 18, /* pa1: LR(symbol - GP, addend */
+ RELOC_DPREL14WR, /* pa1: RR(symbol - GP, addend */
+ RELOC_DPREL14DR, /* pa1: RR(symbol - GP, addend */
+ RELOC_DPREL14R, /* pa1: RR(symbol - GP, addend */
+ RELOC_GPREL21L = 26, /* LR(symbol - GP, addend */
+ RELOC_GPREL14R = 30, /* RR(symbol - GP, addend */
+ RELOC_LTOFF21L = 34, /* L(ltoff(symbol + addend)) */
+ RELOC_LTOFF14R = 38, /* R(ltoff(symbol + addend)) */
+ RELOC_LTOFF14F, /* pa1: ltoff(symbol + addend) */
+ RELOC_SETBASE, /* no relocation; base = symbol */
+ RELOC_SECREL32, /* symbol - SECT + addend */
+ RELOC_BASEREL21L, /* pa1: LR(symbol - base, addend) */
+ RELOC_BASEREL17R, /* pa1: RR(symbol - base, addend) */
+ RELOC_BASEREL14R = 46, /* pa1: RR(symbol - base, addend) */
+ RELOC_SEGBASE = 48, /* no relocation; SB = symbol */
+ RELOC_SEGREL32, /* symbol - SB + addend */
+ RELOC_PLTOFF21L, /* LR(pltoff(symbol), addend */
+ RELOC_PLTOFF14R = 54, /* RR(pltoff(symbol), addend */
+ RELOC_PLTOFF14F, /* pa1: pltoff(symbol) + addend */
+ RELOC_LTOFF_FPTR32 = 57,/* pa2: ltoff(fptr(symbol + addend)) */
+ RELOC_LTOFF_FPTR21L, /* pa2: L(ltoff(fptr(symbol + addend))) */
+ RELOC_LTOFF_FPTR14R= 62,/* pa2: R(ltoff(fptr(symbol + addend))) */
+ RELOC_FPTR64 = 64, /* pa2: fptr(symbol + addend) */
+ RELOC_PLABEL32, /* pa1: fptr(symbol) */
+ RELOC_PCREL64 = 72, /* pa2: symbol - PC - 8 + addend */
+ RELOC_PCREL22C, /* pa1: symbol - PC - 8 + addend */
+ RELOC_PCREL22F, /* symbol - PC - 8 + addend */
+ RELOC_PCREL14WR, /* R(symbol - PC - 8 + addend) */
+ RELOC_PCREL14DR, /* R(symbol - PC - 8 + addend) */
+ RELOC_PCREL16F, /* pa2: symbol - PC - 8 + addend */
+ RELOC_PCREL16WF, /* pa2: symbol - PC - 8 + addend */
+ RELOC_PCREL16DF, /* pa2: symbol - PC - 8 + addend */
+ RELOC_DIR64, /* pa2: symbol + addend */
+ RELOC_DIR14WR = 83, /* RR(symbol, addend) */
+ RELOC_DIR14DR, /* RR(symbol, addend) */
+ RELOC_DIR16F, /* pa2: symbol + addend */
+ RELOC_DIR16WF, /* pa2: symbol + addend */
+ RELOC_DIR16DF, /* pa2: symbol + addend */
+ RELOC_GPREL64, /* pa2: symbol - GP + addend */
+ RELOC_GPREL14WR = 91, /* RR(symbol - GP, addend) */
+ RELOC_GPREL14DR, /* RR(symbol - GP, addend) */
+ RELOC_GPREL16F, /* pa2: symbol - GP + addend */
+ RELOC_GPREL16WF, /* pa2: symbol - GP + addend */
+ RELOC_GPREL16DF, /* pa2: symbol - GP + addend */
+ RELOC_LTOFF64 = 96, /* pa2: ltoff(symbol + addend) */
+ RELOC_LTOFF14WR = 99, /* R(ltoff(symbol + addend)) */
+ RELOC_LTOFF14DR, /* R(ltoff(symbol + addend)) */
+ RELOC_LTOFF16F, /* pa2: ltoff(symbol + addend) */
+ RELOC_LTOFF16WF, /* pa2: ltoff(symbol + addend) */
+ RELOC_LTOFF16DF, /* pa2: ltoff(symbol + addend) */
+ RELOC_SECREL64, /* pa2: symbol - SECT + addend */
+ RELOC_BASEREL14WR=107, /* pa1: RR(symbol - base, addend */
+ RELOC_BASEREL14DR, /* pa1: RR(symbol - base, addend */
+ RELOC_SEGREL64 = 112, /* pa2: symbol - SB + addend */
+ RELOC_PLTOFF14WR =115, /* RR(pltoff(symbol) + addend) */
+ RELOC_PLTOFF14DR, /* RR(pltoff(symbol) + addend) */
+ RELOC_PLTOFF16F, /* pa2: pltoff(symbol) + addend */
+ RELOC_PLTOFF16WF, /* pa2: pltoff(symbol) + addend */
+ RELOC_PLTOFF16DF, /* pa2: pltoff(symbol) + addend */
+ RELOC_LTOFF_FPTR64, /* pa2: ltoff(fptr(symbol + addend)) */
+ RELOC_LTOFF_FPTR14WR=123,/* pa2: R(ltoff(fptr(symbol + addend) */
+ RELOC_LTOFF_FPTR14DR, /* pa2: R(ltoff(fptr(symbol + addend) */
+ RELOC_LTOFF_FPTR16F, /* pa2: ltoff(fptr(symbol + addend)) */
+ RELOC_LTOFF_FPTR16WF, /* pa2: ltoff(fptr(symbol + addend)) */
+ RELOC_LTOFF_FPTR16DF, /* pa2: ltoff(fptr(symbol + addend)) */
+ RELOC_LORESERVE, /* reserved for environment-specific use */
+ RELOC_COPY = 128,
+ RELOC_IPLT,
+ RELOC_EPLT,
+ RELOC_GDATA,
+ RELOC_JMPSLOT,
+ RELOC_RELATIVE,
+ RELOC_HIRESERVE = 255
+};
+
+#endif /* _MACHINE_RELOC_H_ */
diff --git a/sys/arch/hppa64/include/setjmp.h b/sys/arch/hppa64/include/setjmp.h
new file mode 100644
index 00000000000..aee122ff95e
--- /dev/null
+++ b/sys/arch/hppa64/include/setjmp.h
@@ -0,0 +1,7 @@
+/* $OpenBSD: setjmp.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * machine/setjmp.h: machine dependent setjmp-related information.
+ */
+
+#define _JBLEN 48 /* size, in longs, of a jmp_buf */
diff --git a/sys/arch/hppa64/include/signal.h b/sys/arch/hppa64/include/signal.h
new file mode 100644
index 00000000000..c09fcd73ea1
--- /dev/null
+++ b/sys/arch/hppa64/include/signal.h
@@ -0,0 +1,57 @@
+/* $OpenBSD: signal.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 1994, The University of Utah and
+ * the Computer Systems Laboratory at the University of Utah (CSL).
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software is hereby
+ * granted provided that (1) source code retains these copyright, permission,
+ * and disclaimer notices, and (2) redistributions including binaries
+ * reproduce the notices in supporting documentation, and (3) all advertising
+ * materials mentioning features or use of this software display the following
+ * acknowledgement: ``This product includes software developed by the
+ * Computer Systems Laboratory at the University of Utah.''
+ *
+ * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
+ * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
+ * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * CSL requests users of this software to return to csl-dist@cs.utah.edu any
+ * improvements that they make and grant CSL redistribution rights.
+ *
+ * Utah $Hdr: signal.h 1.3 94/12/16$
+ */
+
+#ifndef _HPPA64_SIGNAL_H_
+#define _HPPA64_SIGNAL_H_
+
+/*
+ * Machine-dependent signal definitions
+ */
+
+typedef int sig_atomic_t;
+
+#ifndef _ANSI_SOURCE
+#include <machine/trap.h>
+
+/*
+ * Information pushed on stack when a signal is delivered.
+ * This is used by the kernel to restore state following
+ * execution of the signal handler. It is also made available
+ * to the handler to allow it to restore state properly if
+ * a non-standard exit is performed.
+ */
+struct sigcontext {
+ unsigned long sc_onstack; /* sigstack state to restore */
+ unsigned long sc_mask; /* signal mask to restore */
+ unsigned long sc_ps; /* psl to restore */
+ unsigned long sc_fp; /* fp to restore */
+ unsigned long sc_pcoqh; /* pc offset queue (head) to restore */
+ unsigned long sc_pcoqt; /* pc offset queue (tail) to restore */
+ unsigned long sc_resv[2];
+ unsigned long sc_regs[32];
+ unsigned long sc_fpregs[64];
+};
+#endif /* !_ANSI_SOURCE */
+#endif /* !_HPPA64_SIGNAL_H_ */
diff --git a/sys/arch/hppa64/include/spinlock.h b/sys/arch/hppa64/include/spinlock.h
new file mode 100644
index 00000000000..d9e362736c5
--- /dev/null
+++ b/sys/arch/hppa64/include/spinlock.h
@@ -0,0 +1,10 @@
+/* $OpenBSD: spinlock.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+#ifndef _MACHINE_SPINLOCK_H_
+#define _MACHINE_SPINLOCK_H_
+
+#define _SPINLOCK_UNLOCKED (1)
+#define _SPINLOCK_LOCKED (0)
+typedef long _spinlock_lock_t;
+
+#endif
diff --git a/sys/arch/hppa64/include/stdarg.h b/sys/arch/hppa64/include/stdarg.h
new file mode 100644
index 00000000000..5d0e1a203d9
--- /dev/null
+++ b/sys/arch/hppa64/include/stdarg.h
@@ -0,0 +1,62 @@
+/* $OpenBSD: stdarg.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)stdarg.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _MACHINE_STDARG_H_
+#define _MACHINE_STDARG_H_
+
+typedef double *va_list;
+
+#ifdef __GNUC__
+#define va_start(ap,lastarg) ((ap) = (va_list)__builtin_saveregs())
+#else
+#define va_start(ap,lastarg) __builtin_va_start(ap, &lastarg)
+#endif
+
+#define va_arg(ap,type) \
+ (sizeof(type) > 8 ? \
+ ((ap = (va_list) ((char *)ap - sizeof (int))), \
+ (*((type *) (void *) (*((int *) (ap)))))): \
+ ((ap = (va_list) ((long)((char *)ap - sizeof (type)) & \
+ (sizeof(type) > 4 ? ~0x7 : ~0x3))),\
+ (*((type *) (void *) ((char *)ap + ((8 - sizeof(type)) % 4))))))
+
+#if !defined(_ANSI_SOURCE) && \
+ (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE) || \
+ defined(_ISOC99_SOURCE) || (__STDC_VERSION__ - 0) >= 199901L)
+#define va_copy(dest, src) \
+ ((dest) = (src))
+#endif
+
+#define va_end(ap)
+
+#endif /* !_MACHINE_STDARG_H */
diff --git a/sys/arch/hppa64/include/trap.h b/sys/arch/hppa64/include/trap.h
new file mode 100644
index 00000000000..16014a425b2
--- /dev/null
+++ b/sys/arch/hppa64/include/trap.h
@@ -0,0 +1,91 @@
+/* $OpenBSD: trap.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _MACHINE_TRAP_H_
+#define _MACHINE_TRAP_H_
+
+/*
+ * This is PA-RISC trap types per 1.1 specs, see .c files for references.
+ */
+#define T_NONEXIST 0 /* invalid interrupt vector */
+#define T_HPMC 1 /* high priority machine check */
+#define T_POWERFAIL 2 /* power failure */
+#define T_RECOVERY 3 /* recovery counter */
+#define T_INTERRUPT 4 /* external interrupt */
+#define T_LPMC 5 /* low-priority machine check */
+#define T_ITLBMISS 6 /* instruction TLB miss fault */
+#define T_IPROT 7 /* instruction protection */
+#define T_ILLEGAL 8 /* Illegal instruction */
+#define T_IBREAK 9 /* break instruction */
+#define T_PRIV_OP 10 /* privileged operation */
+#define T_PRIV_REG 11 /* privileged register */
+#define T_OVERFLOW 12 /* overflow */
+#define T_CONDITION 13 /* conditional */
+#define T_EXCEPTION 14 /* assist exception */
+#define T_DTLBMISS 15 /* data TLB miss */
+#define T_ITLBMISSNA 16 /* ITLB non-access miss */
+#define T_DTLBMISSNA 17 /* DTLB non-access miss */
+#define T_DPROT 18 /* data protection/rights/alignment <7100 */
+#define T_DBREAK 19 /* data break */
+#define T_TLB_DIRTY 20 /* TLB dirty bit */
+#define T_PAGEREF 21 /* page reference */
+#define T_EMULATION 22 /* assist emulation */
+#define T_HIGHERPL 23 /* higher-privelege transfer */
+#define T_LOWERPL 24 /* lower-privilege transfer */
+#define T_TAKENBR 25 /* taken branch */
+#define T_DATACC 26 /* data access rights >=7100 */
+#define T_DATAPID 27 /* data protection ID >=7100 */
+#define T_DATALIGN 28 /* unaligned data ref */
+#define T_PERFMON 29 /* performance monitor interrupt */
+#define T_IDEBUG 30 /* debug SFU interrupt */
+#define T_DDEBUG 31 /* debug SFU interrupt */
+
+/*
+ * Reserved range for traps is 0-63, place user flag at 6th bit
+ */
+#define T_USER_POS 57
+#define T_USER (1 << (63 - T_USER_POS))
+
+/*
+ * Various trap frame flags.
+ */
+#define TFF_LAST_POS 40
+#define TFF_SYS_POS 41
+#define TFF_INTR_POS 42
+
+#define TFF_LAST (1 << (63 - TFF_LAST_POS))
+#define TFF_SYS (1 << (63 - TFF_SYS_POS))
+#define TFF_INTR (1 << (63 - TFF_INTR_POS))
+
+/*
+ * Define this for pretty printings of trapflags.
+ */
+#define T_BITS "\020\07user\036intr\037itlb\040last"
+
+/*
+ * These are break instruction entry points.
+ */
+/* im5 */
+#define HPPA_BREAK_KERNEL 0
+/* im13 */
+#define HPPA_BREAK_KGDB 5
+#define HPPA_BREAK_GET_PSW 9
+#define HPPA_BREAK_SET_PSW 10
+
+#endif /* _MACHINE_TRAP_H_ */
diff --git a/sys/arch/hppa64/include/types.h b/sys/arch/hppa64/include/types.h
new file mode 100644
index 00000000000..b098db4f83c
--- /dev/null
+++ b/sys/arch/hppa64/include/types.h
@@ -0,0 +1,81 @@
+/* $OpenBSD: types.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)types.h 8.3 (Berkeley) 1/5/94
+ */
+
+#ifndef _MACHINE_TYPES_H_
+#define _MACHINE_TYPES_H_
+
+#if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
+typedef struct label_t {
+ int lbl_rp;
+ int lbl_sp;
+ int lbl_s[17];
+ int lbl_ss[1];
+ double lbl_sf[10]; /* hp800:fr12-fr15, hp700:fr12-fr21 */
+} label_t;
+
+typedef unsigned long hppa_hpa_t;
+typedef unsigned long hppa_spa_t;
+typedef unsigned int pa_space_t;
+typedef unsigned long vaddr_t;
+typedef unsigned long vsize_t;
+typedef unsigned long paddr_t;
+typedef unsigned long psize_t;
+#endif
+
+/*
+ * Basic integral types. Omit the typedef if
+ * not possible for a machine/compiler combination.
+ */
+#define __BIT_TYPES_DEFINED__
+typedef __signed char int8_t;
+typedef unsigned char u_int8_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;
+typedef unsigned short u_int16_t;
+typedef unsigned short uint16_t;
+typedef int int32_t;
+typedef unsigned int u_int32_t;
+typedef unsigned int uint32_t;
+typedef long int64_t;
+typedef unsigned long u_int64_t;
+typedef unsigned long uint64_t;
+
+typedef int64_t register_t;
+
+typedef long int __intptr_t;
+typedef unsigned long int __uintptr_t;
+
+#define __HAVE_DEVICE_REGISTER
+#define __HAVE_CPUINFO
+
+#endif /* _MACHINE_TYPES_H_ */
diff --git a/sys/arch/hppa64/include/varargs.h b/sys/arch/hppa64/include/varargs.h
new file mode 100644
index 00000000000..f0ddb6d4709
--- /dev/null
+++ b/sys/arch/hppa64/include/varargs.h
@@ -0,0 +1,17 @@
+/* $OpenBSD: varargs.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+#ifndef _MACHINE_VARARGS_H_
+#define _MACHINE_VARARGS_H_
+
+#include <machine/stdarg.h>
+
+#define __va_ellipsis ...
+
+#define va_alist __builtin_va_alist
+#define va_dcl long __builtin_va_alist; __va_ellipsis
+
+#undef va_start
+#define va_start(ap) \
+ ((ap) = (va_list)&__builtin_va_alist)
+
+#endif /* !_MACHINE_VARARGS_H */
diff --git a/sys/arch/hppa64/include/vmparam.h b/sys/arch/hppa64/include/vmparam.h
new file mode 100644
index 00000000000..88e16e672b4
--- /dev/null
+++ b/sys/arch/hppa64/include/vmparam.h
@@ -0,0 +1,105 @@
+/* $OpenBSD: vmparam.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 1988-1994, The University of Utah and
+ * the Computer Systems Laboratory at the University of Utah (CSL).
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software is hereby
+ * granted provided that (1) source code retains these copyright, permission,
+ * and disclaimer notices, and (2) redistributions including binaries
+ * reproduce the notices in supporting documentation, and (3) all advertising
+ * materials mentioning features or use of this software display the following
+ * acknowledgement: ``This product includes software developed by the
+ * Computer Systems Laboratory at the University of Utah.''
+ *
+ * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
+ * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
+ * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * CSL requests users of this software to return to csl-dist@cs.utah.edu any
+ * improvements that they make and grant CSL redistribution rights.
+ *
+ * Utah $Hdr: vmparam.h 1.16 94/12/16$
+ */
+
+#ifndef _MACHINE_VMPARAM_H_
+#define _MACHINE_VMPARAM_H_
+
+/*
+ * Machine dependent constants for HP PA
+ */
+/*
+ * USRTEXT is the start of the user text/data space, while USRSTACK
+ * is the bottm (start) of the user stack.
+ */
+#define USRTEXT PAGE_SIZE /* Start of user .text */
+#define USRSTACK 0x68FF3000 /* Start of user stack */
+#define SYSCALLGATE 0xC0000000 /* syscall gateway page */
+
+/*
+ * Virtual memory related constants, all in bytes
+ */
+#ifndef MAXTSIZ
+#define MAXTSIZ (64*1024*1024) /* max text size */
+#endif
+#ifndef DFLDSIZ
+#define DFLDSIZ (16*1024*1024) /* initial data size limit */
+#endif
+#ifndef MAXDSIZ
+#define MAXDSIZ (1*1024*1024*1024) /* max data size */
+#endif
+#ifndef DFLSSIZ
+#define DFLSSIZ (512*1024) /* initial stack size limit */
+#endif
+#ifndef MAXSSIZ
+#define MAXSSIZ (32*1024*1024) /* max stack size */
+#endif
+
+#ifndef USRIOSIZE
+#define USRIOSIZE ((2*HPPA_PGALIAS)/PAGE_SIZE) /* 2mb */
+#endif
+
+/*
+ * PTEs for system V style shared memory.
+ * This is basically slop for kmempt which we actually allocate (malloc) from.
+ */
+#ifndef SHMMAXPGS
+#define SHMMAXPGS 8192 /* 32mb */
+#endif
+
+#define VM_MIN_ADDRESS (0UL)
+#define VM_MAXUSER_ADDRESS (0x20000000000UL)
+#define VM_MAX_ADDRESS VM_MAXUSER_ADDRESS
+#define VM_MIN_KERNEL_ADDRESS (0x1000000000UL)
+#define VM_MAX_KERNEL_ADDRESS (0x10f0000000UL)
+
+/* virtual sizes (bytes) for various kernel submaps */
+#define VM_PHYS_SIZE (USRIOSIZE*PAGE_SIZE)
+
+#define VM_PHYSSEG_MAX 8 /* this many physmem segments */
+#define VM_PHYSSEG_STRAT VM_PSTRAT_BIGFIRST
+
+#define VM_PHYSSEG_NOADD /* XXX until uvm code is fixed */
+
+#define VM_NFREELIST 2
+#define VM_FREELIST_DEFAULT 0
+#define VM_FREELIST_ARCH 1
+
+#if defined(_KERNEL) && !defined(_LOCORE)
+#define __HAVE_VM_PAGE_MD
+struct pv_entry;
+struct vm_page_md {
+ struct simplelock pvh_lock; /* locks every pv on this list */
+ struct pv_entry *pvh_list; /* head of list (locked by pvh_lock) */
+ u_int pvh_attrs; /* to preserve ref/mod */
+};
+
+#define VM_MDPAGE_INIT(pg) do { \
+ simple_lock_init(&(pg)->mdpage.pvh_lock); \
+ (pg)->mdpage.pvh_list = NULL; \
+ (pg)->mdpage.pvh_attrs = 0; \
+} while (0)
+#endif
+
+#endif /* _MACHINE_VMPARAM_H_ */
diff --git a/sys/arch/hppa64/stand/Makefile b/sys/arch/hppa64/stand/Makefile
new file mode 100644
index 00000000000..296da014aa6
--- /dev/null
+++ b/sys/arch/hppa64/stand/Makefile
@@ -0,0 +1,11 @@
+# $OpenBSD: Makefile,v 1.1 2005/04/01 10:40:48 mickey Exp $
+
+.if ${MACHINE} == "hppa64"
+SUBDIR= libsa libkern libz
+.endif
+SUBDIR+= mkboot boot
+.if ${MACHINE} == "hppa64"
+#SUBDIR+= cdboot
+.endif
+
+.include <bsd.subdir.mk>
diff --git a/sys/arch/hppa64/stand/Makefile.inc b/sys/arch/hppa64/stand/Makefile.inc
new file mode 100644
index 00000000000..2f7a45dcf73
--- /dev/null
+++ b/sys/arch/hppa64/stand/Makefile.inc
@@ -0,0 +1,44 @@
+# $OpenBSD: Makefile.inc,v 1.1 2005/04/01 10:40:48 mickey Exp $
+
+CFLAGS=${DEBUG} -Os -Wall -Werror
+CPPFLAGS+=-I${S} -I. -I${.CURDIR} -Derrno=errno
+SACFLAGS=-nostdinc -fno-builtin -D_STANDALONE -I${STANDIR}/libsa
+SACFLAGS+=-mdisable-fpregs -fno-stack-protector
+#DEBUGFLAGS=-DDEBUG
+#DEBUGFLAGS+=-DPDCDEBUG
+#DEBUGFLAGS+=-DLIFDEBUG
+#DEBUGFLAGS+=-DEXEC_DEBUG
+#DEBUGFLAGS+=-DALLOC_TRACE
+LINKADDR=0x780000
+LOADADDR=0x780000
+HEAP_LIMIT=0x7f8000
+CLEANFILES+= machine
+DEBUGLIBS= no
+
+.if !make(libdep) && !make(sadep) && !make(salibdir) && !make(kernlibdir) && !make(obj) && !(defined(PROG) && ${PROG} == "mkboot")
+.BEGIN:
+ @([ -h machine ] || ln -s $(S)/arch/hppa64/include machine)
+.endif
+
+.if exists(${STANDIR}/libsa/libsa.a)
+LIBSA=${STANDIR}/libsa/libsa.a
+.else
+LIBSA=${STANDIR}/libsa/${__objdir}/libsa.a
+.endif
+.if exists(${STANDIR}/libkern/libkern.a)
+LIBKERN=${STANDIR}/libkern/libkern.a
+.else
+LIBKERN=${STANDIR}/libkern/${__objdir}/libkern.a
+.endif
+.if exists(${STANDIR}/libz/libz.a)
+LIBZ=${STANDIR}/libz/libz.a
+.else
+LIBZ=${STANDIR}/libz/${__objdir}/libz.a
+.endif
+.if exists(${STANDIR}/mkboot/mkboot)
+MKBOOT=${STANDIR}/mkboot/mkboot
+.else
+MKBOOT=${STANDIR}/mkboot/${__objdir}/mkboot
+.endif
+
+BINDIR= /usr/mdec
diff --git a/sys/arch/hppa64/stand/boot/Makefile b/sys/arch/hppa64/stand/boot/Makefile
new file mode 100644
index 00000000000..dd9bc44c62f
--- /dev/null
+++ b/sys/arch/hppa64/stand/boot/Makefile
@@ -0,0 +1,60 @@
+# $OpenBSD: Makefile,v 1.1 2005/04/01 10:40:48 mickey Exp $
+
+MAN= boot.8
+MANSUBDIR=hppa64
+MLINKS= boot.8 boot.conf.8
+S =${.CURDIR}/../../../..
+CLEANFILES+= boot.gdb boot.map boot.lif
+
+.if ${MACHINE} == "hppa64"
+PROG= boot
+SRCS= srt0.S exec.c boot.c cmd.c vars.c bootarg.c conf.c
+LD?= ld
+LDFLAGS+=-Bstatic -nostartfiles -nostdlib -N -Ttext $(LINKADDR)
+LDFLAGS+=-T ${.CURDIR}/ld.script -Map boot.map
+LDFLAGS+=--warn-constructors --warn-common
+SIZE?= size
+STRIP?= strip
+STANDIR=${.CURDIR}/..
+CRTBEGIN=
+CRTEND=
+LINKS= ${BINDIR}/boot.lif ${BINDIR}/sdboot \
+ ${BINDIR}/boot.lif ${BINDIR}/stboot \
+ ${BINDIR}/boot.lif ${BINDIR}/xxboot
+
+LDADD= ${LIBSA} ${LIBZ} ${LIBKERN}
+DPADD= ${LIBSA} ${LIBZ} ${LIBKERN}
+
+.PATH: ${S}/stand/boot
+
+all: boot.lif
+
+realinstall:
+ ${INSTALL} ${INSTALL_COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
+ boot ${DESTDIR}${BINDIR}
+ ${INSTALL} ${INSTALL_COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
+ boot.lif ${DESTDIR}${BINDIR}
+
+.if exists(${.CURDIR}/../../compile/GENERIC/bsd)
+bsd: ${.CURDIR}/../../compile/GENERIC/bsd
+ gzip -9 -c ${.CURDIR}/../../compile/GENERIC/bsd > bsd
+ADDBOOT+=bsd
+.endif
+
+# probably we should check for 256k limit for ISL
+boot.lif: ${PROG} ${ADDBOOT}
+ -@cp ${PROG} ${PROG}.gdb
+ ${STRIP} ${PROG}
+ ${MKBOOT} -v ${PROG} ${ADDBOOT} boot.lif
+
+${PROG}: $(OBJS) $(DPADD)
+ $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LDADD)
+ @${SIZE} $(PROG)
+.else
+NOPROG=
+.endif
+
+.include <bsd.prog.mk>
+
+CPPFLAGS+=${DEBUGFLAGS} -DRELOC=${LOADADDR} -DHEAP_LIMIT=${HEAP_LIMIT}
+CFLAGS+=$(SACFLAGS)
diff --git a/sys/arch/hppa64/stand/boot/boot.8 b/sys/arch/hppa64/stand/boot/boot.8
new file mode 100644
index 00000000000..4b52dabbe02
--- /dev/null
+++ b/sys/arch/hppa64/stand/boot/boot.8
@@ -0,0 +1,342 @@
+.\" $OpenBSD: boot.8,v 1.1 2005/04/01 10:40:48 mickey Exp $
+.\"
+.\" Copyright (c) 2002 Miodrag Vallat
+.\" Copyright (c) 1997-2005 Michael Shalayeff
+.\" 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 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 HIS RELATIVES 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 MIND, 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.
+.\"
+.\"
+.Dd March 16, 2005
+.Dt BOOT 8 hppa
+.Os
+.Sh NAME
+.Nm boot ,
+.Nm boot.conf
+.Nd
+hppa-specific bootstrap
+.Sh DESCRIPTION
+The main purpose of this program is to load the system kernel while dealing
+with the various features of the PA-RISC hardware.
+.Pp
+As described in
+.Xr boot_hppa 8 ,
+this program is loaded by the PDC firmware
+and provides a convenient way to load the kernel.
+.Pp
+Basic operations include:
+.Pp
+.Bl -bullet -compact
+.It
+Loading kernels from any device supported by your system.
+.It
+Loading kernels compressed by
+.Xr gzip 1 .
+.It
+Providing an interactive command line.
+.It
+Detecting and switching between multiple consoles.
+.El
+.Pp
+The sequence of its operation is as follows: initialization,
+parsing the configuration file, then an interactive command line.
+While at the command line you have 5 seconds to type any commands, if needed.
+If time expires, the kernel will be loaded according to
+the current variable settings (see the
+.Nm set
+command).
+Each time a kernel load fails, the timeout is increased by one second.
+The sequence of
+.Nm
+operations is as follows:
+.Bl -enum
+.It
+If the file
+.Pa /etc/boot.conf
+exists on the filesystem or LIF image
+.Nm
+was loaded from, open and parse it.
+This file may contain any commands
+.Nm
+accepts at the interactive prompt.
+Though default settings usually suffice, they can be changed here.
+.It
+The header line
+.Pp
+.Dl >> OpenBSD/hppa BOOT [x.xx]
+.Pp
+is displayed to the active console, where
+.Ar x.xx
+is the version number of the
+.Nm
+program, followed by the
+.Pp
+.Dl boot>
+.Pp
+prompt, which means you are in interactive mode and may enter commands.
+If you do not,
+.Nm
+will proceed to load the kernel with the current parameters after the
+timeout period has expired.
+.El
+.Pp
+By default,
+.Nm
+attempts to load the kernel executable
+.Pa /bsd .
+If that fails, it will attempt to load
+.Pa /obsd
+and then
+.Pa /bsd.old .
+If it fails to find any of these files,
+and no alternative kernel image has been specified,
+the system will be unable to boot.
+.Sh COMMANDS
+The following commands are accepted at the
+.Nm
+prompt:
+.Bl -tag -width shorten
+.It boot Op Ar image Op Fl acds
+Boots the kernel image specified by
+.Ar image
+with any options given.
+Image specification consists of a pair
+.Ar device : Ns Ar filename ;
+either or both can be omitted (`:' is not needed if both are omitted),
+in which case values from
+.Nm
+variables will be used.
+.Bl -tag -width _a_
+.It Fl a
+Causes the kernel to ask for the
+.Nm root
+device to use.
+.It Fl c
+Causes the kernel to go into
+.Xr boot_config 8
+before performing
+.Xr autoconf 4
+procedures.
+.It Fl d
+Causes the kernel to drop into
+.Xr ddb 4
+at the earliest convenient point.
+.It Fl s
+Causes the kernel to boot single-user.
+.El
+.It echo Op Ar args
+Displays
+.Ar args
+on the console device.
+.It help
+Prints a list of available commands and machine dependent
+commands, if any.
+.It machine Op Ar command
+Issues machine-dependent commands.
+These are defined for hppa architecture:
+.Bl -tag -width keyboard
+.It Nm console
+Displays or sets the console path.
+.Pp
+When invoked with no argument, this command will display the configured
+console path found in the stable storage area.
+.Pp
+Otherwise, the argument will be interpreted as a console path
+definition string, and
+.Nm
+will attempt to switch the console configuration to the desired device.
+The console definition attempts to follow the PDC syntax,
+and would have a form of:
+.Pp
+.Bd -filled -compact
+graphics
+.Op _head
+.Op .mode
+.Ed
+for graphics console, and
+.Pp
+.Bd -filled -compact
+rs232
+.Op _2
+.Op .speed Op .bits Op .parity
+.Ed
+for serial console.
+.Pp
+The default head and mode for graphics console are 0, that is the default
+videomode of the first graphics device.
+The default serial settings are 9600 bps, 8 data bits, and no parity.
+.It Nm keyboard
+Displays or sets the keyboard path.
+.Pp
+When invoked with no argument, this command will display the configured
+keyboard path found in the stable storage area.
+.Pp
+Otherwise, the argument will be interpreted as a keyboard path definition
+string, and
+.Nm
+will attempt to switch the keyboard configuration to the desired port.
+The keyboard definition attempts to follow the PDC syntax,
+and would have a form of:
+.Pp
+.Bd -filled -compact
+hil
+.Ed
+for hil keyboard, and
+.Pp
+.Bd -filled -compact
+ps2
+.Ed
+for PS/2 keyboard.
+.El
+.Pp
+After changing any path settings, the machine usually has to be restarted for
+the changes to have effect.
+.It ls Op Ar directory
+Prints contents of the specified
+.Ar directory
+in long format including: attributes and file type, owner, group,
+size, filename.
+.It reboot
+Reboots the machine by initiating a warm boot procedure.
+.It set Op Ar varname Op Ar value
+If invoked without arguments, prints a list of variables and their values.
+If only
+.Ar varname
+is specified, displays contents of that variable.
+If
+.Ar varname
+and
+.Ar value
+are both specified, sets that variable to the given value.
+Variables include:
+.Pp
+.Bl -tag -compact -width boothow
+.It Nm addr
+Address at which to load the kernel.
+.It Nm debug
+Debug flag if
+.Nm
+was compiled with DEBUG defined.
+.It Nm device
+Boot device name (i.e.,
+.Li lf0a ,
+.Li sd0a ) .
+.It Nm howto
+Options to pass to the loaded kernel.
+.It Nm image
+File name containing the kernel image.
+.It Nm timeout
+Number of seconds boot will wait for human intervention before
+booting the default kernel image.
+.\" .It Nm tty
+.\" Active console device name (i.e.,
+.\" .Li ttya ,
+.\" .Li ttyb ,
+.\" .Li ite0) .
+.El
+.\" .It stty Op Ar device Op Ar speed
+.\" Displays or sets the
+.\" .Ar speed
+.\" for a console
+.\" .Ar device .
+.\" If changing the baudrate for the currently active console,
+.\" .Nm
+.\" offers you five seconds of grace time before committing the change
+.\" to allow you to change your terminal's speed to match.
+.\" If changing speed
+.\" .Em not
+.\" for the active console, the baudrate is set for the
+.\" .Em next
+.\" time you switch to a serial console.
+.\" The baudrate value is not used for the
+.\" .Li ite0
+.\" console.
+.\" .Pp
+.\" The default baudrate is 9600bps.
+.It time
+Displays system time and date.
+.El
+.Sh FILES
+.Bl -tag -width /etc/boot.conf -compact
+.It Pa /boot
+system bootstrap
+.It Pa /etc/boot.conf
+system bootstrap's startup file
+.It Pa /bsd
+kernel image
+.El
+.Sh EXAMPLES
+Boot the default kernel:
+.Pp
+.Dl boot> boot
+.Pp
+Remove the 5 second pause at boot-time permanently, causing
+.Nm
+to load the kernel immediately without prompting:
+.Pp
+.Dl # echo \&"boot\&" > /etc/boot.conf
+.Pp
+Use serial console on the first serial port, with the usual 9600 8N1 settings.
+A null modem cable should connect the specified serial port to a terminal.
+Useful for debugging.
+.Pp
+.Dl boot> machine console rs232.9600.8.none
+.Pp
+Boot the kernel named
+.Pa /bsd
+from the second SCSI disk in
+.Dq User Kernel Configuration
+mode (see
+.Xr boot_config 8 ) .
+This mechanism allows for the explicit enabling and disabling of devices
+during the current boot sequence, as well as the modification
+of device parameters.
+Once booted, such changes can be made permanent by using
+.Xr config 8 Ns 's
+.Fl e
+option.
+.Pp
+.Dl boot> boot sd1a:/bsd -c
+.Sh SEE ALSO
+.Xr gzip 1 ,
+.Xr autoconf 4 ,
+.Xr ddb 4 ,
+.Xr boot_config 8 ,
+.Xr boot_hppa 8 ,
+.\" .Xr installboot 8 ,
+.Xr reboot 8
+.Pp
+RFC 1950 describes the zlib library interface.
+.Pp
+The official home page for the version of zlib used in this
+operating system see http://quest.jpl.nasa.gov/zlib/.
+.Sh HISTORY
+This program was written by Michael Shalayeff for
+.Ox 2.1 .
+The hppa specific parts were written by Michael Shalayeff and Miodrag Vallat
+for
+.Ox 3.1 .
+.Sh CAVEATS
+Making mistakes in console paths may cost you a toupee.
+.Sh BUGS
+Changing the display resolution (mode) on a graphics console does not work
+correctly.
diff --git a/sys/arch/hppa64/stand/boot/conf.c b/sys/arch/hppa64/stand/boot/conf.c
new file mode 100644
index 00000000000..91ecd77b2b1
--- /dev/null
+++ b/sys/arch/hppa64/stand/boot/conf.c
@@ -0,0 +1,51 @@
+/* $OpenBSD: conf.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <libsa.h>
+#include <lib/libsa/ufs.h>
+#include <lib/libsa/cd9660.h>
+#include <dev/cons.h>
+
+const char version[] = "0.8";
+int debug = 0;
+
+struct fs_ops file_system[] = {
+ { ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek,
+ ufs_stat, ufs_readdir },
+ { cd9660_open, cd9660_close, cd9660_read, cd9660_write, cd9660_seek,
+ cd9660_stat, cd9660_readdir },
+ { lif_open, lif_close, lif_read, lif_write, lif_seek,
+ lif_stat, lif_readdir },
+};
+int nfsys = NENTS(file_system);
+
+struct devsw devsw[] = {
+ { "dk", iodcstrategy, dkopen, dkclose, noioctl },
+ { "ct", iodcstrategy, ctopen, ctclose, noioctl },
+ { "lf", iodcstrategy, lfopen, lfclose, noioctl }
+};
+int ndevs = NENTS(devsw);
+
+struct consdev constab[] = {
+ { ite_probe, ite_init, ite_getc, ite_putc },
+ { NULL }
+};
+struct consdev *cn_tab;
+
diff --git a/sys/arch/hppa64/stand/boot/exec.c b/sys/arch/hppa64/stand/boot/exec.c
new file mode 100644
index 00000000000..adc206b3a19
--- /dev/null
+++ b/sys/arch/hppa64/stand/boot/exec.c
@@ -0,0 +1,42 @@
+/* $OpenBSD: exec.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <machine/pdc.h>
+#include "libsa.h"
+#include <lib/libsa/loadfile.h>
+#include <stand/boot/bootarg.h>
+#include "dev_hppa64.h"
+
+typedef void (*startfuncp)(int, int, int, int, int, int, caddr_t)
+ __attribute__ ((noreturn));
+
+void
+run_loadfile(u_long *marks, int howto)
+{
+ fcacheall();
+
+ __asm("mtctl %r0, %cr17");
+ __asm("mtctl %r0, %cr17");
+ /* stack and the gung is ok at this point, so, no need for asm setup */
+ (*(startfuncp)(marks[MARK_ENTRY]))((int)(long)(long)pdc, howto, bootdev,
+ marks[MARK_END], BOOTARG_APIVER, BOOTARG_LEN, (caddr_t)BOOTARG_OFF);
+
+ /* not reached */
+}
diff --git a/sys/arch/hppa64/stand/boot/ld.script b/sys/arch/hppa64/stand/boot/ld.script
new file mode 100644
index 00000000000..51aed14df19
--- /dev/null
+++ b/sys/arch/hppa64/stand/boot/ld.script
@@ -0,0 +1,61 @@
+/* $OpenBSD: ld.script,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+OUTPUT_FORMAT("elf64-hppa")
+OUTPUT_ARCH(hppa2.0w)
+ENTRY(begin)
+
+SECTIONS {
+
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .text : {
+ *(.text)
+ *(.text.*)
+ *(.rodata)
+ *(.rodata1)
+ *($CODE$)
+ etext = .;
+ } = 0x08000240
+
+ /* Read-write sections, merged into data segment: */
+ .data : {
+ $global$ = .;
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ edata = ABSOLUTE(.);
+ } = 0
+
+ .opd : { *(.opd) }
+ PROVIDE(__gp = .);
+ .plt : { *(.plt) }
+ .dlt : { *(.dlt) }
+
+ .bss : {
+ __bss_start = .;
+ *(.dynbss)
+ *(.bss)
+ *(.sbss)
+ *(.scommon)
+ *(COMMON)
+ end = ABSOLUTE(.);
+ __bss_end = .;
+ }
+
+ /* don't need an unwind in the boot, unless we'll have a boot-ddb (; */
+ /DISCARD/ :
+ {
+ *(.PARISC.unwind)
+ *(.exitcall.exit)
+ *(.interp)
+ *(.dynsym)
+ *(.dynstr)
+ *(.dynamic)
+ *(.hash)
+ *(.stub)
+ }
+}
+
diff --git a/sys/arch/hppa64/stand/boot/srt0.S b/sys/arch/hppa64/stand/boot/srt0.S
new file mode 100644
index 00000000000..99498dbf970
--- /dev/null
+++ b/sys/arch/hppa64/stand/boot/srt0.S
@@ -0,0 +1,181 @@
+/* $OpenBSD: srt0.S,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+;
+; Copyright (c) 1990 mt Xinu, Inc. All rights reserved.
+; Copyright (c) 1990 University of Utah. All rights reserved.
+;
+; This file may be freely distributed in any form as long as
+; this copyright notice is included.
+; THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+; IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+; WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+;
+; Utah $Hdr: srt0.c 1.3 94/12/13$
+;
+
+#define _LOCORE
+#include <machine/iomod.h>
+#include <machine/asm.h>
+#include <machine/frame.h>
+
+/*
+ * This is the ending of the begin
+ */
+ENTRY(begin,0)
+
+ blr %r0,%r5 ; Get address of 'boff' into 'r5',
+ ldo begin-boff(%r5),%r5 ; and subtract to get 'begin'.
+boff
+ ldil L%RELOC,%r4
+ ldo R%RELOC(%r4),%r4
+ ldo start-begin(%r4),%rp
+ ldil L%edata,%r3
+ ldo R%edata(%r3),%r3 ; Get address of edata.
+ ldil L%begin,%r1
+ ldo R%begin(%r1),%r1 ; Get address of begin
+ sub %r3,%r1,%r3 ; Subtract to get # of bytes to copy
+copyloop ; do
+ ldwm 4(%r5),%r1 ; *r4++ = *r5++;
+ addib,>= -4,%r3,copyloop ; while (--r3 >= 0);
+ stwm %r1,4(%r4)
+
+ ; here we zero the .bss
+ ldil L%__bss_start, %r4
+ ldo R%__bss_start(%r4), %r4
+ ldil L%__bss_end, %r3
+ ldo R%__bss_end(%r3), %r3
+zeroloop
+ combf,<,n %r3,%r4, zeroloop ; while (r4 < r3);
+ stwm %r0,4(%r4) ; *r4++ = 0;
+
+ ldil L%$global$,%dp
+ ldo R%$global$(%dp),%dp
+ ldil L%start,%r1
+ ldo R%start(%r1),%r1
+ sub %dp,%r1,%dp ; Subtract to get difference
+ add %rp,%dp,%dp ; and relocate it.
+
+;
+; We have relocated ourself to RELOC. If we are running on a machine
+; with separate instruction and data caches, we must flush our data
+; cache before trying to execute the code starting at rp.
+;
+ ldil L%RELOC,%r22 ; Set %t1 to start of relocated code.
+ ldo R%RELOC(%r22),%r22
+ ldil L%edata,%r21 ; Set r21 to address of edata
+ ldo R%edata(%r21),%r21
+ ldil L%begin,%r1 ; set %r1 to address of begin
+ ldo R%begin(%r1),%r1
+ sub %r21,%r1,%r21 ; Subtract to get length
+ mtsp %r0,%sr0 ; Set sr0 to kernel space.
+ ldo -1(%r21),%r21
+ fdc %r21(0,%r22)
+loop addib,>,n -16,%r21,loop ; Decrement by cache line size (16).
+ fdc %r21(%sr0,%r22)
+ fdc 0(%sr0,%r22) ; Flush first word at addr to handle
+ sync ; arbitrary cache line boundary.
+ nop ; Prevent prefetching.
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ bv 0(%rp)
+ nop
+EXIT(begin) /* jump to relocated code */
+
+start
+ ldil L%HEAP_LIMIT, %sp
+ ldo R%HEAP_LIMIT(%sp), %sp
+
+ .import bootprompt, data
+ ldil L%bootprompt, %r1
+ stw %arg0, R%bootprompt(%r1)
+ b boot ; Call boot(),
+ copy %r0, %arg0 ; use default boot device
+ nop
+
+/*
+ * rtt - restart the box
+ */
+LEAF_ENTRY(_rtt)
+ ldil L%LBCAST_ADDR, %arg1
+ ldi CMD_RESET, %arg0
+ stw %arg0, R%iomod_command(%arg1)
+forever ; Loop until bus reset takes effect.
+ b,n forever
+
+ bv 0(%rp)
+ ldo -48(%sp),%sp
+EXIT(_rtt)
+
+ENTRY(pdc_call,96)
+ copy %r3, %r1
+ std %rp, HPPA_FRAME_RP(%sp)
+ copy %sp, %r3
+ std,ma %r1, HPPA_FRAME_SIZE+8*4(%sp)
+
+ copy %arg0, %r1
+ copy %arg1, %arg0
+ copy %arg2, %arg1
+ copy %arg3, %arg2
+ copy arg4, %arg3
+ stw arg5, -(32 + 4*(4 + 1))(%sp)
+ stw arg6, -(32 + 4*(5 + 1))(%sp)
+ stw arg7, -(32 + 4*(6 + 1))(%sp)
+ ldw 0(ap), arg5
+ ldw 8(ap), arg6
+ ldw 16(ap), arg7
+ stw arg5, -(32 + 4*(7 + 1))(%sp)
+ stw arg6, -(32 + 4*(8 + 1))(%sp)
+ stw arg7, -(32 + 4*(9 + 1))(%sp)
+
+ .call
+ blr %r0, %rp
+ bv,n %r0(%r1)
+ nop
+
+ ldd HPPA_FRAME_RP(%r3), %rp
+ bv %r0(%rp)
+ ldd,mb -(HPPA_FRAME_SIZE+8*4)(%sp), %r3
+EXIT(pdc_call)
+
+ .end
diff --git a/sys/arch/hppa64/stand/cdboot/Makefile b/sys/arch/hppa64/stand/cdboot/Makefile
new file mode 100644
index 00000000000..6ff9c00821a
--- /dev/null
+++ b/sys/arch/hppa64/stand/cdboot/Makefile
@@ -0,0 +1,55 @@
+# $OpenBSD: Makefile,v 1.1 2005/04/01 10:40:48 mickey Exp $
+
+NOMAN= no man
+S =${.CURDIR}/../../../..
+CLEANFILES+= cdboot.gdb cdboot.map
+
+.if ${MACHINE} == "hppa64"
+
+PROG= cdboot
+SRCS= srt0.S cdboot.c pdc.c itecons.c dev_hppa64.c dk.c
+LD?= ld
+LDFLAGS+=-Bstatic -nostartfiles -nostdlib -N -Ttext $(LINKADDR)
+LDFLAGS+=-T ${.CURDIR}/ld.script -Map cdboot.map
+SIZE?= size
+STRIP?= strip
+STANDIR=${.CURDIR}/..
+CRTBEGIN=
+CRTEND=
+
+SAREL=
+USE_LOADFILE=yes
+.include "${S}/lib/libsa/Makefile.inc"
+DPADD+= $(SALIB) $(LIBKERN)
+LDADD+= $(SALIB) $(LIBKERN)
+
+.PATH: ${S}/stand/boot
+.PATH: ${.CURDIR}/../boot
+.PATH: ${.CURDIR}/../libsa
+
+all: ${PROG}
+
+clean::
+ rm -f a.out [Ee]rrs mklog core *.core \
+ ${PROG} ${OBJS} ${LOBJS} ${CLEANFILES}
+
+realinstall:
+ ${INSTALL} ${INSTALL_COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
+ ${PROG} ${DESTDIR}${BINDIR}
+
+# TODO check for <=32k
+${PROG}: $(OBJS) $(DPADD)
+ $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LDADD)
+ @cp ${PROG} ${PROG}.gdb
+ ${STRIP} ${PROG}
+ @${SIZE} $(PROG)
+ @${MKBOOT} -v ${PROG} ${PROG}.lif
+ @mv ${PROG}.lif ${PROG}
+.else
+NOPROG=
+.endif
+
+.include <bsd.prog.mk>
+
+CPPFLAGS+=-DRELOC=${LOADADDR} -DHEAP_LIMIT=${HEAP_LIMIT}
+CFLAGS+=$(SACFLAGS) -I../.. -I${.CURDIR}/../libsa -I${S}/stand/boot
diff --git a/sys/arch/hppa64/stand/cdboot/cdboot.c b/sys/arch/hppa64/stand/cdboot/cdboot.c
new file mode 100644
index 00000000000..2ceb33315df
--- /dev/null
+++ b/sys/arch/hppa64/stand/cdboot/cdboot.c
@@ -0,0 +1,82 @@
+/* $OpenBSD: cdboot.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/stat.h>
+#include <libsa.h>
+#include <lib/libsa/cd9660.h>
+#include <lib/libsa/loadfile.h>
+#include <dev/cons.h>
+#include <machine/pdc.h>
+#include <stand/boot/bootarg.h>
+#include "dev_hppa64.h"
+#include "cmd.h"
+
+dev_t bootdev;
+int debug = 1;
+int bootprompt = 1;
+
+struct fs_ops file_system[] = {
+ { cd9660_open, cd9660_close, cd9660_read, cd9660_write, cd9660_seek,
+ cd9660_stat, cd9660_readdir },
+};
+int nfsys = NENTS(file_system);
+
+struct devsw devsw[] = {
+ { "dk", iodcstrategy, dkopen, dkclose, noioctl },
+};
+int ndevs = NENTS(devsw);
+
+struct consdev constab[] = {
+ { ite_probe, ite_init, ite_getc, ite_putc },
+ { NULL }
+};
+struct consdev *cn_tab;
+
+typedef void (*startfuncp)(int, int, int, int, int, int, caddr_t)
+ __attribute__ ((noreturn));
+
+void
+boot(dev_t dev)
+{
+ u_long marks[MARK_MAX];
+ char path[128];
+
+ pdc_init();
+ cninit();
+ devboot(dev, path);
+ strncpy(path + strlen(path), ":/bsd.rd", 9);
+ printf(">> OpenBSD/" MACHINE " CDBOOT 0.1\n"
+ "booting %s: ", path);
+
+ marks[MARK_START] = (u_long)DEFAULT_KERNEL_ADDRESS;
+ if (!loadfile(path, marks, LOAD_KERNEL)) {
+ marks[MARK_END] = ALIGN(marks[MARK_END] -
+ (u_long)DEFAULT_KERNEL_ADDRESS);
+ fcacheall();
+
+ __asm("mtctl %r0, %cr17");
+ __asm("mtctl %r0, %cr17");
+ (*(startfuncp)(marks[MARK_ENTRY]))((int)(long)pdc, 0, bootdev,
+ marks[MARK_END], BOOTARG_APIVER, BOOTARG_LEN,
+ (caddr_t)BOOTARG_OFF);
+ /* not reached */
+ }
+}
diff --git a/sys/arch/hppa64/stand/cdboot/ld.script b/sys/arch/hppa64/stand/cdboot/ld.script
new file mode 100644
index 00000000000..b36df9be9e4
--- /dev/null
+++ b/sys/arch/hppa64/stand/cdboot/ld.script
@@ -0,0 +1,49 @@
+/* $OpenBSD: ld.script,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+OUTPUT_FORMAT("elf64-hppa")
+OUTPUT_ARCH(hppa2.0w)
+ENTRY(begin)
+
+SECTIONS {
+
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .text : {
+ *(.text)
+ *(.text.*)
+ *(.rodata)
+ *(.rodata1)
+ *($CODE$)
+ etext = .;
+ } = 0x08000240
+
+ /* Read-write sections, merged into data segment: */
+ .data : {
+ $global$ = .;
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.dynamic)
+ CONSTRUCTORS
+ edata = ABSOLUTE(.);
+ } = 0
+
+ .bss : {
+ __bss_start = .;
+ *(.dynbss)
+ *(.bss)
+ *(.sbss)
+ *(.scommon)
+ *(COMMON)
+ end = ABSOLUTE(.);
+ __bss_end = .;
+ }
+
+ /* don't need an unwind in the boot, unless we'll have a boot-ddb (; */
+ /DISCARD/ :
+ {
+ *(.PARISC.unwind)
+ }
+}
+
diff --git a/sys/arch/hppa64/stand/libkern/Makefile b/sys/arch/hppa64/stand/libkern/Makefile
new file mode 100644
index 00000000000..6815b67c49b
--- /dev/null
+++ b/sys/arch/hppa64/stand/libkern/Makefile
@@ -0,0 +1,29 @@
+# $OpenBSD: Makefile,v 1.1 2005/04/01 10:40:48 mickey Exp $
+
+LIB= kern
+
+S= ${.CURDIR}/../../../..
+M= ${KERNDIR}/arch/${MACHINE_ARCH}
+SADIR= ${.CURDIR}/..
+KERNDIR=$S/lib/libkern
+
+NOPIC= nopic
+NOPROFILE= noprofile
+
+.PATH: ${KERNDIR}
+
+.include "arch/hppa64/Makefile.inc"
+
+# Quad support
+SRCS+= adddi3.c anddi3.c ashldi3.c ashrdi3.c cmpdi2.c divdi3.c iordi3.c \
+ lshldi3.c lshrdi3.c moddi3.c muldi3.c negdi2.c notdi2.c qdivrem.c \
+ subdi3.c ucmpdi2.c udivdi3.c umoddi3.c xordi3.c
+
+# Other stuff
+SRCS+= srandom.c bcd.c
+
+install:
+
+.include <bsd.lib.mk>
+CPPFLAGS+= ${DEBUGFLAGS}
+CFLAGS+= ${SACFLAGS}
diff --git a/sys/arch/hppa64/stand/libsa/Makefile b/sys/arch/hppa64/stand/libsa/Makefile
new file mode 100644
index 00000000000..eda10f3436e
--- /dev/null
+++ b/sys/arch/hppa64/stand/libsa/Makefile
@@ -0,0 +1,43 @@
+# $OpenBSD: Makefile,v 1.1 2005/04/01 10:40:48 mickey Exp $
+
+.include "${.CURDIR}/../Makefile.inc"
+
+LIB= sa
+
+S=${.CURDIR}/../../../..
+SADIR=${.CURDIR}/..
+DIR_SA= $S/lib/libsa
+
+NOPROFILE=noprofile
+NOPIC=nopic
+
+#AS=cat ;
+#AS+= -R
+#AS+= -a
+
+# hppa64 stuff
+SRCS= machdep.c pdc.c itecons.c dev_hppa64.c time.c \
+ ct.c dk.c lf.c lif.c cmd_hppa64.c
+
+# stand routines
+SRCS+= alloc.c exit.c getfile.c gets.c globals.c \
+ printf.c strerror.c strtol.c strchr.c ctime.c loadfile.c snprintf.c
+
+# io routines
+SRCS+= close.c closeall.c dev.c disklabel.c dkcksum.c fstat.c ioctl.c lseek.c \
+ open.c read.c stat.c write.c cread.c readdir.c cons.c
+
+# boot filesystems
+SRCS+= ufs.c cd9660.c
+
+.PATH: ${DIR_SA}
+
+all: ${SALIB}
+
+install:
+
+.include <bsd.lib.mk>
+
+CPPFLAGS+=-DHEAP_LIMIT=${HEAP_LIMIT} ${DEBUGFLAGS} -DNO_NET
+CPPFLAGS+=-I${S}/stand/boot
+CFLAGS+=${SACFLAGS} -D__INTERNAL_LIBSA_CREAD -DCOMPAT_UFS
diff --git a/sys/arch/hppa64/stand/libsa/cmd_hppa64.c b/sys/arch/hppa64/stand/libsa/cmd_hppa64.c
new file mode 100644
index 00000000000..1aa6117cb07
--- /dev/null
+++ b/sys/arch/hppa64/stand/libsa/cmd_hppa64.c
@@ -0,0 +1,819 @@
+/* $OpenBSD: cmd_hppa64.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2002 Miodrag Vallat
+ * 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 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 HIS RELATIVES 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 MIND, 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.
+ */
+
+/*#define DEBUG*/
+
+#include <sys/param.h>
+/* would come from <sys/param.h> if -D_KERNEL */
+#define offsetof(s, e) ((size_t)&((s *)0)->e)
+
+#include <machine/iomod.h>
+#include <machine/pdc.h>
+
+#include <arch/hppa/dev/cpudevs.h>
+
+#include <libsa.h>
+#include "cmd.h"
+#include "dev_hppa64.h" /* pdc */
+
+extern struct stable_storage sstor;
+extern int sstorsiz;
+
+/* storage sizes we're interested in */
+#define CONSOLEOFFSET \
+ offsetof(struct stable_storage, ss_console)
+#define CONSOLESIZE \
+ (offsetof(struct stable_storage, ss_console) + \
+ sizeof(struct device_path))
+
+#define KEYBOARDOFFSET \
+ offsetof(struct stable_storage, ss_keyboard)
+#define KEYBOARDSIZE \
+ (offsetof(struct stable_storage, ss_keyboard) + \
+ sizeof(struct device_path))
+
+/*
+ * Table for the possible console devices found during the device walk.
+ */
+struct consoledev {
+ struct device_path dp;
+ int type;
+ int iodc_type;
+ int iodc_model;
+};
+
+#define PS2 1
+#define HIL 2
+#define SERIAL 3
+#define GRAPHICS 4
+
+/* max. serial ports */
+#define MAX_SERIALS 4
+/* max. HIL and PS2 */
+#define MAX_KEYBOARDS 2
+/* max. heads */
+#define MAX_GRAPHICS 4
+
+struct consoledev serials[MAX_SERIALS];
+struct consoledev keyboards[MAX_KEYBOARDS];
+struct consoledev graphics[MAX_GRAPHICS];
+
+/* Relaxed device comparison */
+#define MATCH(dev1, dev2) \
+ (dev1).dp_mod == (dev2).dp_mod && \
+ (dev1).dp_bc[0] == (dev2).dp_bc[0] && \
+ (dev1).dp_bc[1] == (dev2).dp_bc[1] && \
+ (dev1).dp_bc[2] == (dev2).dp_bc[2] && \
+ (dev1).dp_bc[3] == (dev2).dp_bc[3] && \
+ (dev1).dp_bc[4] == (dev2).dp_bc[4] && \
+ (dev1).dp_bc[5] == (dev2).dp_bc[5]
+
+int walked;
+
+void bus_walk(struct device_path *);
+void register_device(struct consoledev *, int,
+ struct device_path *, struct iodc_data *, int, int);
+
+int Xconsole(void);
+void print_console(void);
+int set_graphics(struct device_path *, int, char *);
+int set_serial(struct device_path *, int, char *);
+int set_console(struct device_path *);
+
+int Xkeyboard(void);
+void print_keyboard(void);
+int set_keyboard(struct device_path *);
+
+struct cmd_table cmd_machine[] = {
+ { "console", CMDT_CMD, Xconsole },
+ { "keyboard", CMDT_CMD, Xkeyboard },
+ { NULL, },
+};
+
+/* value to console speed table */
+int i_speeds[] = {
+ 50,
+ 75,
+ 110,
+ 150,
+ 300,
+ 600,
+ 1200,
+ 2400,
+ 4800,
+ 7200,
+ 9600,
+ 19200,
+ 38400,
+ 57600,
+ 115200,
+ 230400,
+};
+
+char *c_speeds[] = {
+ "50",
+ "75",
+ "110",
+ "150",
+ "300",
+ "600",
+ "1200",
+ "2400",
+ "4800",
+ "7200",
+ "9600",
+ "19200",
+ "38400",
+ "57600",
+ "115200",
+ "230400",
+};
+
+/* values to console parity table */
+char *parities[] = {
+ "none",
+ "odd",
+ "<unknown parity>",
+ "even",
+};
+
+/*
+ * C O N S O L E S E T T I N G S
+ */
+
+void
+print_console()
+{
+ int port, mode, speed, parity, bits;
+ int i;
+
+#ifdef DEBUG
+ printf("console flags %x mod %x bc %d/%d/%d/%d/%d/%d\n",
+ sstor.ss_console.dp_flags,
+ sstor.ss_console.dp_mod,
+ sstor.ss_console.dp_bc[0],
+ sstor.ss_console.dp_bc[1],
+ sstor.ss_console.dp_bc[2],
+ sstor.ss_console.dp_bc[3],
+ sstor.ss_console.dp_bc[4],
+ sstor.ss_console.dp_bc[5]);
+
+ printf("console path %x/%x/%x/%x/%x/%x\n",
+ sstor.ss_console.dp_layers[0],
+ sstor.ss_console.dp_layers[1],
+ sstor.ss_console.dp_layers[2],
+ sstor.ss_console.dp_layers[3],
+ sstor.ss_console.dp_layers[4],
+ sstor.ss_console.dp_layers[5]);
+#endif
+
+ printf("Console path: ");
+
+ /* look for a serial console */
+ for (port = i = 0; i < MAX_SERIALS; i++)
+ if (MATCH(serials[i].dp, sstor.ss_console)) {
+ port = i + 1;
+ break;
+ }
+
+ if (port == 0) {
+ /*
+ * Graphics console
+ */
+
+ for (port = i = 0; i < MAX_GRAPHICS; i++)
+ if (MATCH(graphics[i].dp, sstor.ss_console)) {
+ port = i;
+ break;
+ }
+
+ /*
+ * If the console could still not be identified, consider
+ * it is a simplified encoding for the default graphics
+ * console. Hence port == 0, no need to check.
+ */
+ if (port == 0)
+ printf("graphics");
+ else
+ printf("graphics_%d", port);
+
+ mode = sstor.ss_console.dp_layers[0];
+ if (mode != 0)
+ printf(".%d", mode);
+ } else {
+ /*
+ * Serial console
+ */
+
+ if (port == 1)
+ printf("rs232");
+ else
+ printf("rs232_%d", port);
+
+ speed = PZL_SPEED(sstor.ss_console.dp_layers[0]);
+ printf(".%d", i_speeds[speed]);
+
+ bits = PZL_BITS(sstor.ss_console.dp_layers[0]);
+ printf(".%d", bits);
+
+ parity = PZL_PARITY(sstor.ss_console.dp_layers[0]);
+ printf(".%s", parities[parity]);
+ }
+
+ printf("\n");
+}
+
+int
+set_graphics(console, port, arg)
+ struct device_path *console;
+ int port;
+ char *arg;
+{
+ int maxmode, mode = 0;
+ char *digit;
+
+ /* head */
+ if (graphics[port].type == 0) {
+ printf("no such device found\n");
+ return 0;
+ }
+
+ /* mode */
+ if (arg != NULL) {
+ for (digit = arg; *digit != '\0'; digit++) {
+ if (*digit >= '0' && *digit <= '9')
+ mode = 10 * mode + (*digit - '0');
+ else {
+ printf("invalid mode specification, %s\n",
+ arg);
+ return 0;
+ }
+ }
+
+ if (mode <= 0) {
+ printf("invalid mode specification, %s\n",
+ arg);
+ return 0;
+ }
+ }
+
+ /*
+ * If we are just changing the mode of the same graphics
+ * console, check that our mode is in the valid range.
+ */
+ if (MATCH(graphics[port].dp, sstor.ss_console)) {
+ maxmode = sstor.ss_console.dp_layers[1];
+
+ /* pick back same mode if unspecified */
+ if (mode == 0)
+ mode = sstor.ss_console.dp_layers[0];
+
+ if (mode > maxmode) {
+ printf("invalid mode value, available range is 1-%d\n",
+ maxmode);
+ return 0;
+ }
+ } else {
+ if (mode == 0)
+ mode = 1;
+ maxmode = mode;
+ }
+
+ *console = graphics[port].dp;
+ console->dp_layers[0] = mode;
+ console->dp_layers[1] = maxmode;
+ console->dp_layers[2] = console->dp_layers[3] =
+ console->dp_layers[4] = console->dp_layers[5] = 0;
+
+ return 1;
+}
+
+int
+set_serial(console, port, arg)
+ struct device_path *console;
+ int port;
+ char *arg;
+{
+ char *dot;
+ int i;
+ int speed, parity, bits;
+
+ /* port */
+ port--;
+ if (serials[port].type == 0) {
+ printf("no such device found\n");
+ return 0;
+ }
+
+ /* speed */
+ dot = strchr(arg, '.');
+ if (dot != NULL)
+ *dot++ = '\0';
+
+ speed = 0;
+ if (arg == NULL || *arg == '\0') {
+ for (i = 0; i < NENTS(i_speeds); i++)
+ if (i_speeds[i] == 9600) {
+ speed = i;
+ break;
+ }
+ } else {
+ for (i = 0; i < NENTS(c_speeds); i++)
+ if (strcmp(arg, c_speeds[i]) == 0) {
+ speed = i;
+ break;
+ }
+ if (speed == 0) {
+ printf("invalid speed specification, %s\n", arg);
+ return 0;
+ }
+ }
+
+ /* data bits */
+ arg = dot;
+ dot = strchr(arg, '.');
+
+ if (arg == NULL || *arg == '\0')
+ bits = 8;
+ else {
+ if (dot == arg + 1)
+ bits = *arg - '0';
+ else
+ bits = 0;
+
+ if (bits < 5 || bits > 8) {
+ printf("invalid bits specification, %s\n", arg);
+ return 0;
+ }
+ }
+ if (dot != NULL)
+ *dot++ = '\0';
+
+ /* parity */
+ arg = dot;
+ if (arg == NULL || *arg == '\0')
+ parity = 0; /* none */
+ else {
+ parity = -1;
+ for (i = 0; i <= 3; i++)
+ if (strcmp(arg, parities[i]) == 0) {
+ parity = i;
+ break;
+ }
+ if (parity == 2)
+ parity = -1; /* unknown parity */
+ }
+ if (parity < 0) {
+ printf("invalid parity specification, %s\n", arg);
+ return 0;
+ }
+
+ *console = serials[port].dp;
+ console->dp_layers[0] = PZL_ENCODE(bits, parity, speed);
+
+ return 1;
+}
+
+int
+set_console(console)
+ struct device_path *console;
+{
+ char *arg = cmd.argv[1], *dot;
+ int port;
+
+ /* extract first word */
+ dot = strchr(arg, '.');
+ if (dot != NULL)
+ *dot++ = '\0';
+
+ /*
+ * Graphics console
+ */
+ if (strcmp(arg, "graphics") == 0)
+ return set_graphics(console, 0, dot);
+ if (strncmp(arg, "graphics_", 9) == 0) {
+ port = arg[9] - '0';
+ if (port > 0 && port < MAX_GRAPHICS)
+ return set_graphics(console, port, dot);
+ }
+
+ /*
+ * Serial console
+ */
+ if (strcmp(arg, "rs232") == 0)
+ return set_serial(console, 1, dot);
+ if (strncmp(arg, "rs232_", 6) == 0) {
+ port = arg[6] - '0';
+ if (port > 0 && port <= MAX_SERIALS)
+ return set_serial(console, port, dot);
+ }
+
+ printf("invalid device specification, %s\n", arg);
+ return 0;
+}
+
+int
+Xconsole()
+{
+ struct device_path console;
+ int rc;
+
+ /* walk the device list if not already done */
+ if (walked == 0) {
+ bus_walk(NULL);
+ walked++;
+ }
+
+ if (sstorsiz < CONSOLESIZE) {
+ printf("no console information in stable storage\n");
+ return 0;
+ }
+
+ if (cmd.argc == 1) {
+ print_console();
+ } else {
+ console = sstor.ss_console;
+ if (set_console(&console)) {
+ if (memcmp(&sstor.ss_console, &console,
+ sizeof console) != 0) {
+ sstor.ss_console = console;
+
+ /* alea jacta est */
+ rc = (*pdc)(PDC_STABLE, PDC_STABLE_WRITE,
+ CONSOLEOFFSET, &sstor.ss_console,
+ sizeof(sstor.ss_console));
+ if (rc != 0) {
+ printf("failed to save console settings, error %d\n",
+ rc);
+ /* read sstor again for safety */
+ (*pdc)(PDC_STABLE, PDC_STABLE_READ,
+ CONSOLEOFFSET, &sstor.ss_console,
+ sizeof(sstor.ss_console));
+ } else
+ printf("you will need to power-cycle "
+ "your machine for the changes "
+ "to take effect.\n");
+ }
+ print_console();
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * K E Y B O A R D S E T T I N G S
+ */
+
+void
+print_keyboard()
+{
+ int type;
+ int i;
+
+#ifdef DEBUG
+ printf("keyboard flags %x mod %x bc %d/%d/%d/%d/%d/%d\n",
+ sstor.ss_keyboard.dp_flags,
+ sstor.ss_keyboard.dp_mod,
+ sstor.ss_keyboard.dp_bc[0],
+ sstor.ss_keyboard.dp_bc[1],
+ sstor.ss_keyboard.dp_bc[2],
+ sstor.ss_keyboard.dp_bc[3],
+ sstor.ss_keyboard.dp_bc[4],
+ sstor.ss_keyboard.dp_bc[5]);
+
+ printf("keyboard path %x/%x/%x/%x/%x/%x\n",
+ sstor.ss_keyboard.dp_layers[0],
+ sstor.ss_keyboard.dp_layers[1],
+ sstor.ss_keyboard.dp_layers[2],
+ sstor.ss_keyboard.dp_layers[3],
+ sstor.ss_keyboard.dp_layers[4],
+ sstor.ss_keyboard.dp_layers[5]);
+#endif
+
+ printf("Keyboard path: ");
+
+ for (type = i = 0; i < MAX_KEYBOARDS; i++)
+ if (MATCH(keyboards[i].dp, sstor.ss_keyboard)) {
+ type = keyboards[i].type;
+ break;
+ }
+
+ switch (type) {
+ case HIL:
+ printf("hil");
+ break;
+ case PS2:
+ printf("ps2");
+ break;
+ default:
+ printf("unknown");
+ break;
+ }
+
+ printf("\n");
+}
+
+int
+set_keyboard(keyboard)
+ struct device_path *keyboard;
+{
+ int i;
+ char *arg = cmd.argv[1];
+ int type;
+
+ if (strcmp(arg, "hil") == 0)
+ type = HIL;
+ else if (strcmp(arg, "ps2") == 0)
+ type = PS2;
+ else {
+ printf("invalid device specification, %s\n", arg);
+ return 0;
+ }
+
+ for (i = 0; i < MAX_KEYBOARDS; i++)
+ if (keyboards[i].type == type) {
+ *keyboard = keyboards[i].dp;
+ return 1;
+ }
+
+ printf("no such device found\n");
+ return 0;
+}
+
+int
+Xkeyboard()
+{
+ struct device_path keyboard;
+ int rc;
+
+ /* walk the device list if not already done */
+ if (walked == 0) {
+ bus_walk(NULL);
+ walked++;
+ }
+
+ if (sstorsiz < KEYBOARDSIZE) {
+ printf("no keyboard information in stable storage\n");
+ return 0;
+ }
+
+ if (cmd.argc == 1) {
+ print_keyboard();
+ } else {
+ keyboard = sstor.ss_keyboard;
+ if (set_keyboard(&keyboard)) {
+ if (memcmp(&sstor.ss_keyboard, &keyboard,
+ sizeof keyboard) != 0) {
+ sstor.ss_keyboard = keyboard;
+
+ /* alea jacta est */
+ rc = (*pdc)(PDC_STABLE, PDC_STABLE_WRITE,
+ KEYBOARDOFFSET, &sstor.ss_keyboard,
+ sizeof(sstor.ss_keyboard));
+ if (rc != 0) {
+ printf("failed to save keyboard settings, error %d\n",
+ rc);
+ /* read sstor again for safety */
+ (*pdc)(PDC_STABLE, PDC_STABLE_READ,
+ KEYBOARDOFFSET, &sstor.ss_keyboard,
+ sizeof(sstor.ss_keyboard));
+ } else
+ printf("you will need to power-cycle "
+ "your machine for the changes "
+ "to take effect.\n");
+ }
+ print_keyboard();
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * U T I L I T I E S
+ */
+
+/*
+ * Bus walker.
+ * This routine will walk all the modules on a given bus, registering
+ * serial ports, keyboard and graphics devices as they are found.
+ */
+void
+bus_walk(struct device_path *idp)
+{
+ struct device_path dp;
+ struct pdc_memmap memmap;
+ struct iodc_data mptr;
+ int err, i, kluge_ps2 = 0; /* kluge, see below */
+
+ for (i = 0; i < MAXMODBUS; i++) {
+
+ if (idp) {
+ dp.dp_bc[0] = idp->dp_bc[1];
+ dp.dp_bc[1] = idp->dp_bc[2];
+ dp.dp_bc[2] = idp->dp_bc[3];
+ dp.dp_bc[3] = idp->dp_bc[4];
+ dp.dp_bc[4] = idp->dp_bc[5];
+ dp.dp_bc[5] = idp->dp_mod;
+ } else {
+ dp.dp_bc[0] = dp.dp_bc[1] = dp.dp_bc[2] =
+ dp.dp_bc[3] = dp.dp_bc[4] = dp.dp_bc[5] = -1;
+ }
+
+ dp.dp_mod = i;
+ if ((pdc)(PDC_MEMMAP, PDC_MEMMAP_HPA, &memmap, &dp) < 0 &&
+ (pdc)(PDC_SYSMAP, PDC_SYSMAP_HPA, &memmap, &dp) < 0)
+ continue;
+
+ if ((err = (pdc)(PDC_IODC, PDC_IODC_READ, &pdcbuf, memmap.hpa,
+ IODC_DATA, &mptr, sizeof(mptr))) < 0)
+ continue;
+
+#ifdef DEBUG
+ printf("device %d/%d/%d/%d/%d/%d "
+ "flags %d mod %x type %x model %x\n",
+ dp.dp_bc[0], dp.dp_bc[1], dp.dp_bc[2], dp.dp_bc[3],
+ dp.dp_bc[4], dp.dp_bc[5], dp.dp_flags, dp.dp_mod,
+ mptr.iodc_type, mptr.iodc_sv_model);
+#endif
+ /*
+ * If the device can be considered as a valid rs232,
+ * graphics console or keyboard, register it.
+ *
+ * Unfortunately, devices which should be considered as
+ * ``main'' aren't necessarily seen first.
+ * The rules we try to enforce here are as follows:
+ * - GIO PS/2 ports wins over any other PS/2 port.
+ * - the first GIO serial found wins over any other
+ * serial port.
+ * The second rule is a bit tricky to achieve, since on
+ * some machines (for example, 715/100XC), the two serial
+ * ports are not seen as attached to the same busses...
+ */
+ switch (mptr.iodc_type) {
+ case HPPA_TYPE_BCPORT:
+ bus_walk(&dp);
+ break;
+ case HPPA_TYPE_BHA:
+ case HPPA_TYPE_BRIDGE:
+ /* if there was no phantomas here */
+ if (dp.dp_bc[5] == -1) {
+ dp.dp_bc[0] = dp.dp_bc[1];
+ dp.dp_bc[1] = dp.dp_bc[2];
+ dp.dp_bc[2] = dp.dp_bc[3];
+ dp.dp_bc[3] = dp.dp_bc[4];
+ dp.dp_bc[4] = dp.dp_bc[5];
+ dp.dp_bc[5] = dp.dp_mod;
+ dp.dp_mod = 0;
+ }
+ bus_walk(&dp);
+ break;
+ case HPPA_TYPE_ADIRECT:
+ switch (mptr.iodc_sv_model) {
+ case HPPA_ADIRECT_RS232:
+ register_device(serials, MAX_SERIALS,
+ &dp, &mptr, SERIAL, 0);
+ break;
+ case HPPA_ADIRECT_HIL:
+ register_device(keyboards, MAX_KEYBOARDS,
+ &dp, &mptr, HIL, 0);
+ break;
+ case HPPA_ADIRECT_PEACOCK:
+ case HPPA_ADIRECT_LEONARDO:
+ register_device(graphics, MAX_GRAPHICS,
+ &dp, &mptr, GRAPHICS, 0);
+ break;
+ }
+ break;
+ case HPPA_TYPE_FIO:
+ switch (mptr.iodc_sv_model) {
+ case HPPA_FIO_HIL:
+ register_device(keyboards, MAX_KEYBOARDS,
+ &dp, &mptr, HIL, 0);
+ break;
+ case HPPA_FIO_RS232:
+ register_device(serials, MAX_SERIALS,
+ &dp, &mptr, SERIAL, 0);
+ break;
+ case HPPA_FIO_DINOPCK:
+ register_device(keyboards, MAX_KEYBOARDS,
+ &dp, &mptr, PS2, 0);
+ break;
+ case HPPA_FIO_GPCIO:
+ /*
+ * KLUGE! At this point, there is no way to
+ * know if this port is the keyboard port or
+ * the mouse port.
+ * Let's assume the first port found is the
+ * keyboard, and ignore the others.
+ */
+ if (kluge_ps2 != 0)
+ break;
+ register_device(keyboards, MAX_KEYBOARDS,
+ &dp, &mptr, PS2, 1);
+ kluge_ps2++;
+ break;
+ case HPPA_FIO_GRS232:
+ {
+ int j, first;
+
+ /*
+ * If a GIO serial port is already registered,
+ * register as extra port...
+ */
+ first = 1;
+ for (j = 0; j < MAX_SERIALS; j++)
+ if (serials[j].type == SERIAL &&
+ serials[j].iodc_type ==
+ HPPA_TYPE_FIO &&
+ serials[j].iodc_model ==
+ HPPA_FIO_GRS232) {
+ first = 0;
+ break;
+ }
+
+ register_device(serials, MAX_SERIALS,
+ &dp, &mptr, SERIAL, first);
+ }
+ break;
+ case HPPA_FIO_SGC:
+ register_device(graphics, MAX_GRAPHICS,
+ &dp, &mptr, GRAPHICS, 0);
+ break;
+ case HPPA_FIO_GSGC:
+ register_device(graphics, MAX_GRAPHICS,
+ &dp, &mptr, GRAPHICS, 1);
+ break;
+ }
+ break;
+ }
+ }
+}
+
+void
+register_device(devlist, cnt, dp, mptr, type, first)
+ struct consoledev *devlist;
+ int cnt;
+ struct device_path *dp;
+ struct iodc_data *mptr;
+ int type;
+ int first;
+{
+ int i;
+ struct consoledev *dev;
+
+ for (i = 0, dev = devlist; i < cnt; i++, dev++)
+ if (dev->type == 0)
+ break;
+
+ if (i == cnt) {
+#ifdef DEBUG
+ printf("can't register device, need more room!\n");
+#endif
+ return;
+ }
+
+ /*
+ * If this is supposedly the main device, insert on top
+ */
+ if (first != 0) {
+ memcpy(devlist + 1, devlist,
+ (cnt - 1) * sizeof(struct consoledev));
+ dev = devlist;
+ }
+
+ dev->dp = *dp;
+ dev->type = type;
+ dev->iodc_type = mptr->iodc_type;
+ dev->iodc_model = mptr->iodc_sv_model;
+
+#ifdef DEBUG
+ printf("(registered as type %d)\n", type);
+#endif
+}
diff --git a/sys/arch/hppa64/stand/libsa/ct.c b/sys/arch/hppa64/stand/libsa/ct.c
new file mode 100644
index 00000000000..44316e10b12
--- /dev/null
+++ b/sys/arch/hppa64/stand/libsa/ct.c
@@ -0,0 +1,71 @@
+/* $OpenBSD: ct.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "libsa.h"
+
+#include <sys/param.h>
+#include <sys/disklabel.h>
+#include <sys/reboot.h>
+
+#include <machine/pdc.h>
+#include <machine/iomod.h>
+
+#include "dev_hppa64.h"
+
+int
+ctopen(struct open_file *f, ...)
+{
+ struct hppa_dev *dp = f->f_devdata;
+
+ if (!(dp->pz_dev = pdc_findev(-1, PCL_SEQU)))
+ return (ENXIO);
+
+ return (0);
+}
+
+/*ARGSUSED*/
+int
+ctclose(f)
+ struct open_file *f;
+{
+ free (f->f_devdata, sizeof(struct hppa_dev));
+ f->f_devdata = NULL;
+ return 0;
+}
diff --git a/sys/arch/hppa64/stand/libsa/dev_hppa64.c b/sys/arch/hppa64/stand/libsa/dev_hppa64.c
new file mode 100644
index 00000000000..75eb87528e4
--- /dev/null
+++ b/sys/arch/hppa64/stand/libsa/dev_hppa64.c
@@ -0,0 +1,228 @@
+/* $OpenBSD: dev_hppa64.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "libsa.h"
+#include <sys/param.h>
+#include <sys/disklabel.h>
+#include <sys/reboot.h>
+#include <dev/cons.h>
+
+#include <machine/iomod.h>
+
+#include "dev_hppa64.h"
+
+extern int debug;
+
+const char cdevs[][4] = {
+ "ite", "", "", "", "", "", "", "",
+ "", "", "", "", ""
+};
+const int ncdevs = NENTS(cdevs);
+
+const struct pdc_devs {
+ char name[3];
+ int dev_type;
+} pdc_devs[] = {
+ { "dk", 0 },
+ { "ct", 1 },
+ { "lf", 2 },
+ { "", -1 },
+ { "rd", -1 },
+ { "sw", -1 },
+ { "fl", -1 },
+};
+
+/* pass dev_t to the open routines */
+int
+devopen(f, fname, file)
+ struct open_file *f;
+ const char *fname;
+ char **file;
+{
+ struct hppa_dev *hpd;
+ const struct pdc_devs *dp = pdc_devs;
+ int rc = 1;
+
+ if (!(*file = strchr(fname, ':')))
+ return ENODEV;
+ else
+ (*file)++;
+
+#ifdef DEBUGBUG
+ if (debug)
+ printf("devopen: ");
+#endif
+
+ for (dp = pdc_devs; dp < &pdc_devs[NENTS(pdc_devs)]; dp++)
+ if (!strncmp(fname, dp->name, sizeof(dp->name)-1))
+ break;
+
+ if (dp >= &pdc_devs[NENTS(pdc_devs)] || dp->dev_type < 0)
+ return ENODEV;
+#ifdef DEBUGBUG
+ if (debug)
+ printf("%s\n", dp->name);
+#endif
+
+ if (!(hpd = alloc(sizeof *hpd))) {
+#ifdef DEBUG
+ printf ("devopen: no mem\n");
+#endif
+ } else {
+ bzero(hpd, sizeof *hpd);
+ hpd->bootdev = bootdev;
+ hpd->buf = (char *)(((u_long)hpd->ua_buf + IODC_MINIOSIZ-1) &
+ ~(IODC_MINIOSIZ-1));
+ f->f_devdata = hpd;
+ if ((rc = (*devsw[dp->dev_type].dv_open)(f, file)) == 0) {
+ f->f_dev = &devsw[dp->dev_type];
+ return 0;
+ }
+ free (hpd, 0);
+ f->f_devdata = NULL;
+ }
+
+ if (!(f->f_flags & F_NODEV))
+ f->f_dev = &devsw[dp->dev_type];
+
+ if (!f->f_devdata)
+ *file = NULL;
+
+ return rc;
+}
+
+void
+devboot(dev, p)
+ dev_t dev;
+ char *p;
+{
+ const char *q;
+ if (!dev) {
+ int type, unit;
+
+ switch (PAGE0->mem_boot.pz_class) {
+ case PCL_RANDOM:
+ type = 0;
+ unit = PAGE0->mem_boot.pz_layers[0];
+ break;
+ case PCL_SEQU:
+ type = 1;
+ unit = PAGE0->mem_boot.pz_layers[0];
+ break;
+ case PCL_NET_MASK|PCL_SEQU:
+ type = 2;
+ unit = 0;
+ break;
+ default:
+ type = 0;
+ unit = 0;
+ break;
+ }
+ dev = bootdev = MAKEBOOTDEV(type, 0, 0, unit, B_PARTITION(dev));
+ }
+#ifdef _TEST
+ *p++ = '/';
+ *p++ = 'd';
+ *p++ = 'e';
+ *p++ = 'v';
+ *p++ = '/';
+ *p++ = 'r';
+#endif
+ /* quick copy device name */
+ for (q = pdc_devs[B_TYPE(dev)].name; (*p++ = *q++););
+ p[-1] = '0' + B_UNIT(dev);
+ *p++ = 'a' + B_PARTITION(dev);
+ *p = '\0';
+}
+
+int pch_pos;
+
+void
+putchar(c)
+ int c;
+{
+ switch(c) {
+ case '\177': /* DEL erases */
+ cnputc('\b');
+ cnputc(' ');
+ case '\b':
+ cnputc('\b');
+ if (pch_pos)
+ pch_pos--;
+ break;
+ case '\t':
+ do
+ cnputc(' ');
+ while(++pch_pos % 8);
+ break;
+ case '\n':
+ case '\r':
+ cnputc(c);
+ pch_pos=0;
+ break;
+ default:
+ cnputc(c);
+ pch_pos++;
+ break;
+ }
+}
+
+int
+getchar()
+{
+ int c = cngetc();
+
+ if (c == '\r')
+ c = '\n';
+
+ if ((c < ' ' && c != '\n') || c == '\177')
+ return(c);
+
+ putchar(c);
+
+ return(c);
+}
+
+char ttyname_buf[8];
+char *
+ttyname(fd)
+ int fd;
+{
+ snprintf(ttyname_buf, sizeof ttyname_buf, "%s%d",
+ cdevs[major(cn_tab->cn_dev)],
+ minor(cn_tab->cn_dev));
+ return (ttyname_buf);
+}
+
+dev_t
+ttydev(name)
+ char *name;
+{
+ int i, unit = -1;
+ char *no = name + strlen(name) - 1;
+
+ while (no >= name && *no >= '0' && *no <= '9')
+ unit = (unit < 0 ? 0 : (unit * 10)) + *no-- - '0';
+ if (no < name || unit < 0)
+ return (NODEV);
+ for (i = 0; i < ncdevs; i++)
+ if (strncmp(name, cdevs[i], no - name + 1) == 0)
+ return (makedev(i, unit));
+ return (NODEV);
+}
diff --git a/sys/arch/hppa64/stand/libsa/dev_hppa64.h b/sys/arch/hppa64/stand/libsa/dev_hppa64.h
new file mode 100644
index 00000000000..a47daa2173a
--- /dev/null
+++ b/sys/arch/hppa64/stand/libsa/dev_hppa64.h
@@ -0,0 +1,43 @@
+/* $OpenBSD: dev_hppa64.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+
+#define IOPGSHIFT 11
+#define IONBPG (1 << IOPGSHIFT)
+#define IOPGOFSET (IONBPG - 1)
+
+struct disklabel;
+struct hppa_dev {
+ dev_t bootdev;
+ struct pz_device *pz_dev; /* device descriptor */
+ daddr_t fsoff; /* offset to the file system */
+ daddr_t last_blk; /* byte offset for last read blk */
+ size_t last_read; /* amount read last time */
+ struct disklabel *label;
+ /* buffer to cache data (aligned properly) */
+ char *buf;
+ char ua_buf[IODC_IOSIZ + IODC_MINIOSIZ];
+};
+
+#ifdef PDCDEBUG
+#define DEVPATH_PRINT(dp) \
+ printf("%x, %d.%d.%d.%d.%d.%d, 0x%x, %x.%x.%x.%x.%x.%x\n", \
+ (dp)->dp_flags, (dp)->dp_bc[0], (dp)->dp_bc[1], (dp)->dp_bc[2], \
+ (dp)->dp_bc[3], (dp)->dp_bc[4], (dp)->dp_bc[5], (dp)->dp_mod, \
+ (dp)->dp_layers[0], (dp)->dp_layers[1], (dp)->dp_layers[2], \
+ (dp)->dp_layers[3], (dp)->dp_layers[4], (dp)->dp_layers[5]);
+#define PZDEV_PRINT(dp) \
+ printf("devpath={%x, %d.%d.%d.%d.%d.%d, 0x%x, %x.%x.%x.%x.%x.%x}," \
+ "\n\thpa=%p, spa=%p, io=%p, class=%u\n", \
+ (dp)->pz_flags, (dp)->pz_bc[0], (dp)->pz_bc[1], (dp)->pz_bc[2], \
+ (dp)->pz_bc[3], (dp)->pz_bc[4], (dp)->pz_bc[5], (dp)->pz_mod, \
+ (dp)->pz_layers[0], (dp)->pz_layers[1], (dp)->pz_layers[2], \
+ (dp)->pz_layers[3], (dp)->pz_layers[4], (dp)->pz_layers[5], \
+ (dp)->pz_hpa, (dp)->pz_spa, (dp)->pz_iodc_io, (dp)->pz_class);
+#endif
+
+extern pdcio_t pdc;
+extern int pdcbuf[]; /* PDC returns, pdc.c */
+
+int iodc_rw(char *, u_int, u_int, int func, struct pz_device *);
+const char *dk_disklabel(struct hppa_dev *dp, struct disklabel *label);
+int pdc_call(void *, ...);
diff --git a/sys/arch/hppa64/stand/libsa/dk.c b/sys/arch/hppa64/stand/libsa/dk.c
new file mode 100644
index 00000000000..d20d19d5b3f
--- /dev/null
+++ b/sys/arch/hppa64/stand/libsa/dk.c
@@ -0,0 +1,101 @@
+/* $OpenBSD: dk.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "libsa.h"
+
+#include <sys/param.h>
+#include <sys/disklabel.h>
+#include <sys/reboot.h>
+#include <machine/pdc.h>
+#include <machine/iomod.h>
+
+#include "dev_hppa64.h"
+
+const char *
+dk_disklabel(struct hppa_dev *dp, struct disklabel *label)
+{
+ char buf[DEV_BSIZE];
+ size_t ret;
+
+ if (iodcstrategy(dp, F_READ, LABELSECTOR, DEV_BSIZE, buf, &ret))
+ if (ret != DEV_BSIZE)
+ return "cannot read disklabel";
+
+ return (getdisklabel(buf, label));
+}
+
+int
+dkopen(struct open_file *f, ...)
+{
+ struct disklabel *lp;
+ struct hppa_dev *dp = f->f_devdata;
+ const char *st;
+
+#ifdef DEBUG
+ if (debug)
+ printf("dkopen(%p)\n", f);
+#endif
+
+ if (!(dp->pz_dev = pdc_findev(-1, PCL_RANDOM)))
+ return ENXIO;
+
+ lp = dp->label;
+ st = NULL;
+
+#ifdef DEBUG
+ if (debug)
+ printf ("disklabel\n");
+#endif
+
+ if ((st = dk_disklabel(dp, lp)) != NULL) {
+#ifdef DEBUG
+ if (debug)
+ printf ("dkopen: %s\n", st);
+#endif
+ /* we do not know if it's a disk or net, but do not fail */
+ } else {
+ u_int i;
+
+ i = B_PARTITION(dp->bootdev);
+ if (i >= lp->d_npartitions || !lp->d_partitions[i].p_size)
+ return (EPART);
+
+ dp->fsoff = lp->d_partitions[i].p_offset;
+ }
+
+#ifdef DEBUGBUG
+ if (debug)
+ printf ("dkopen() ret\n");
+#endif
+ return (0);
+}
+
+int
+dkclose(f)
+ struct open_file *f;
+{
+ free (f->f_devdata, sizeof(struct hppa_dev));
+ f->f_devdata = NULL;
+ return 0;
+}
diff --git a/sys/arch/hppa64/stand/libsa/itecons.c b/sys/arch/hppa64/stand/libsa/itecons.c
new file mode 100644
index 00000000000..49e4413e2d2
--- /dev/null
+++ b/sys/arch/hppa64/stand/libsa/itecons.c
@@ -0,0 +1,212 @@
+/* $OpenBSD: itecons.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "libsa.h"
+
+#include <sys/param.h>
+#include <sys/disklabel.h>
+#include <machine/pdc.h>
+#include <machine/iomod.h>
+#include <dev/cons.h>
+
+#include "dev_hppa64.h"
+
+iodcio_t cniodc; /* console IODC entry point */
+iodcio_t kyiodc; /* keyboard IODC entry point */
+pz_device_t *cons_pzdev, *kbd_pzdev;
+
+/*
+ * Console.
+ */
+
+char cnbuf[IODC_MINIOSIZ] __attribute__ ((aligned (IODC_MINIOSIZ)));
+int kycode[IODC_MAXSIZE/sizeof(int)];
+
+int
+cnspeed(dev, sp)
+ dev_t dev;
+ int sp;
+{
+ return 9600;
+}
+
+void
+ite_probe(cn)
+ struct consdev *cn;
+{
+ cniodc = (iodcio_t)(u_long)PAGE0->mem_free;
+ cons_pzdev = &PAGE0->mem_cons;
+ kbd_pzdev = &PAGE0->mem_kbd;
+
+ if (pdc_call(pdc, PDC_IODC, PDC_IODC_READ, pdcbuf, cons_pzdev->pz_hpa,
+ IODC_INIT, cniodc, IODC_MAXSIZE) < 0 ||
+ pdc_call(cniodc, cons_pzdev->pz_hpa,
+ (cons_pzdev->pz_hpa==PAGE0->mem_boot.pz_hpa)?
+ IODC_INIT_DEV: IODC_INIT_ALL, cons_pzdev->pz_spa,
+ cons_pzdev->pz_layers, pdcbuf, 0,0,0,0) < 0 ||
+ pdc_call(pdc, PDC_IODC, PDC_IODC_READ, pdcbuf, cons_pzdev->pz_hpa,
+ IODC_IO, cniodc, IODC_MAXSIZE) < 0) {
+ /* morse code with the LED's?!! */
+ cons_pzdev->pz_iodc_io = kbd_pzdev->pz_iodc_io = NULL;
+ } else {
+ cn->cn_pri = CN_INTERNAL;
+ cn->cn_dev = makedev(0, 0);
+ }
+}
+
+void
+ite_init(cn)
+ struct consdev *cn;
+{
+ /*
+ * If the keyboard is separate from the console output device,
+ * we load the keyboard code at `kycode'.
+ *
+ * N.B. In this case, since the keyboard code is part of the
+ * boot code, it will be overwritten when we load a kernel.
+ */
+ if (cons_pzdev->pz_class != PCL_DUPLEX ||
+ kbd_pzdev->pz_class == PCL_KEYBD) {
+
+ kyiodc = (iodcio_t)kycode;
+
+ if (pdc_call(pdc, PDC_IODC, PDC_IODC_READ, pdcbuf, kbd_pzdev->pz_hpa,
+ IODC_INIT, kyiodc, IODC_MAXSIZE) < 0 ||
+ pdc_call(kyiodc, kbd_pzdev->pz_hpa,
+ (kbd_pzdev->pz_hpa == PAGE0->mem_boot.pz_hpa ||
+ kbd_pzdev->pz_hpa == cons_pzdev->pz_hpa)?
+ IODC_INIT_DEV: IODC_INIT_ALL, kbd_pzdev->pz_spa,
+ kbd_pzdev->pz_layers, pdcbuf, 0, 0, 0, 0) < 0 ||
+ pdc_call(pdc, PDC_IODC, PDC_IODC_READ, pdcbuf, kbd_pzdev->pz_hpa,
+ IODC_IO, kyiodc, IODC_MAXSIZE))
+ kyiodc = NULL;
+ } else {
+ kyiodc = cniodc;
+
+ bcopy((char *)&PAGE0->mem_cons, (char *)&PAGE0->mem_kbd,
+ sizeof(struct pz_device));
+ }
+
+ cons_pzdev->pz_iodc_io = (u_long)cniodc;
+ kbd_pzdev->pz_iodc_io = (u_long)kyiodc;
+#ifdef DEBUG
+ if (!kyiodc)
+ printf("ite_init: no kbd\n");
+#endif
+}
+
+void
+ite_putc(dev, c)
+ dev_t dev;
+ int c;
+{
+ if (cniodc == NULL)
+ return;
+
+ *cnbuf = c;
+
+ pdc_call(cniodc, cons_pzdev->pz_hpa, IODC_IO_CONSOUT,
+ cons_pzdev->pz_spa, cons_pzdev->pz_layers, pdcbuf, 0, cnbuf, 1, 0);
+}
+
+/*
+ * since i don't know how to 'just check the char available'
+ * i store the key into the stash removing on read op later;
+ */
+int
+ite_getc(dev)
+ dev_t dev;
+{
+ static int stash = 0;
+ int err, c, l, i;
+
+ if (kyiodc == NULL)
+ return(0x100);
+
+ if (stash) {
+ c = stash;
+ if (!(dev & 0x80))
+ stash = 0;
+ return c;
+ }
+
+ i = 16;
+ do {
+ err = pdc_call(kyiodc, kbd_pzdev->pz_hpa, IODC_IO_CONSIN,
+ kbd_pzdev->pz_spa, kbd_pzdev->pz_layers, pdcbuf,
+ 0, cnbuf, 1, 0);
+ l = pdcbuf[0];
+ c = cnbuf[0];
+#ifdef DEBUG
+ if (debug && err < 0)
+ printf("KBD input error: %d", err);
+#endif
+
+ /* if we are doing ischar() report immidiatelly */
+ if (!i-- && (dev & 0x80) && l == 0) {
+#ifdef DEBUG
+ if (debug > 2)
+ printf("ite_getc(0x%x): no char %d(%x)\n",
+ dev, l, c);
+#endif
+ return (0);
+ }
+ } while(!l);
+
+#if DEBUG
+ if (debug && l > 1)
+ printf("KBD input got too much (%d)\n", l);
+
+ if (debug > 3)
+ printf("kbd: \'%c\' (0x%x)\n", c, c);
+#endif
+ if (dev & 0x80)
+ stash = c;
+
+ return (c);
+}
+
+void
+ite_pollc(dev, on)
+ dev_t dev;
+ int on;
+{
+
+}
diff --git a/sys/arch/hppa64/stand/libsa/lf.c b/sys/arch/hppa64/stand/libsa/lf.c
new file mode 100644
index 00000000000..15b7a6c0957
--- /dev/null
+++ b/sys/arch/hppa64/stand/libsa/lf.c
@@ -0,0 +1,44 @@
+/* $OpenBSD: lf.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "libsa.h"
+#include <machine/pdc.h>
+#include <machine/iomod.h>
+#include <machine/param.h>
+
+#include "dev_hppa64.h"
+
+int
+lfopen(struct open_file *f, ...)
+{
+ struct hppa_dev *dp = f->f_devdata;
+
+ if (!(dp->pz_dev = pdc_findev(-1, PCL_NET_MASK|PCL_SEQU)))
+ return ENXIO;
+
+ return 0;
+}
+
+int
+lfclose(struct open_file *f)
+{
+ free(f->f_devdata, sizeof(struct hppa_dev));
+ f->f_devdata = NULL;
+ return 0;
+}
diff --git a/sys/arch/hppa64/stand/libsa/libsa.h b/sys/arch/hppa64/stand/libsa/libsa.h
new file mode 100644
index 00000000000..9952a35a383
--- /dev/null
+++ b/sys/arch/hppa64/stand/libsa/libsa.h
@@ -0,0 +1,72 @@
+/* $OpenBSD: libsa.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <lib/libsa/stand.h>
+
+#define EXEC_ELF
+#define EXEC_SOM
+
+#define DEFAULT_KERNEL_ADDRESS 0
+
+extern dev_t bootdev;
+
+void pdc_init(void);
+struct pz_device;
+struct pz_device *pdc_findev(int, int);
+
+int iodcstrategy(void *, int, daddr_t, size_t, void *, size_t *);
+
+int ctopen(struct open_file *, ...);
+int ctclose(struct open_file *);
+
+int dkopen(struct open_file *, ...);
+int dkclose(struct open_file *);
+
+int lfopen(struct open_file *, ...);
+int lfstrategy(void *, int, daddr_t, size_t, void *, size_t *);
+int lfclose(struct open_file *);
+
+void ite_probe(struct consdev *);
+void ite_init(struct consdev *);
+int ite_getc(dev_t);
+void ite_putc(dev_t, int);
+void ite_pollc(dev_t, int);
+
+void machdep(void);
+void devboot(dev_t, char *);
+void fcacheall(void);
+void run_loadfile(u_long *marks, int howto);
+
+int lif_open(char *path, struct open_file *f);
+int lif_close(struct open_file *f);
+int lif_read(struct open_file *f, void *buf, size_t size, size_t *resid);
+int lif_write(struct open_file *f, void *buf, size_t size, size_t *resid);
+off_t lif_seek(struct open_file *f, off_t offset, int where);
+int lif_stat(struct open_file *f, struct stat *sb);
+int lif_readdir(struct open_file *f, char *name);
+
+union x_header;
+struct x_param;
+int som_probe(int, union x_header *);
+int som_load(int, struct x_param *);
+int som_ldsym(int, struct x_param *);
+
+extern int debug;
+
+#define MACHINE_CMD cmd_machine /* we have hppa specific commands */
diff --git a/sys/arch/hppa64/stand/libsa/lif.c b/sys/arch/hppa64/stand/libsa/lif.c
new file mode 100644
index 00000000000..25c25471f14
--- /dev/null
+++ b/sys/arch/hppa64/stand/libsa/lif.c
@@ -0,0 +1,261 @@
+/* $OpenBSD: lif.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/disklabel.h>
+#include "libsa.h"
+
+extern int debug;
+
+struct file {
+ char f_buf[LIF_FILESTART];/* buffer for lif volume header and dir */
+ struct lifvol *f_lp; /* lif volume header pointer */
+ struct lifdir *f_ld; /* lif dir pointer */
+ int f_nfiles; /* gross number for lif dir entries */
+
+ off_t f_seek; /* seek pointer for file read */
+ struct lifdir *f_rd; /* lif dir pointer for readdir */
+
+ int f_isdir; /* special hacky flag for '.' dir */
+ int f_count; /* this file length */
+ int f_off; /* this file offset */
+};
+
+int
+lif_open (path, f)
+ char *path;
+ struct open_file *f;
+{
+ struct file *fp;
+ struct lifdir *dp;
+ char *p, *q;
+ struct lif_load load;
+ size_t buf_size;
+ int err, l;
+
+#ifdef LIFDEBUG
+ if (debug)
+ printf("lif_open(%s, %p)\n", path, f);
+#endif
+
+ fp = alloc(sizeof(*fp));
+ /* XXX we're assuming here that sizeof(fp->f_buf) >= LIF_FILESTART */
+ if ((err = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, 0,
+ sizeof(fp->f_buf), &fp->f_buf, &buf_size)) ||
+ buf_size != sizeof(fp->f_buf)) {
+#ifdef LIFDEBUG
+ if (debug)
+ printf("lif_open: unable to read LIF header (%d)\n", err);
+#endif
+ } else if ((fp->f_lp = (struct lifvol *)fp->f_buf)->vol_id == LIF_VOL_ID) {
+ f->f_fsdata = fp;
+ fp->f_ld = (struct lifdir *)(fp->f_buf + LIF_DIRSTART);
+ fp->f_seek = 0;
+ fp->f_rd = fp->f_ld;
+ fp->f_nfiles = lifstob(fp->f_lp->vol_dirsize) /
+ sizeof(struct lifdir);
+
+ /* no dirs on the lif */
+ for (p = path + (l = strlen(path)); p >= path; p--)
+ if (*p == '/') {
+ p++;
+ break;
+ }
+ if (p > path)
+ path = p;
+ } else
+ err = EINVAL;
+
+ if (!err && *path != '.') {
+ fp->f_isdir = 0;
+ err = ENOENT;
+ for (dp = fp->f_ld; dp < &fp->f_ld[fp->f_nfiles]; dp++) {
+#ifdef LIFDEBUG
+ if (debug)
+ printf("lif_open: "
+ "%s <--> '%c%c%c%c%c%c%c%c%c%c'\n",
+ path, dp->dir_name[0], dp->dir_name[1],
+ dp->dir_name[2], dp->dir_name[3],
+ dp->dir_name[4], dp->dir_name[5],
+ dp->dir_name[6], dp->dir_name[7],
+ dp->dir_name[8], dp->dir_name[9]);
+#endif
+ for (p = path, q = dp->dir_name;
+ *q && *q != ' '; q++, p++)
+ if (tolower(*q) != tolower(*p))
+ break;
+ if ((!*q || *q == ' ') && !*p) {
+ err = 0;
+ break;
+ }
+ }
+ if (!err) {
+ fp->f_off = lifstodb(dp->dir_addr);
+ if (!(err =(f->f_dev->dv_strategy)(f->f_devdata, F_READ,
+ fp->f_off, sizeof(load), &load, &buf_size)) &&
+ buf_size == sizeof(load)) {
+ /* no checksum */
+ fp->f_count = load.count - sizeof(int);
+ fp->f_off = dbtob(fp->f_off) + sizeof(load);
+#ifdef LIFDEBUG
+ if (debug)
+ printf("lif_open: %u @ %u [%x]\n",
+ fp->f_count, fp->f_off,
+ load.address);
+#endif
+ } else if (!err)
+ err = EIO;
+ }
+ } else
+ fp->f_isdir = 1;
+
+ if (err) {
+ free (fp, sizeof(*fp));
+ f->f_fsdata = NULL;
+ }
+#ifdef LIFDEBUG
+ if (debug)
+ printf("ret(%d)\n", err);
+#endif
+ return err;
+}
+
+int
+lif_close(f)
+ struct open_file *f;
+{
+ free (f->f_fsdata, sizeof(struct file));
+ f->f_fsdata = NULL;
+ return 0;
+}
+
+int
+lif_read(f, buf, size, resid)
+ struct open_file *f;
+ void *buf;
+ size_t size;
+ size_t *resid;
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ char *p;
+ char bbuf[DEV_BSIZE];
+ size_t bsize, count = sizeof(bbuf);
+ int err = 0;
+ int foff;
+
+#ifdef LIFDEBUG
+ if (debug)
+ printf("lif_read(%p, %p, %u, %p)\n", f, buf, size, resid);
+#endif
+
+ for (p = bbuf; size; fp->f_seek += bsize, p += bsize) {
+ twiddle();
+ foff = fp->f_off + fp->f_seek;
+ if (fp->f_seek >= fp->f_count ||
+ (err = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
+ btodb(foff), count, p, &bsize)))
+ break;
+ if (p == bbuf) {
+ bsize = sizeof(bbuf) - (foff & (sizeof(bbuf) - 1));
+ bsize = min(bsize, size);
+ bcopy(bbuf + (foff & (sizeof(bbuf) - 1)), buf, bsize);
+ p = buf;
+ }
+ count = size -= bsize;
+ }
+ if (resid)
+ *resid = size;
+
+ return err;
+}
+
+int
+lif_write(f, buf, size, resid)
+ struct open_file *f;
+ void *buf;
+ size_t size;
+ size_t *resid;
+{
+ return EOPNOTSUPP;
+}
+
+off_t
+lif_seek(f, offset, where)
+ struct open_file *f;
+ off_t offset;
+ int where;
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+
+ switch (where) {
+ case SEEK_SET:
+ fp->f_seek = offset;
+ break;
+ case SEEK_CUR:
+ fp->f_seek += offset;
+ break;
+ case SEEK_END:
+ fp->f_seek = fp->f_count - offset;
+ break;
+ default:
+ return (-1);
+ }
+ return (fp->f_seek);
+}
+
+int
+lif_stat(f, sb)
+ struct open_file *f;
+ struct stat *sb;
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+
+ sb->st_mode = 0755 | (fp->f_isdir? S_IFDIR: 0); /* XXX */
+ sb->st_uid = 0;
+ sb->st_gid = 0;
+ sb->st_size = fp->f_count;
+ return 0;
+}
+
+int
+lif_readdir(f, name)
+ struct open_file *f;
+ char *name;
+{
+ struct file *fp = (struct file *)f->f_fsdata;
+ char *p;
+
+ if (name) {
+ while ((fp->f_rd->dir_name[0] == ' ' ||
+ !fp->f_rd->dir_name[0]) &&
+ (fp->f_rd - fp->f_ld) < fp->f_nfiles)
+ fp->f_rd++;
+ if ((fp->f_rd - fp->f_ld) >= fp->f_nfiles) {
+ *name = '\0';
+ return -1;
+ }
+ strncpy(name, fp->f_rd->dir_name, sizeof(fp->f_rd->dir_name));
+ if ((p = strchr(name, ' ')))
+ *p = '\0';
+ fp->f_rd++;
+ } else
+ fp->f_rd = fp->f_ld;
+
+ return 0;
+}
diff --git a/sys/arch/hppa64/stand/libsa/machdep.c b/sys/arch/hppa64/stand/libsa/machdep.c
new file mode 100644
index 00000000000..521488e2257
--- /dev/null
+++ b/sys/arch/hppa64/stand/libsa/machdep.c
@@ -0,0 +1,75 @@
+/* $OpenBSD: machdep.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/disklabel.h>
+#include <sys/reboot.h>
+#include "libsa.h"
+#include <machine/iomod.h>
+#include <machine/pdc.h>
+
+#include "dev_hppa64.h"
+
+extern struct stable_storage sstor; /* contents of Stable Storage */
+int howto;
+dev_t bootdev;
+
+void
+machdep()
+{
+ pdc_init();
+#ifdef notyet
+ debug_init();
+#endif
+ cninit();
+
+#ifdef PDCDEBUG
+ if (debug) {
+ int i;
+
+ printf("SSTOR:\n");
+ printf("pri_boot="); DEVPATH_PRINT(&sstor.ss_pri_boot);
+ printf("alt_boot="); DEVPATH_PRINT(&sstor.ss_alt_boot);
+ printf("console ="); DEVPATH_PRINT(&sstor.ss_console);
+ printf("keyboard="); DEVPATH_PRINT(&sstor.ss_keyboard);
+ printf("mem=%d, fn=%s, osver=%d\nos={",
+ sstor.ss_fast_size, sstor.ss_filenames,
+ sstor.ss_os_version);
+ for (i = 0; i < sizeof(sstor.ss_os); i++)
+ printf ("%x%c", sstor.ss_os[i], (i%8)? ',' : '\n');
+
+ printf("}\nPAGE0:\n");
+ printf("ivec=%x, pf=%p[%u], toc=%p[%u], rndz=%p, clk/10ms=%u\n",
+ PAGE0->ivec_special, PAGE0->ivec_mempf,
+ PAGE0->ivec_mempflen, PAGE0->ivec_toc,
+ PAGE0->ivec_toclen, PAGE0->ivec_rendz,
+ PAGE0->mem_10msec);
+ printf ("mem: cont=%u, phys=%u, pdc_spa=%u, resv=%u, free=%x\n"
+ "cpu_hpa=%x, pdc=%p, imm_hpa=%p[%u,%u], soft=%u\n",
+ PAGE0->memc_cont, PAGE0->memc_phsize, PAGE0->memc_adsize,
+ PAGE0->memc_resv, PAGE0->mem_free, PAGE0->mem_hpa,
+ PAGE0->mem_pdc, PAGE0->imm_hpa, PAGE0->imm_spa_size,
+ PAGE0->imm_max_mem, PAGE0->imm_soft_boot);
+
+ printf("console: "); PZDEV_PRINT(&PAGE0->mem_cons);
+ printf("boot: "); PZDEV_PRINT(&PAGE0->mem_boot);
+ printf("keyboard: "); PZDEV_PRINT(&PAGE0->mem_kbd);
+ }
+#endif
+}
diff --git a/sys/arch/hppa64/stand/libsa/pdc.c b/sys/arch/hppa64/stand/libsa/pdc.c
new file mode 100644
index 00000000000..1569c52a1dd
--- /dev/null
+++ b/sys/arch/hppa64/stand/libsa/pdc.c
@@ -0,0 +1,448 @@
+/* $OpenBSD: pdc.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * Copyright 1996 1995 by Open Software Foundation, Inc.
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appears in all copies and
+ * that both the copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+ * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * Copyright (c) 1990 mt Xinu, Inc. All rights reserved.
+ * Copyright (c) 1990 University of Utah. All rights reserved.
+ *
+ * This file may be freely distributed in any form as long as
+ * this copyright notice is included.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Utah $Hdr: pdc.c 1.8 92/03/14$
+ */
+
+#include <sys/time.h>
+#include "libsa.h"
+#include <sys/reboot.h>
+#include <sys/disklabel.h>
+
+#include <machine/trap.h>
+#include <machine/pdc.h>
+#include <machine/iomod.h>
+#include <machine/nvm.h>
+#include <machine/param.h>
+#include <machine/cpufunc.h>
+
+#include "dev_hppa64.h"
+
+/*
+ * Interface routines to initialize and access the PDC.
+ */
+
+pdcio_t pdc;
+int pdcbuf[64] PDC_ALIGNMENT;/* PDC return buffer */
+struct stable_storage sstor; /* contents of Stable Storage */
+int sstorsiz; /* size of Stable Storage */
+struct bootdata bd;
+int bdsize = sizeof(struct bootdata);
+
+/*
+ * Initialize PDC and related variables.
+ */
+void
+pdc_init()
+{
+ int err;
+
+ /*
+ * Initialize important global variables (defined above).
+ */
+ pdc = (pdcio_t)(u_long)PAGE0->mem_pdc;
+
+ err = pdc_call(pdc, PDC_STABLE, PDC_STABLE_SIZE, pdcbuf, 0, 0);
+ if (err >= 0) {
+ sstorsiz = min(pdcbuf[0],sizeof(sstor));
+ err = (*pdc)(PDC_STABLE, PDC_STABLE_READ, 0, &sstor, sstorsiz);
+ }
+
+ /*
+ * Now that we (may) have an output device, if we encountered
+ * an error reading Stable Storage (above), let them know.
+ */
+#ifdef DEBUG
+ if (debug && err)
+ printf("Stable storage PDC_STABLE Read Ret'd %d\n", err);
+#endif
+
+ /*
+ * Clear the FAULT light (so we know when we get a real one)
+ */
+ pdc_call(pdc, PDC_CHASSIS, PDC_CHASSIS_DISP,
+ PDC_OSTAT(PDC_OSTAT_BOOT) | 0xCEC0);
+}
+
+/*
+ * Generic READ/WRITE through IODC. Takes pointer to PDC device
+ * information, returns (positive) number of bytes actually read or
+ * the (negative) error condition, or zero if at "EOF".
+ */
+int
+iodcstrategy(devdata, rw, blk, size, buf, rsize)
+ void *devdata;
+ int rw;
+ daddr_t blk;
+ size_t size;
+ void *buf;
+ size_t *rsize;
+{
+ struct hppa_dev *dp = devdata;
+ struct pz_device *pzdev = dp->pz_dev;
+ iodcio_t iodc = (iodcio_t)(u_long)pzdev->pz_iodc_io;
+ int offset, xfer, ret;
+
+#ifdef PDCDEBUG
+ if (debug)
+ printf("iodcstrategy(%p, %s, %u, %u, %p, %p)\n", devdata,
+ rw==F_READ? "READ" : "WRITE", blk, size, buf, rsize);
+
+ if (debug > 1)
+ PZDEV_PRINT(pzdev);
+#endif
+
+ blk += dp->fsoff;
+ blk <<= DEV_BSHIFT;
+ if ((pzdev->pz_class & PCL_CLASS_MASK) == PCL_SEQU) {
+ /* rewind and re-read to seek */
+ if (blk < dp->last_blk) {
+#ifdef PDCDEBUG
+ if (debug)
+ printf("iodc: rewind ");
+#endif
+ if ((ret = ((iodcio_t)(long)pzdev->pz_iodc_io)(
+ pzdev->pz_hpa, IODC_IO_READ, pzdev->pz_spa,
+ pzdev->pz_layers, pdcbuf, 0, dp->buf, 0, 0)) < 0) {
+#ifdef DEBUG
+ if (debug)
+ printf("IODC_IO: %d\n", ret);
+#endif
+ return (EIO);
+ } else {
+ dp->last_blk = 0;
+ dp->last_read = 0;
+ }
+ }
+
+#ifdef PDCDEBUG
+ if (debug)
+ printf("seek %d ", dp->last_blk);
+#endif
+ for (; (dp->last_blk + dp->last_read) <= blk;
+ dp->last_read = ret) {
+ twiddle();
+ dp->last_blk += dp->last_read;
+ if ((ret = (iodc)(pzdev->pz_hpa,
+ IODC_IO_READ, pzdev->pz_spa, pzdev->pz_layers,
+ pdcbuf, dp->last_blk, dp->buf, IODC_IOSIZ,
+ IODC_IOSIZ)) < 0) {
+#ifdef DEBUG
+ if (debug)
+ printf("IODC_IO: %d\n", ret);
+#endif
+ return (EIO);
+ }
+ if ((ret = pdcbuf[0]) == 0)
+ break;
+#ifdef PDCDEBUG
+ if (debug)
+ printf("-");
+#endif
+ }
+#ifdef PDCDEBUG
+ if (debug)
+ printf("> %d[%d]\n", dp->last_blk, dp->last_read);
+#endif
+ }
+
+ xfer = 0;
+ /* see if we can scratch anything from buffer */
+ if (dp->last_blk <= blk && (dp->last_blk + dp->last_read) > blk) {
+ twiddle();
+ offset = blk - dp->last_blk;
+ xfer = min(dp->last_read - offset, size);
+ size -= xfer;
+ blk += xfer;
+#ifdef PDCDEBUG
+ if (debug)
+ printf("off=%d,xfer=%d,size=%d,blk=%d\n",
+ offset, xfer, size, blk);
+#endif
+ bcopy(dp->buf + offset, buf, xfer);
+ buf += xfer;
+ }
+
+ /*
+ * double buffer it all the time, to cache
+ */
+ for (; size; size -= ret, buf += ret, blk += ret, xfer += ret) {
+ offset = blk & IOPGOFSET;
+ if ((ret = (iodc)(pzdev->pz_hpa,
+ (rw == F_READ? IODC_IO_READ: IODC_IO_WRITE),
+ pzdev->pz_spa, pzdev->pz_layers, pdcbuf,
+ blk - offset, dp->buf, IODC_IOSIZ, IODC_IOSIZ)) < 0) {
+#ifdef DEBUG
+ if (debug)
+ printf("iodc_read(%d,%d): %d\n",
+ blk - offset, IODC_IOSIZ, ret);
+#endif
+ if (xfer)
+ break;
+ else
+ return (EIO);
+ }
+ if ((ret = pdcbuf[0]) <= 0)
+ break;
+ dp->last_blk = blk - offset;
+ dp->last_read = ret;
+ if ((ret -= offset) > size)
+ ret = size;
+ bcopy(dp->buf + offset, buf, ret);
+#ifdef PDCDEBUG
+ if (debug)
+ printf("read %d(%d,%d)@%x ", ret,
+ dp->last_blk, dp->last_read, (u_int)buf);
+#endif
+ }
+
+#ifdef PDCDEBUG
+ if (debug)
+ printf("\n");
+#endif
+
+ if (rsize)
+ *rsize = xfer;
+ return (0);
+}
+
+/*
+ * Find a device with specified unit number
+ * (any if unit == -1), and of specified class (PCL_*).
+ */
+struct pz_device *
+pdc_findev(unit, class)
+ int unit, class;
+{
+ static struct pz_device pz;
+ int layers[sizeof(pz.pz_layers)/sizeof(pz.pz_layers[0])];
+ iodcio_t iodc;
+ int err = 0;
+ u_int hpa, spa;
+
+#ifdef PDCDEBUG
+ if (debug)
+ printf("pdc_finddev(%d, %x)\n", unit, class);
+#endif
+ iodc = (iodcio_t)((u_long)PAGE0->mem_free + IODC_MAXSIZE);
+ hpa = PAGE0->mem_boot.pz_hpa;
+ spa = ((struct iomod *)(u_long)hpa)->io_spa;
+
+ /* quick hack for boot device */
+ if (PAGE0->mem_boot.pz_class == class &&
+ (unit == -1 || PAGE0->mem_boot.pz_layers[0] == unit)) {
+
+ bcopy (&PAGE0->mem_boot.pz_dp, &pz.pz_dp, sizeof(pz.pz_dp));
+ bcopy (pz.pz_layers, layers, sizeof(layers));
+ if ((err = (pdc)(PDC_IODC, PDC_IODC_READ, pdcbuf, hpa,
+ IODC_INIT, iodc, IODC_MAXSIZE)) < 0) {
+#ifdef DEBUG
+ if (debug)
+ printf("IODC_READ: %d\n", err);
+#endif
+ return NULL;
+ }
+ } else {
+ struct pdc_memmap memmap;
+ struct iodc_data mptr;
+ int i, stp;
+
+ for (i = 0; i < 0xf; i++) {
+ pz.pz_bc[0] = pz.pz_bc[1] =
+ pz.pz_bc[2] = pz.pz_bc[3] = -1;
+ pz.pz_bc[4] = 2;
+ pz.pz_bc[5] = 0; /* core bus */
+ pz.pz_mod = i;
+ if ((pdc)(PDC_MEMMAP, PDC_MEMMAP_HPA, &memmap,
+ &pz.pz_dp) < 0)
+ continue;
+#ifdef PDCDEBUG
+ if (debug)
+ printf("memap: %d.%d.%d, hpa=%x, mpgs=%x\n",
+ pz.pz_bc[4], pz.pz_bc[5], pz.pz_mod,
+ memmap.hpa, memmap.morepages);
+#endif
+ hpa = memmap.hpa;
+
+ if ((err = (pdc)(PDC_IODC, PDC_IODC_READ, &pdcbuf, hpa,
+ IODC_DATA, &mptr, sizeof(mptr))) < 0) {
+#ifdef DEBUG
+ if (debug)
+ printf("IODC_DATA: %d\n", err);
+#endif
+ continue;
+ }
+
+ if ((err = (pdc)(PDC_IODC, PDC_IODC_READ, pdcbuf, hpa,
+ IODC_INIT, iodc, IODC_MAXSIZE)) < 0) {
+#ifdef DEBUG
+ if (debug)
+ printf("IODC_READ: %d\n", err);
+#endif
+ continue;
+ }
+
+ stp = IODC_INIT_FIRST;
+ do {
+ if ((err = (iodc)(hpa, stp, spa, layers,
+ pdcbuf, 0, 0, 0, 0)) < 0) {
+#ifdef DEBUG
+ if (debug && err != PDC_ERR_EOD)
+ printf("IODC_INIT_%s: %d\n",
+ stp==IODC_INIT_FIRST?
+ "FIRST":"NEXT", err);
+#endif
+ break;
+ }
+#ifdef PDCDEBUG
+ if (debug)
+ printf("[%x,%x,%x,%x,%x,%x], "
+ "[%x,%x,%x,%x,%x,%x]\n",
+ pdcbuf[0], pdcbuf[1], pdcbuf[2],
+ pdcbuf[3], pdcbuf[4], pdcbuf[5],
+ layers[0], layers[1], layers[2],
+ layers[3], layers[4], layers[5]);
+#endif
+ stp = IODC_INIT_NEXT;
+
+ } while (pdcbuf[1] != class &&
+ unit != -1 && unit != layers[0]);
+
+ if (err >= 0)
+ break;
+ }
+ }
+
+ if (err >= 0) {
+ /* init device */
+ if (0 && (err = (iodc)(hpa, IODC_INIT_DEV, spa,
+ layers, pdcbuf, 0, 0, 0, 0)) < 0) {
+#ifdef DEBUG
+ if (debug)
+ printf("INIT_DEV: %d\n", err);
+#endif
+ return NULL;
+ }
+
+ /* read i/o entry code */
+ if ((err = (pdc)(PDC_IODC, PDC_IODC_READ, pdcbuf, hpa,
+ IODC_IO, iodc, IODC_MAXSIZE)) < 0) {
+#ifdef DEBUG
+ if (debug)
+ printf("IODC_READ: %d\n", err);
+#endif
+ return NULL;
+ }
+
+ pz.pz_flags = 0;
+ bcopy(layers, pz.pz_layers, sizeof(pz.pz_layers));
+ pz.pz_hpa = hpa;
+/* XXX pz.pz_spa = spa; */
+ pz.pz_iodc_io = (u_long)iodc;
+ pz.pz_class = class;
+
+ return &pz;
+ }
+
+ return NULL;
+}
+
+static __inline void
+fall(int c_base, int c_count, int c_loop, int c_stride, int data)
+{
+ int loop; /* Internal vars */
+
+ for (; c_count--; c_base += c_stride)
+ for (loop = c_loop; loop--; )
+ if (data)
+ fdce(0, c_base);
+ else
+ fice(0, c_base);
+}
+
+/*
+ * fcacheall - Flush all caches.
+ *
+ * This routine is just a wrapper around the real cache flush routine.
+ */
+struct pdc_cache pdc_cacheinfo PDC_ALIGNMENT;
+
+void
+fcacheall()
+{
+ int err;
+
+ if ((err = (*pdc)(PDC_CACHE, PDC_CACHE_DFLT, &pdc_cacheinfo)) < 0) {
+#ifdef DEBUG
+ if (debug)
+ printf("fcacheall: PDC_CACHE failed (%d).\n", err);
+#endif
+ return;
+ }
+#if PDCDEBUG
+ if (debug)
+ printf("pdc_cache:\nic={%u,%x,%x,%u,%u,%u}\n"
+ "dc={%u,%x,%x,%u,%u,%u}\n",
+ pdc_cacheinfo.ic_size, *(u_int *)&pdc_cacheinfo.ic_conf,
+ pdc_cacheinfo.ic_base, pdc_cacheinfo.ic_stride,
+ pdc_cacheinfo.ic_count, pdc_cacheinfo.ic_loop,
+ pdc_cacheinfo.dc_size, *(u_int *)&pdc_cacheinfo.ic_conf,
+ pdc_cacheinfo.dc_base, pdc_cacheinfo.dc_stride,
+ pdc_cacheinfo.dc_count, pdc_cacheinfo.dc_loop);
+#endif
+ /*
+ * Flush the instruction, then data cache.
+ */
+ fall(pdc_cacheinfo.ic_base, pdc_cacheinfo.ic_count,
+ pdc_cacheinfo.ic_loop, pdc_cacheinfo.ic_stride, 0);
+ sync_caches();
+ fall(pdc_cacheinfo.dc_base, pdc_cacheinfo.dc_count,
+ pdc_cacheinfo.dc_loop, pdc_cacheinfo.dc_stride, 1);
+ sync_caches();
+}
diff --git a/sys/arch/hppa64/stand/libsa/time.c b/sys/arch/hppa64/stand/libsa/time.c
new file mode 100644
index 00000000000..fd1fa22f1e7
--- /dev/null
+++ b/sys/arch/hppa64/stand/libsa/time.c
@@ -0,0 +1,47 @@
+/* $OpenBSD: time.c,v 1.1 2005/04/01 10:40:48 mickey Exp $ */
+
+/*
+ * Copyright (c) 2005 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <machine/pdc.h>
+#include <sys/disklabel.h>
+#include "libsa.h"
+#include "dev_hppa64.h"
+
+time_t
+getsecs()
+{
+ time_t tt;
+ int err;
+
+ if ((err = (*pdc)(PDC_TOD, PDC_TOD_READ, &pdcbuf)) < 0) {
+ tt = 0;
+#ifdef DEBUG
+ if (debug)
+ printf("getsecs: TOD read failed (%d)\n", err);
+#endif
+ } else {
+ tt = ((struct pdc_tod *)pdcbuf)->sec;
+#ifdef DEBUG
+ if (debug && tt < 800000000)
+ printf("getsecs: got %u seconds\n", tt);
+#endif
+ }
+
+ return tt;
+}
diff --git a/sys/arch/hppa64/stand/libz/Makefile b/sys/arch/hppa64/stand/libz/Makefile
new file mode 100644
index 00000000000..d6ed6c93837
--- /dev/null
+++ b/sys/arch/hppa64/stand/libz/Makefile
@@ -0,0 +1,10 @@
+# $OpenBSD: Makefile,v 1.1 2005/04/01 10:40:49 mickey Exp $
+
+S=${.CURDIR}/../../../..
+ZDST=${.OBJDIR}
+SADIR=${.CURDIR}/..
+
+.PATH: ${S}/lib/libz
+
+.include "${S}/lib/libz/Makefile"
+CFLAGS+=${SACFLAGS} -I${S}/lib/libsa
diff --git a/sys/arch/hppa64/stand/mkboot/Makefile b/sys/arch/hppa64/stand/mkboot/Makefile
new file mode 100644
index 00000000000..e83c1dd1f66
--- /dev/null
+++ b/sys/arch/hppa64/stand/mkboot/Makefile
@@ -0,0 +1,14 @@
+# $OpenBSD: Makefile,v 1.1 2005/04/01 10:40:49 mickey Exp $
+
+MAN= mkboot.8
+MANSUBDIR=hppa64
+
+.if ${MACHINE} == "hppa64"
+PROG= mkboot
+CC= ${HOSTCC}
+LDSTATIC= -static
+.else
+NOPROG=
+.endif
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/hppa64/stand/mkboot/mkboot.8 b/sys/arch/hppa64/stand/mkboot/mkboot.8
new file mode 100644
index 00000000000..536bc587019
--- /dev/null
+++ b/sys/arch/hppa64/stand/mkboot/mkboot.8
@@ -0,0 +1,58 @@
+.\" $OpenBSD: mkboot.8,v 1.1 2005/04/01 10:40:49 mickey Exp $
+.\"
+.\" Copyright (c) 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd November 11, 2002
+.Dt MKBOOT 8
+.Os
+.Sh NAME
+.Nm mkboot
+.Nd create LIF files
+.Sh SYNOPSIS
+.Nm mkboot
+.Op Fl v
+.Op Fl l Ar loadpoint
+.Ar program ... outfile
+.Sh DESCRIPTION
+Creates the LIF file containing the bootstrap
+.Ar program
+and possibly other programs to be used by the
+.Tn HP 9000/700
+and
+.Tn HP 9000/800
+systems.
+.Pp
+An argument to the
+.Fl l
+option specifies the load point for the boot program,
+with the default value of zero.
+.Sh HISTORY
+An
+.Nm
+utility first appeared in
+.Ox 2.4 .
diff --git a/sys/arch/hppa64/stand/mkboot/mkboot.c b/sys/arch/hppa64/stand/mkboot/mkboot.c
new file mode 100644
index 00000000000..ced89972b56
--- /dev/null
+++ b/sys/arch/hppa64/stand/mkboot/mkboot.c
@@ -0,0 +1,430 @@
+/* $OpenBSD: mkboot.c,v 1.1 2005/04/01 10:40:49 mickey Exp $ */
+
+/*
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)mkboot.c 8.1 (Berkeley) 7/15/93
+ */
+
+#if 0
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1990, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char rcsid[] = "$OpenBSD: mkboot.c,v 1.1 2005/04/01 10:40:49 mickey Exp $";
+#endif /* not lint */
+#endif
+
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#ifdef __OpenBSD__
+#include <err.h>
+#endif
+
+#include <sys/exec_aout.h>
+#include <sys/exec_elf.h>
+
+#ifndef hppa
+/* hack for cross compile XXX */
+#include "../../include/disklabel.h"
+#else
+#include <sys/disklabel.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+
+int putfile(char *, int);
+void __dead usage(void);
+void bcddate(char *, char *);
+char *lifname(char *);
+int cksum(int, int *, int);
+
+char *to_file;
+int loadpoint, verbose;
+u_long entry;
+#ifndef __OpenBSD__
+char *__progname = "mkboot";
+#endif
+
+/*
+ * Old Format:
+ * sector 0: LIF volume header (40 bytes)
+ * sector 1: <unused>
+ * sector 2: LIF directory (8 x 32 == 256 bytes)
+ * sector 3-: LIF file 0, LIF file 1, etc.
+ * where sectors are 256 bytes.
+ *
+ * New Format:
+ * sector 0: LIF volume header (40 bytes)
+ * sector 1: <unused>
+ * sector 2: LIF directory (8 x 32 == 256 bytes)
+ * sector 3: <unused>
+ * sector 4-31: disklabel (~300 bytes right now)
+ * sector 32-: LIF file 0, LIF file 1, etc.
+ */
+int
+main(int argc, char **argv)
+{
+ int to;
+ register int n, pos, c;
+ char buf[LIF_FILESTART];
+ struct lifvol *lifv = (struct lifvol *)buf;
+ struct lifdir *lifd = (struct lifdir *)(buf + LIF_DIRSTART);
+
+ while ((c = getopt(argc, argv, "vl:")) != -1) {
+ switch (c) {
+ case 'v':
+ verbose++;
+ break;
+ case 'l':
+ sscanf(optarg, "0x%x", &loadpoint);
+ break;
+ default:
+ usage();
+ }
+ }
+ if (argc - optind < 2)
+ usage();
+ else if (argc - optind > 8)
+ errx(1, "too many boot programs (max 8 supported)");
+
+ to_file = argv[--argc];
+ if ((to = open(to_file, O_RDWR | O_TRUNC | O_CREAT, 0644)) < 0)
+ err(1, "%s: open", to_file);
+
+ bzero(buf, sizeof(buf));
+ /* clear possibly unused directory entries */
+ memset(lifd[1].dir_name, ' ', sizeof lifd[1].dir_name);
+ lifd[1].dir_type = -1;
+ lifd[1].dir_addr = 0;
+ lifd[1].dir_length = 0;
+ lifd[1].dir_flag = 0xFF;
+ lifd[1].dir_implement = 0;
+ lifd[7] = lifd[6] = lifd[5] = lifd[4] = lifd[3] = lifd[2] = lifd[1];
+
+ /* record volume info */
+ lifv->vol_id = htobe16(LIF_VOL_ID);
+ strncpy(lifv->vol_label, "BOOT44", 6);
+ lifv->vol_addr = htobe32(btolifs(LIF_DIRSTART));
+ lifv->vol_oct = htobe16(LIF_VOL_OCT);
+ lifv->vol_dirsize = htobe32(btolifs(LIF_DIRSIZE));
+ lifv->vol_version = htobe16(1);
+ lifv->vol_lastvol = lifv->vol_number = htobe16(1);
+ lifv->vol_length = LIF_FILESTART;
+ bcddate(to_file, lifv->vol_toc);
+ lifv->ipl_addr = htobe32(LIF_FILESTART);
+ lifv->ipl_size = 0;
+ lifv->ipl_entry = 0;
+
+ argv += optind;
+ argc -= optind;
+ optind = 0;
+ for (pos = LIF_FILESTART; optind < argc; optind++) {
+
+ /* output bootfile */
+ lseek(to, pos, 0);
+ lifd[optind].dir_addr = htobe32(btolifs(pos));
+ n = btolifs(putfile(argv[optind], to));
+ if (lifv->ipl_entry == 0) {
+ lifv->ipl_entry = htobe32(loadpoint + entry);
+ lifv->ipl_size = htobe32(lifstob(n));
+ lifd[optind].dir_type = htobe16(LIF_DIR_ISL);
+ lifd[optind].dir_implement = 0;
+ } else {
+ lifd[optind].dir_type = htobe16(LIF_DIR_TYPE);
+ lifd[1].dir_implement = htobe32(loadpoint + entry);
+ }
+
+ strlcpy(lifd[optind].dir_name, lifname(argv[optind]),
+ sizeof lifd[optind].dir_name);
+ lifd[optind].dir_length = htobe32(n);
+ bcddate(argv[optind], lifd[optind].dir_toc);
+ lifd[optind].dir_flag = htobe16(LIF_DIR_FLAG);
+
+ lifv->vol_length += n;
+ pos += lifstob(n);
+ }
+
+ lifv->vol_length = htobe32(lifv->vol_length);
+
+ /* output volume/directory header info */
+ lseek(to, LIF_VOLSTART, 0);
+ if (write(to, buf, sizeof(buf)) != sizeof(buf))
+ err(1, "%s: write LIF volume", to_file);
+ lseek(to, 0, SEEK_END);
+
+ if (close(to) < 0)
+ err(1, "%s", to_file);
+
+ return(0);
+}
+
+int
+putfile(from_file, to)
+ char *from_file;
+ int to;
+{
+ struct exec ex;
+ register int n, total;
+ char buf[2048];
+ int from, check_sum = 0;
+ struct lif_load load;
+
+ if ((from = open(from_file, O_RDONLY)) < 0)
+ err(1, "%s", from_file);
+
+ n = read(from, &ex, sizeof(ex));
+ if (n != sizeof(ex))
+ err(1, "%s: reading file header", from_file);
+
+ entry = ex.a_entry;
+ if (N_GETMAGIC(ex) == OMAGIC || N_GETMAGIC(ex) == NMAGIC)
+ entry += sizeof(ex);
+ else if (IS_ELF(*(Elf64_Ehdr *)&ex)) {
+ Elf64_Ehdr elf_header;
+ Elf64_Phdr *elf_segments;
+ int i,header_count, memory_needed, elf_load_image_segment;
+
+ (void) lseek(from, 0, SEEK_SET);
+ n = read(from, &elf_header, sizeof (elf_header));
+ if (n != sizeof (elf_header))
+ err(1, "%s: reading ELF header", from_file);
+ header_count = betoh32(elf_header.e_phnum);
+ memory_needed = header_count * sizeof (*elf_segments);
+ elf_segments = malloc(memory_needed);
+ if (elf_segments == NULL)
+ err(1, "malloc");
+ (void) lseek(from, betoh32(elf_header.e_phoff), SEEK_SET);
+ n = read(from, elf_segments, memory_needed);
+ if (n != memory_needed)
+ err(1, "%s: reading ELF segments", from_file);
+ elf_load_image_segment = -1;
+ for (i = 0; i < header_count; i++) {
+ if (elf_segments[i].p_filesz &&
+ elf_segments[i].p_type == htobe32(PT_LOAD) &&
+ elf_segments[i].p_flags & htobe32(PF_X)) {
+ if (elf_load_image_segment != -1)
+ warnx("%s: more than one ELF program segment", from_file);
+ else
+ elf_load_image_segment = i;
+ }
+ }
+ if (elf_load_image_segment == -1)
+ errx(1, "%s: no suitable ELF program segment", from_file);
+ entry = betoh32(elf_header.e_entry) +
+ betoh32(elf_segments[elf_load_image_segment].p_offset) -
+ betoh32(elf_segments[elf_load_image_segment].p_vaddr);
+ } else if (*(u_char *)&ex == 0x1f && ((u_char *)&ex)[1] == 0x8b) {
+ entry = 0;
+ } else
+ errx(1, "%s: bad magic number", from_file);
+
+ entry += sizeof(load);
+ lseek(to, sizeof(load), SEEK_CUR);
+ total = 0;
+ n = sizeof(buf) - sizeof(load);
+ /* copy the whole file */
+ for (lseek(from, 0, 0); ; n = sizeof(buf)) {
+ bzero(buf, sizeof(buf));
+ if ((n = read(from, buf, n)) < 0)
+ err(1, "%s", from_file);
+ else if (n == 0)
+ break;
+
+ if (write(to, buf, n) != n)
+ err(1, "%s", to_file);
+
+ total += n;
+ check_sum = cksum(check_sum, (int *)buf, n);
+ }
+
+ /* load header */
+ load.address = htobe32(loadpoint + sizeof(load));
+ load.count = htobe32(4 + total);
+ check_sum = cksum(check_sum, (int *)&load, sizeof(load));
+
+ if (verbose)
+ warnx("wrote %d bytes of file \'%s\'", total, from_file);
+
+ total += sizeof(load);
+ /* insert the header */
+ lseek(to, -total, SEEK_CUR);
+ if (write(to, &load, sizeof(load)) != sizeof(load))
+ err(1, "%s", to_file);
+ lseek(to, total - sizeof(load), SEEK_CUR);
+
+ bzero(buf, sizeof(buf));
+ /* pad to int */
+ n = sizeof(int) - total % sizeof(int);
+ if (total % sizeof(int)) {
+ if (write(to, buf, n) != n)
+ err(1, "%s", to_file);
+ else
+ total += n;
+ }
+
+ /* pad to the blocksize */
+ n = sizeof(buf) - total % sizeof(buf);
+
+ if (n < sizeof(int)) {
+ n += sizeof(buf);
+ total += sizeof(buf);
+ } else
+ total += n;
+
+ /* TODO should pad here to the 65k boundary for tape boot */
+
+ if (verbose)
+ warnx("checksum is 0x%08x", -check_sum);
+
+ check_sum = htobe32(-check_sum);
+ if (write(to, &check_sum, sizeof(int)) != sizeof(int))
+ err(1, "%s", to_file);
+
+ n -= sizeof(int);
+
+ if (write(to, buf, n) != n)
+ err(1, "%s", to_file);
+
+ if (close(from) < 0 )
+ err(1, "%s", from_file);
+
+ return total;
+}
+
+int
+cksum(ck, p, size)
+ int ck;
+ int *p;
+ int size;
+{
+ /* we assume size is int-aligned */
+ for (size = (size + sizeof(int) - 1) / sizeof(int); size--; p++ )
+ ck += betoh32(*p);
+
+ return ck;
+}
+
+void __dead
+usage()
+{
+ extern char *__progname;
+ fprintf(stderr,
+ "usage: %s [-v] [-l loadpoint] prog1 {progN} outfile\n",
+ __progname);
+ exit(1);
+}
+
+char *
+lifname(str)
+ char *str;
+{
+ static char lname[10] = "XXXXXXXXXX";
+ register int i;
+
+ for (i = 0; i < 9; i++) {
+ if (islower(*str))
+ lname[i] = toupper(*str);
+ else if (isalnum(*str) || *str == '_')
+ lname[i] = *str;
+ else
+ break;
+ str++;
+ }
+ for ( ; i < 10; i++)
+ lname[i] = ' ';
+ return(lname);
+}
+
+
+void
+bcddate(file, toc)
+ char *file;
+ char *toc;
+{
+ struct stat statb;
+#ifndef __OpenBSD__
+ struct tm {
+ int tm_sec; /* second (0-61, allows for leap seconds) */
+ int tm_min; /* minute (0-59) */
+ int tm_hour; /* hour (0-23) */
+ int tm_mday; /* day of the month (1-31) */
+ int tm_mon; /* month (0-11) */
+ int tm_year; /* years since 1900 */
+ int tm_wday; /* day of the week (0-6) */
+ int tm_yday; /* day of the year (0-365) */
+ int tm_isdst; /* non-0 if daylight saving time is in effect */
+ } *tm;
+#else
+ struct tm *tm;
+#endif
+
+ stat(file, &statb);
+ tm = localtime(&statb.st_ctime);
+ *toc = (tm->tm_year / 10) << 4;
+ *toc++ |= tm->tm_year % 10;
+ *toc = ((tm->tm_mon+1) / 10) << 4;
+ *toc++ |= (tm->tm_mon+1) % 10;
+ *toc = (tm->tm_mday / 10) << 4;
+ *toc++ |= tm->tm_mday % 10;
+ *toc = (tm->tm_hour / 10) << 4;
+ *toc++ |= tm->tm_hour % 10;
+ *toc = (tm->tm_min / 10) << 4;
+ *toc++ |= tm->tm_min % 10;
+ *toc = (tm->tm_sec / 10) << 4;
+ *toc |= tm->tm_sec % 10;
+}
+
+#ifndef __OpenBSD__
+int
+err(ex, str)
+ int ex;
+ char *str;
+{
+ perror(str);
+ exit(ex);
+}
+
+int
+errx(ex, str)
+ int ex;
+ char *str;
+{
+ perror(str);
+ exit(ex);
+}
+#endif