diff options
Diffstat (limited to 'sys')
157 files changed, 26259 insertions, 0 deletions
diff --git a/sys/arch/mvmeppc/compile/.cvsignore b/sys/arch/mvmeppc/compile/.cvsignore new file mode 100644 index 00000000000..b72af3039e6 --- /dev/null +++ b/sys/arch/mvmeppc/compile/.cvsignore @@ -0,0 +1,2 @@ +GENERIC +RAMDISK diff --git a/sys/arch/mvmeppc/conf/GENERIC b/sys/arch/mvmeppc/conf/GENERIC new file mode 100644 index 00000000000..a8a9651d459 --- /dev/null +++ b/sys/arch/mvmeppc/conf/GENERIC @@ -0,0 +1,89 @@ +# $OpenBSD: GENERIC,v 1.1 2001/06/26 21:57:37 smurph Exp $ +# +# MVMEPPC GENERIC config file +# + +machine mvmeppc + +maxusers 32 + +# default type, instructs system to try to determin what proper type is +# actual machine type probed via name of openfirmware root node. +option SYS_TYPE=APPL + +option UVM +option PCIVERBOSE + +include "../../../conf/GENERIC" + +config bsd swap generic + +# +# Now the Machine specification +# +mainbus0 at root +cpu* at mainbus0 +bugtty0 at mainbus0 +raven0 at mainbus0 # raven ASIC + +#### PCI Bus devices. + +openpic0 at raven0 # interrupt controller +#mpic0 at raven0 # interrupt controller +mpcpcibr0 at raven0 # PCI controller +pci* at mpcpcibr0 +#ppb* at pci? dev ? function ? # PCI-PCI bridges +#pci* at ppb? bus ? + +# host bridge identifiers + +pchb* at pci? # PCI host bridge +pcib* at pci? dev ? function ? # PCI-ISA bridge +siop* at pci? dev ? function ? +#ncr* at pci? dev ? function ? +de* at pci? dev ? function ? +#vme* at pci? dev ? function ? +#pciide* at pci? dev ? function ? + +# ISA Bus +isa* at pcib? +#pckbc0 at isa? # PC keyboard controller +#pckbd* at pckbc? # PC keyboard +#pms* at pckbc? # PS/2 mouse for wsmouse +#pmsi* at pckbc? # PS/2 "Intelli"mouse for wsmouse +#vga0 at isa? +#vga* at pci? dev ? function ? +#com* at isa? port 0x3f8 irq 4 # standard serial ports +#com* at isa? port 0x2f8 irq 3 +#lpt* at isa? port 0x3bc irq 7 # standard parallel port + +# how many of these are needed? +#ukphy* at mii? phy ? # generic unknown PHYs + +#nvram* at mainbus0 # nvram +#zsc* at obio? +#zstty* at zsc? channel ? + +#### SCSI attachment points + +scsibus* at siop? +#scsibus* at ncr? + +#wdc* at mainbus? flags 0x0 +#wd* at wdc? drive ? flags 0x0000 + +#atapiscsi* at wdc? channel ? flags 0x0000 + +# ATAPI<->SCSI +#scsibus* at atapiscsi? + +#### SCSI Bus devices + +sd0 at scsibus? target 0 lun 0 +#st* at scsibus? target ? lun ? +#cd* at scsibus? target ? lun ? +#ch* at scsibus? target ? lun ? +#ss* at scsibus? target ? lun ? +#uk* at scsibus? target ? lun ? + + diff --git a/sys/arch/mvmeppc/conf/Makefile.mvmeppc b/sys/arch/mvmeppc/conf/Makefile.mvmeppc new file mode 100644 index 00000000000..0dae2924c2c --- /dev/null +++ b/sys/arch/mvmeppc/conf/Makefile.mvmeppc @@ -0,0 +1,184 @@ +# $OpenBSD: Makefile.mvmeppc,v 1.1 2001/06/26 21:57:38 smurph Exp $ +# +# Makefile for OpenBSD PowerPC +# +# This makefile is constructed from a machine description: +# config machineid +# Most changes should be made in the machine description +# /sys/arch/powerpc/conf/``machineid'' +# after which you should do +# config machineid +# Machine generic makefile changes should be made in +# /sys/arch/powerpc/conf/Makefile.powerpc +# 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 +# +.SUFFIXES: .S .c .o + +# DEBUG is set to -g if debugging. +# PROF is set to -pg if profiling. + +AS?= as +CC?= cc +CPP?= cpp +LD?= ld +MKDEP?= mkdep +STRIP?= strip +SIZE?= size + +# source tree is located via $S relative to the compilation directory +#.ifndef S +#S!= cd ../../../..; pwd +#.endif +S= ../../../.. +PPC= ../.. + +INCLUDES= -I. -I$S/arch -I$S -nostdinc -L${DESTDIR}/usr/include +CPPFLAGS= ${INCLUDES} ${IDENT} -D_KERNEL \ + -Dpowerpc -Dmvmeppc +CWARNFLAGS= -Werror -Wreturn-type +CFLAGS= ${DEBUG} ${CWARNFLAGS} -O2 -msoft-float +AFLAGS= -D_LOCORE +LINKFLAGS= -N -Ttext 100074 -e start +STRIPFLAGS= -d + +HOSTCC?= ${CC} +HOSTED_CPPFLAGS=${CPPFLAGS:S/^-nostdinc$//} +HOSTED_CFLAGS= ${CFLAGS} + +### 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}${CONFIG_DEP} +# where TYPE is NORMAL, DRIVER, or PROFILE}; SUFFIX is the file suffix, +# capitalized (e.g. C for a .c file), and CONFIG_DEP is _C if the file +# is marked as config-dependent. + +USRLAND_C= ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c $< +USRLAND_C_C= ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} ${PARAM} -c $< + +NORMAL_C= ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c $< +NORMAL_C_C= ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} ${PARAM} -c $< + +DRIVER_C= ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c $< +DRIVER_C_C= ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} ${PARAM} -c $< + +NORMAL_S= ${CC} ${AFLAGS} ${CPPFLAGS} -c $< +NORMAL_S_C= ${AS} ${COPTS} ${PARAM} $< -o $@ + + +%OBJS + +%CFILES + +%SFILES + +# load lines for config "xxx" will be emitted as: +# xxx: ${SYSTEM_DEP} swapxxx.o +# ${SYSTEM_LD_HEAD} +# ${SYSTEM_LD} swapxxx.o +# ${SYSTEM_LD_TAIL} +SYSTEM_OBJ= locore.o param.o ioconf.o ${OBJS} ${LIBKERN} ${LIBCOMPAT} +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" +LINKFLAGS+= -X +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 ${PPC}/mvmeppc/genassym.cf + sh $S/kern/genassym.sh ${CC} ${CFLAGS} ${CPPFLAGS} \ + < ${PPC}/mvmeppc/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_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.gdb tags *.[io] [a-z]*.s \ + [Ee]rrs linterrs makelinks genassym genassym.o assym.h + +lint: + @lint -hbxncez -DGENERIC -Dvolatile= ${CPPFLAGS} -UKGDB \ + ${PPC}/mvmeppc/Locore.c ${CFILES} ${PPC}/mvmeppc/swapgeneric.c \ + 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= ${PPC}/mvmeppc/locore.S \ + param.c ioconf.c ${CFILES} ${SFILES} +depend:: .depend +.depend: ${SRCS} assym.h param.c + ${MKDEP} ${AFLAGS} ${CPPFLAGS} ${PPC}/mvmeppc/locore.S + ${MKDEP} -a ${CFLAGS} ${CPPFLAGS} param.c ioconf.c ${CFILES} +.if ${SFILES} != "" + ${MKDEP} -a ${AFLAGS} ${CPPFLAGS} ${SFILES} +.endif + +# 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 +genassym.o machdep.o: Makefile + +# depend on CPU configuration +locore.o machdep.o: Makefile + + +locore.o: ${PPC}/mvmeppc/locore.S assym.h + ${NORMAL_S} + +%RULES diff --git a/sys/arch/mvmeppc/conf/RAMDISK b/sys/arch/mvmeppc/conf/RAMDISK new file mode 100644 index 00000000000..06fe720a7a6 --- /dev/null +++ b/sys/arch/mvmeppc/conf/RAMDISK @@ -0,0 +1,94 @@ +# $OpenBSD: RAMDISK,v 1.1 2001/06/26 21:57:38 smurph Exp $ +# +# MVMEPPC GENERIC config file +# + +machine mvmeppc + +maxusers 32 + +# default type, instructs system to try to determin what proper type is +# actual machine type probed via name of openfirmware root node. +option SYS_TYPE=APPL + +option UVM +option PCIVERBOSE + +include "../../../conf/GENERIC" + +config bsd root on rd0a swap on rd0b + +# +# Now the Machine specification +# +mainbus0 at root +cpu* at mainbus0 +bugtty0 at mainbus0 +raven0 at mainbus0 # raven ASIC + +#### PCI Bus devices. + +openpic0 at raven0 # interrupt controller +#mpic0 at raven0 # interrupt controller +mpcpcibr0 at raven0 # PCI controller +pci* at mpcpcibr0 +#ppb* at pci? dev ? function ? # PCI-PCI bridges +#pci* at ppb? bus ? + +# host bridge identifiers + +pchb* at pci? # PCI host bridge +pcib* at pci? dev ? function ? # PCI-ISA bridge +siop* at pci? dev ? function ? +#ncr* at pci? dev ? function ? +de* at pci? dev ? function ? +#vme* at pci? dev ? function ? +#pciide* at pci? dev ? function ? + +# ISA Bus +isa* at pcib? +#pckbc0 at isa? # PC keyboard controller +#pckbd* at pckbc? # PC keyboard +#pms* at pckbc? # PS/2 mouse for wsmouse +#pmsi* at pckbc? # PS/2 "Intelli"mouse for wsmouse +#vga0 at isa? +#vga* at pci? dev ? function ? +#com* at isa? port 0x3f8 irq 4 # standard serial ports +#com* at isa? port 0x2f8 irq 3 +#lpt* at isa? port 0x3bc irq 7 # standard parallel port + +# how many of these are needed? +#ukphy* at mii? phy ? # generic unknown PHYs + +#nvram* at mainbus0 # nvram +#zsc* at obio? +#zstty* at zsc? channel ? + +#### SCSI attachment points + +scsibus* at siop? +#scsibus* at ncr? + +#wdc* at mainbus? flags 0x0 +#wd* at wdc? drive ? flags 0x0000 + +#atapiscsi* at wdc? channel ? flags 0x0000 + +# ATAPI<->SCSI +#scsibus* at atapiscsi? + +#### SCSI Bus devices + +sd0 at scsibus? target 0 lun 0 +#st* at scsibus? target ? lun ? +#cd* at scsibus? target ? lun ? +#ch* at scsibus? target ? lun ? +#ss* at scsibus? target ? lun ? +#uk* at scsibus? target ? lun ? + +pseudo-device rd 1 # ram disk + +# RAMDISK stuff +option MINIROOTSIZE=8192 +option RAMDISK_HOOKS + diff --git a/sys/arch/mvmeppc/conf/files.mvmeppc b/sys/arch/mvmeppc/conf/files.mvmeppc new file mode 100644 index 00000000000..df0fadd8527 --- /dev/null +++ b/sys/arch/mvmeppc/conf/files.mvmeppc @@ -0,0 +1,133 @@ +# +# powerpc-specific configuration info +# +maxpartitions 16 + +maxusers 2 8 64 + +file dev/cons.c +file dev/cninit.c +file arch/mvmeppc/ddb/setjmp.S ddb +file arch/mvmeppc/ddb/db_memrw.c ddb +file arch/mvmeppc/ddb/db_disasm.c ddb +file arch/mvmeppc/ddb/db_interface.c ddb +file arch/mvmeppc/ddb/db_trace.c ddb + +file arch/mvmeppc/dev/bugio.c +file arch/mvmeppc/dev/clock.c +file arch/mvmeppc/dev/mem.c + +file arch/powerpc/powerpc/Locore.c +file arch/mvmeppc/mvmeppc/autoconf.c +file arch/powerpc/powerpc/bcopy.c +file arch/mvmeppc/mvmeppc/conf.c +file arch/powerpc/powerpc/copyinstr.c +file arch/powerpc/powerpc/copyoutstr.c +file arch/powerpc/powerpc/copystr.c +file arch/mvmeppc/mvmeppc/disksubr.c disk +file arch/powerpc/powerpc/fpu.c +file arch/powerpc/powerpc/fubyte.c +file arch/powerpc/powerpc/fuswintr.c +file arch/powerpc/powerpc/in_cksum.c +file arch/powerpc/powerpc/ipkdb_glue.c ipkdb +file arch/mvmeppc/mvmeppc/machdep.c +#file arch/powerpc/powerpc/wscons_machdep.c +file arch/mvmeppc/mvmeppc/bus_space.c +file arch/mvmeppc/mvmeppc/bus_dma.c +file arch/mvmeppc/mvmeppc/pmap.c +file arch/mvmeppc/mvmeppc/ppc1_machdep.c +file arch/mvmeppc/mvmeppc/process_machdep.c +file arch/powerpc/powerpc/subyte.c +file arch/powerpc/powerpc/suword.c +file arch/powerpc/powerpc/suswintr.c +file arch/mvmeppc/mvmeppc/sys_machdep.c +file arch/mvmeppc/mvmeppc/trap.c +file arch/mvmeppc/mvmeppc/vm_machdep.c + +# +# Media Indepedent Interface (mii) +# +include "../../../dev/mii/files.mii" + +define mainbus {} +device mainbus +attach mainbus at root +file arch/mvmeppc/dev/mainbus.c mainbus + +device cpu +attach cpu at mainbus +file arch/mvmeppc/dev/cpu.c + +device raven {} +attach raven at mainbus +file arch/mvmeppc/dev/raven.c + +device openpic +attach openpic at raven +file arch/mvmeppc/dev/openpic.c + +major {rd = 17} + +# PCI bus support +# XXX Dummy bus needed for some multi-homed devices specified in files.isa +define pcmcia {} +include "dev/pci/files.pci" # XXX some ISA devs are 'at pci' too. + +# Ethernet driver for DC21140A-based SBCs +device vde: ether, ifnet, ifmedia +attach vde at pci +file arch/mvmeppc/pci/if_vde.c vde + +device mpcpcibr {} : pcibus +attach mpcpcibr at raven +file arch/mvmeppc/pci/mpcpcibr.c mpcpcibr + +# PCI-Host bridge chipsets +device pchb: pcibus +attach pchb at pci +file arch/mvmeppc/pci/pchb.c pchb + +# +# ISA Bus devices +# +include "dev/isa/files.isa" +include "dev/isa/files.isapnp" +file arch/mvmeppc/isa/isa_machdep.c isa + +# PCI-ISA bridge chipsets +device pcib: isabus +attach pcib at pci +file arch/mvmeppc/pci/pcib.c pcib + +include "dev/pckbc/files.pckbc" + +major {sd = 2} # hey this was 0 but at slot 2 in bdevsw XXX +major {cd = 3} +include "../../../scsi/files.scsi" + +# +# "workstation console" routines +# + +#include "dev/wscons/files.wscons" + +# Machine-independent ATAPI drivers + +include "../../../dev/atapiscsi/files.atapiscsi" +include "../../../dev/ata/files.ata" + +# MAC periph ??? XXX smurph + +#device zsc {channel = -1} +#attach zsc at obio +#file arch/powerpc/mac/zs.c zsc needs-flag +#file dev/ic/z8530sc.c zsc + +#device zstty: tty +#attach zstty at zsc +#file dev/ic/z8530tty.c zstty needs-flag + +device bugtty: tty +attach bugtty at mainbus +file arch/mvmeppc/dev/bugtty.c bugtty needs-flag + diff --git a/sys/arch/mvmeppc/ddb/db_disasm.c b/sys/arch/mvmeppc/ddb/db_disasm.c new file mode 100644 index 00000000000..42f5bb6c6c7 --- /dev/null +++ b/sys/arch/mvmeppc/ddb/db_disasm.c @@ -0,0 +1,865 @@ +/* $OpenBSD: db_disasm.c,v 1.1 2001/06/26 21:57:39 smurph Exp $ */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> + +#include <machine/db_machdep.h> + +#include <ddb/db_access.h> +#include <ddb/db_sym.h> +#include <ddb/db_variables.h> +#include <ddb/db_interface.h> + +enum function_mask { + Op_A = 0x00000001, + Op_B = 0x00000002, + Op_BI = 0x00000004, + Op_BO = 0x00000008, + Op_CRM = 0x00000010, + Op_D = 0x00000020, /* yes, Op_S and Op_D are the same */ + Op_S = 0x00000020, + Op_FM = 0x00000040, + Op_IMM = 0x00000080, + Op_LK = 0x00000100, + Op_Rc = 0x00000200, + Op_AA = Op_LK | Op_Rc, /* kludge (reduce Op_s) */ + Op_LKM = Op_AA, + Op_RcM = Op_AA, + Op_OE = 0x00000400, + Op_SR = 0x00000800, + Op_TO = 0x00001000, + Op_sign = 0x00002000, + Op_const = 0x00004000, + Op_SIMM = Op_const | Op_sign, + Op_UIMM = Op_const, + Op_d = Op_const | Op_sign, + Op_crbA = 0x00008000, + Op_crbB = 0x00010000, + Op_crbD = 0x00020000, + Op_crfD = 0x00040000, + Op_crfS = 0x00080000, + Op_ds = 0x00100000, + Op_me = 0x00200000, + Op_spr = 0x00400000, + Op_tbr = 0x00800000, + + Op_L = 0x01000000, + Op_BD = 0x02000000, + Op_LI = 0x04000000, + Op_C = 0x08000000, + + Op_NB = 0x10000000, + + Op_sh_mb_sh = 0x20000000, + Op_sh = 0x40000000, + Op_SH = Op_sh | Op_sh_mb_sh, + Op_mb = 0x80000000, + Op_MB = Op_mb | Op_sh_mb_sh, + Op_ME = Op_MB, + +}; + +struct opcode { + char *name; + u_int32_t mask; + u_int32_t code; + enum function_mask func; +}; + +typedef u_int32_t instr_t; +typedef void (op_class_func) (u_int32_t addr, instr_t); + +void dis_ppc(u_int32_t, const struct opcode *opcodeset, instr_t instr); + +op_class_func op_ill, op_base; +op_class_func op_cl_x13, op_cl_x1e, op_cl_x1f; +op_class_func op_cl_x3a, op_cl_x3b; +op_class_func op_cl_x3e, op_cl_x3f; + +op_class_func *opcodes_base[] = { +/*x00*/ op_ill, op_ill, op_base, op_ill, +/*x04*/ op_ill, op_ill, op_ill, op_base, +/*x08*/ op_base, op_base, op_ill, op_base, +/*x0C*/ op_base, op_base, op_base/*XXX*/, op_base/*XXX*/, +/*x10*/ op_base, op_base, op_base, op_cl_x13, +/*x14*/ op_base, op_base, op_ill, op_base, +/*x18*/ op_base, op_base, op_base, op_base, +/*x1C*/ op_base, op_base, op_cl_x1e, op_cl_x1f, +/*x20*/ op_base, op_base, op_base, op_base, +/*x24*/ op_base, op_base, op_base, op_base, +/*x28*/ op_base, op_base, op_base, op_base, +/*x2C*/ op_base, op_base, op_base, op_base, +/*x30*/ op_base, op_base, op_base, op_base, +/*x34*/ op_base, op_base, op_base, op_base, +/*x38*/ op_ill, op_ill, op_cl_x3a, op_cl_x3b, +/*x3C*/ op_ill, op_ill, op_cl_x3e, op_cl_x3f +}; + + +/* This table could be modified to make significant the "reserved" fields + * of the opcodes, But I didn't feel like it when typing in the table, + * I would recommend that this table be looked over for errors, + * This was derived from the table in Appendix A.2 of (Mot part # MPCFPE/AD) + * PowerPC Microprocessor Family: The Programming Environments + */ + +const struct opcode opcodes[] = { + { "tdi", 0xfc000000, 0x08000000, Op_TO | Op_A | Op_SIMM }, + { "twi", 0xfc000000, 0x0c000000, Op_TO | Op_A | Op_SIMM }, + { "mulli", 0xfc000000, 0x1c000000, Op_D | Op_A | Op_SIMM }, + { "subfic", 0xfc000000, 0x20000000, Op_D | Op_A | Op_SIMM }, + { "cmpli", 0xfc000000, 0x28000000, Op_crfD | Op_L | Op_A | Op_SIMM }, + { "cmpi", 0xfc000000, 0x2c000000, Op_crfD | Op_L | Op_A | Op_SIMM }, + { "addic", 0xfc000000, 0x30000000, Op_D | Op_A | Op_SIMM }, + { "addic.", 0xfc000000, 0x34000000, Op_D | Op_A | Op_SIMM }, + { "addi", 0xfc000000, 0x38000000, Op_D | Op_A | Op_SIMM }, + { "addis", 0xfc000000, 0x3c000000, Op_D | Op_A | Op_SIMM }, + { "bc", 0xfc000000, 0x40000000, Op_BO | Op_BI | Op_BD | Op_AA | Op_LK }, + { "sc", 0xffffffff, 0x44000002, Op_BO | Op_BI | Op_BD | Op_AA | Op_LK }, + { "b", 0xfc000000, 0x48000000, Op_LI | Op_AA | Op_LK }, + + { "rlwimi", 0xfc000000, 0x50000000, Op_S | Op_A | Op_SH | Op_MB | Op_ME | Op_Rc }, + { "rlwinmi", 0xfc000000, 0x54000000, Op_S | Op_A | Op_SH | Op_MB | Op_ME | Op_Rc }, + { "rlwnmi", 0xfc000000, 0x5C000000, Op_S | Op_A | Op_SH | Op_MB | Op_ME | Op_Rc }, + + { "ori", 0xfc000000, 0x60000000, Op_S | Op_A | Op_UIMM }, + { "oris", 0xfc000000, 0x64000000, Op_S | Op_A | Op_UIMM }, + { "xori", 0xfc000000, 0x68000000, Op_S | Op_A | Op_UIMM }, + { "xoris", 0xfc000000, 0x6C000000, Op_S | Op_A | Op_UIMM }, + + { "andi.", 0xfc000000, 0x70000000, Op_S | Op_A | Op_UIMM }, + { "andis.", 0xfc000000, 0x74000000, Op_S | Op_A | Op_UIMM }, + + { "lwz", 0xfc000000, 0x80000000, Op_D | Op_A | Op_d }, + { "lwzu", 0xfc000000, 0x84000000, Op_D | Op_A | Op_d }, + { "lbz", 0xfc000000, 0x88000000, Op_D | Op_A | Op_d }, + { "lbzu", 0xfc000000, 0x8c000000, Op_D | Op_A | Op_d }, + { "stw", 0xfc000000, 0x90000000, Op_S | Op_A | Op_d }, + { "stwu", 0xfc000000, 0x94000000, Op_S | Op_A | Op_d }, + { "stb", 0xfc000000, 0x98000000, Op_S | Op_A | Op_d }, + { "stbu", 0xfc000000, 0x9c000000, Op_S | Op_A | Op_d }, + + { "lhz", 0xfc000000, 0xa0000000, Op_D | Op_A | Op_d }, + { "lhzu", 0xfc000000, 0xa4000000, Op_D | Op_A | Op_d }, + { "lha", 0xfc000000, 0xa8000000, Op_D | Op_A | Op_d }, + { "lhau", 0xfc000000, 0xac000000, Op_D | Op_A | Op_d }, + { "sth", 0xfc000000, 0xb0000000, Op_S | Op_A | Op_d }, + { "sthu", 0xfc000000, 0xb4000000, Op_S | Op_A | Op_d }, + { "lmw", 0xfc000000, 0xb8000000, Op_D | Op_A | Op_d }, + { "stmw", 0xfc000000, 0xbc000000, Op_S | Op_A | Op_d }, + + { "lfs", 0xfc000000, 0xc0000000, Op_D | Op_A | Op_d }, + { "lfsu", 0xfc000000, 0xc4000000, Op_D | Op_A | Op_d }, + { "lfd", 0xfc000000, 0xc8000000, Op_D | Op_A | Op_d }, + { "lfdu", 0xfc000000, 0xcc000000, Op_D | Op_A | Op_d }, + + { "stfs", 0xfc000000, 0xd0000000, Op_S | Op_A | Op_d }, + { "stfsu", 0xfc000000, 0xd4000000, Op_S | Op_A | Op_d }, + { "stfd", 0xfc000000, 0xd8000000, Op_S | Op_A | Op_d }, + { "stfdu", 0xfc000000, 0xdc000000, Op_S | Op_A | Op_d }, + { "", 0x0, 0x0, 0 } + +}; +/* 13 * 4 = 4c */ +const struct opcode opcodes_13[] = { +/* 0x13 << 2 */ + { "mcrf", 0xfc0007fe, 0x4c000000, Op_crfD | Op_crfS }, + { "bclr", 0xfc0007fe, 0x4c000020, Op_BO | Op_BI | Op_LK }, + { "crnor", 0xfc0007fe, 0x4c000042, Op_crbD | Op_crbA | Op_crbB }, + { "rfi", 0xfc0007fe, 0x4c000064, 0 }, + { "crandc", 0xfc0007fe, 0x4c000102, Op_BO | Op_BI | Op_LK }, + { "isync", 0xfc0007fe, 0x4c00012c, 0 }, + { "crxor", 0xfc0007fe, 0x4c000182, Op_crbD | Op_crbA | Op_crbB }, + { "crnand", 0xfc0007fe, 0x4c0001c2, Op_crbD | Op_crbA | Op_crbB }, + { "crand", 0xfc0007fe, 0x4c000202, Op_crbD | Op_crbA | Op_crbB }, + { "creqv", 0xfc0007fe, 0x4c000242, Op_crbD | Op_crbA | Op_crbB }, + { "crorc", 0xfc0007fe, 0x4c000342, Op_crbD | Op_crbA | Op_crbB }, + { "cror", 0xfc0007fe, 0x4c000382, Op_crbD | Op_crbA | Op_crbB }, + { "bcctr", 0xfc0007fe, 0x4c000420, Op_BO | Op_BI | Op_LK }, + { "", 0x0, 0x0, 0 } +}; + +/* 1e * 4 = 78 */ +const struct opcode opcodes_1e[] = { + { "rldicl", 0xfc00001c, 0x78000000, Op_S | Op_A | Op_sh | Op_mb | Op_Rc }, + { "rldicr", 0xfc00001c, 0x78000004, Op_S | Op_A | Op_sh | Op_me | Op_Rc }, + { "rldic", 0xfc00001c, 0x78000008, Op_S | Op_A | Op_sh | Op_mb | Op_Rc }, + { "rldimi", 0xfc00001c, 0x7800000c, Op_S | Op_A | Op_sh | Op_mb | Op_Rc }, + { "rldcl", 0xfc00003e, 0x78000010, Op_S | Op_A | Op_B | Op_mb | Op_Rc }, + { "rldcr", 0xfc00003e, 0x78000012, Op_S | Op_A | Op_B | Op_me | Op_Rc }, + { "", 0x0, 0x0, 0 } +}; + +/* 1f * 4 = 7c */ +const struct opcode opcodes_1f[] = { +/* 1f << 2 */ + { "cmp", 0xfc0007fe, 0x7c000000, Op_S | Op_A | Op_B | Op_me | Op_Rc }, + { "tw", 0xfc0007fe, 0x7c000008, Op_TO | Op_A | Op_B }, + { "subfc", 0xfc0003fe, 0x7c000010, Op_D | Op_A | Op_B | Op_OE | Op_Rc }, + { "mulhdu", 0xfc0007fe, 0x7c000012, Op_D | Op_A | Op_B | Op_Rc }, + { "addc", 0xfc0003fe, 0x7c000014, Op_D | Op_A | Op_B | Op_OE | Op_Rc }, + { "mulhwu", 0xfc0007fe, 0x7c000016, Op_D | Op_A | Op_B | Op_Rc }, + + { "mfcr", 0xfc0007fe, 0x7c000026, Op_D }, + { "lwarx", 0xfc0007fe, 0x7c000028, Op_D | Op_A | Op_B }, + { "ldx", 0xfc0007fe, 0x7c00002a, Op_D | Op_A | Op_B }, + { "lwzx", 0xfc0007fe, 0x7c00002c, Op_D | Op_A | Op_B }, + { "slw", 0xfc0007fe, 0x7c000030, Op_D | Op_A | Op_B | Op_Rc }, + { "cntlzw", 0xfc0007fe, 0x7c000034, Op_D | Op_A | Op_Rc }, + { "sld", 0xfc0007fe, 0x7c000036, Op_D | Op_A | Op_B | Op_Rc }, + { "and", 0xfc0007fe, 0x7c000038, Op_D | Op_A | Op_B | Op_Rc }, + { "cmpl", 0xfc0007fe, 0x7c000040, Op_crfD | Op_L | Op_A | Op_B }, + { "subf", 0xfc0007fe, 0x7c000050, Op_D | Op_A | Op_B | Op_OE | Op_Rc }, + { "ldux", 0xfc0007fe, 0x7c00006a, Op_D | Op_A | Op_B }, + { "dcbst", 0xfc0007fe, 0x7c00006c, Op_A | Op_B }, + { "lwzux", 0xfc0007fe, 0x7c00006e, Op_D | Op_A | Op_B }, + { "cntlzd", 0xfc0007fe, 0x7c000074, Op_S | Op_A | Op_Rc }, + { "andc", 0xfc0007fe, 0x7c000078, Op_S | Op_A | Op_B | Op_Rc }, + { "td", 0xfc0007fe, 0x7c000088, Op_TO | Op_A | Op_B }, + { "mulhd", 0xfc0007fe, 0x7c000092, Op_D | Op_A | Op_B | Op_Rc }, + { "mulhw", 0xfc0007fe, 0x7c000093, Op_D | Op_A | Op_B | Op_Rc }, + { "mfmsr", 0xfc0007fe, 0x7c0000a6, Op_D }, + { "ldarx", 0xfc0007fe, 0x7c0000a8, Op_D | Op_A | Op_B }, + { "dcbf", 0xfc0007fe, 0x7c0000ac, Op_A | Op_B }, + { "lbzx", 0xfc0007fe, 0x7c0000ae, Op_D | Op_A | Op_B }, + { "neg", 0xfc0007fe, 0x7c0000d0, Op_D | Op_A | Op_OE | Op_Rc }, + { "lbzux", 0xfc0007fe, 0x7c0000ee, Op_D | Op_A | Op_B }, + { "nor", 0xfc0007fe, 0x7c0000f8, Op_S | Op_A | Op_B | Op_Rc }, + { "subfe", 0xfc0007fe, 0x7c000110, Op_D | Op_A | Op_B | Op_OE | Op_Rc }, + { "adde", 0xfc0007fe, 0x7c000114, Op_D | Op_A | Op_B | Op_OE | Op_Rc }, + { "mtcrf", 0xfc0007fe, 0x7c000120, Op_S | Op_CRM }, + { "mtmsr", 0xfc0007fe, 0x7c000124, Op_S }, + { "stdx", 0xfc0007fe, 0x7c00012a, Op_S | Op_A | Op_B }, + { "stwcx.", 0xfc0007ff, 0x7c00012d, Op_S | Op_A | Op_B }, + { "stwx", 0xfc0007fe, 0x7c00012e, Op_S | Op_A | Op_B }, + { "stdux", 0xfc0007fe, 0x7c00016a, Op_S | Op_A | Op_B }, + { "stwux", 0xfc0007fe, 0x7c00016e, Op_S | Op_A | Op_B }, + { "subfze", 0xfc0007fe, 0x7c000190, Op_D | Op_A | Op_OE | Op_Rc }, + { "addze", 0xfc0007fe, 0x7c000194, Op_D | Op_A | Op_OE | Op_Rc }, + { "mtsr", 0xfc0007fe, 0x7c0001a4, Op_S | Op_SR }, + { "stdcx.", 0xfc0007ff, 0x7c0001ad, Op_S | Op_A | Op_B }, + { "stbx", 0xfc0007fe, 0x7c0001ae, Op_S | Op_A | Op_B }, + { "subfme", 0xfc0007fe, 0x7c0001d0, Op_D | Op_A | Op_OE | Op_Rc }, + { "mulld", 0xfc0007fe, 0x7c0001d2, Op_D | Op_A | Op_B | Op_OE | Op_Rc }, + { "addme", 0xfc0007fe, 0x7c0001d4, Op_D | Op_A | Op_OE | Op_Rc }, + { "mullw", 0xfc0007fe, 0x7c0001d6, Op_D | Op_A | Op_B | Op_OE | Op_Rc }, + { "mtsrin", 0xfc0007fe, 0x7c0001e4, Op_S | Op_B }, + { "dcbtst", 0xfc0007fe, 0x7c0001ec, Op_A | Op_B }, + { "stbux", 0xfc0007fe, 0x7c0001ee, Op_S | Op_A | Op_B }, + { "add", 0xfc0007fe, 0x7c000214, Op_D | Op_A | Op_B | Op_OE | Op_Rc }, + { "dcbt", 0xfc0007fe, 0x7c00022c, Op_A | Op_B }, + { "lhzx", 0xfc0007ff, 0x7c00022f, Op_D | Op_A | Op_B }, + { "eqv", 0xfc0007fe, 0x7c000238, Op_S | Op_A | Op_B | Op_Rc }, + { "tlbie", 0xfc0007fe, 0x7c000264, Op_B }, + { "eciwx", 0xfc0007fe, 0x7c00026c, Op_D | Op_A | Op_B }, + { "lhzux", 0xfc0007fe, 0x7c00026e, Op_D | Op_A | Op_B }, + { "xor", 0xfc0007fe, 0x7c000278, Op_S | Op_A | Op_B | Op_Rc }, + { "mfspr", 0xfc0007fe, 0x7c0002a6, Op_D | Op_spr }, + { "lhax", 0xfc0007fe, 0x7c0002aa, Op_D | Op_A | Op_B }, + { "lhax", 0xfc0007fe, 0x7c0002ae, Op_D | Op_A | Op_B }, + { "tlbia", 0xfc0007fe, 0x7c0002e4, 0 }, + { "mftb", 0xfc0007fe, 0x7c0002e6, Op_D | Op_tbr }, + { "lwaux", 0xfc0007fe, 0x7c0002e6, Op_D | Op_A | Op_B }, + { "lhaux", 0xfc0007fe, 0x7c0002ee, Op_D | Op_A | Op_B }, + { "sthx", 0xfc0007fe, 0x7c00032e, Op_S | Op_A | Op_B }, + { "orc", 0xfc0007fe, 0x7c000338, Op_S | Op_A | Op_B | Op_Rc }, + { "econwx", 0xfc0007fe, 0x7c00036c, Op_S | Op_A | Op_B | Op_Rc }, + { "slbie", 0xfc0007fc, 0x7c000364, Op_B }, + { "sthux", 0xfc0007fe, 0x7c00036e, Op_S | Op_A | Op_B }, + { "or", 0xfc0007fe, 0x7c000378, Op_S | Op_A | Op_B | Op_Rc }, + { "divdu", 0xfc0007fe, 0x7c000392, Op_D | Op_A | Op_B | Op_OE | Op_Rc }, + { "divwu", 0xfc0007fe, 0x7c000396, Op_D | Op_A | Op_B | Op_OE | Op_Rc }, + { "mtspr", 0xfc0007fe, 0x7c0003a6, Op_S | Op_spr }, + { "dcbi", 0xfc0007fe, 0x7c0003ac, Op_A | Op_B }, + { "nand", 0xfc0007fe, 0x7c0003b8, Op_S | Op_A | Op_B | Op_Rc }, + { "divd", 0xfc0007fe, 0x7c0003d2, Op_S | Op_A | Op_B | Op_OE | Op_Rc }, + { "divw", 0xfc0007fe, 0x7c0003d6, Op_S | Op_A | Op_B | Op_OE | Op_Rc }, + { "slbia", 0xfc0007fe, 0x7c0003d4, Op_S | Op_A | Op_B | Op_OE | Op_Rc }, + { "slbia", 0xfc0007fe, 0x7c0003e4, Op_S | Op_A | Op_B | Op_OE | Op_Rc }, + { "mcrxr", 0xfc0007fe, 0x7c000400, Op_crfD }, + { "lswx", 0xfc0007fe, 0x7c00042a, Op_D | Op_A | Op_B }, + { "lwbrx", 0xfc0007fe, 0x7c00042c, Op_D | Op_A | Op_B }, + { "lfsx", 0xfc0007fe, 0x7c00042e, Op_D | Op_A | Op_B }, + { "srw", 0xfc0007fe, 0x7c000430, Op_S | Op_A | Op_B | Op_Rc }, + { "srd", 0xfc0007fe, 0x7c000436, Op_S | Op_A | Op_B | Op_Rc }, + { "tlbsync", 0xfc0007fe, 0x7c00046c, 0 }, + { "lfsux", 0xfc0007fe, 0x7c00046e, Op_D | Op_A | Op_B }, + { "mfsr", 0xfc0007fe, 0x7c0004a6, Op_D | Op_SR }, + { "iswi", 0xfc0007fe, 0x7c0004a6, Op_D | Op_A | Op_NB }, + { "sync", 0xfc0007fe, 0x7c0004ac, 0 }, + { "lfdx", 0xfc0007fe, 0x7c0004ac, Op_D | Op_A | Op_B }, + { "lfdux", 0xfc0007fe, 0x7c0004ec, Op_D | Op_A | Op_B }, + { "mfsrin", 0xfc0007fe, 0x7c000526, Op_D | Op_B }, + { "stswx", 0xfc0007fe, 0x7c00052a, Op_S | Op_A | Op_B }, + { "stwbrx", 0xfc0007fe, 0x7c00052c, Op_S | Op_A | Op_B }, + { "stfsx", 0xfc0007fe, 0x7c00052e, Op_S | Op_A | Op_B }, + { "stfsux", 0xfc0007fe, 0x7c00056e, Op_S | Op_A | Op_B }, + { "stswi", 0xfc0007fe, 0x7c0005aa, Op_S | Op_A | Op_NB }, + { "stfdx", 0xfc0007fe, 0x7c0005ae, Op_S | Op_A | Op_B }, + { "stfdx", 0xfc0007fe, 0x7c0005ae, Op_S | Op_A | Op_B }, + { "stfdux", 0xfc0007fe, 0x7c0005ee, Op_S | Op_A | Op_B }, + { "lhbrx", 0xfc0007fe, 0x7c00062c, Op_D | Op_A | Op_B }, + { "sraw", 0xfc0007fe, 0x7c000630, Op_S | Op_A | Op_B }, + { "srad", 0xfc0007fe, 0x7c000634, Op_S | Op_A | Op_B | Op_Rc}, + { "srawi", 0xfc0007fe, 0x7c000670, Op_S | Op_A | Op_B | Op_Rc}, +/* ? */ { "sradix", 0xfc0007fc, 0x7c000674, Op_S | Op_A | Op_sh }, + { "eieio", 0xfc0007fe, 0x7c0006ac, 0 }, + { "sthbrx", 0xfc0007fe, 0x7c00072c, Op_S | Op_A | Op_B }, + { "extsh", 0xfc0007fe, 0x7c000734, Op_S | Op_A | Op_B | Op_Rc }, + { "extsb", 0xfc0007fe, 0x7c000774, Op_S | Op_A | Op_Rc }, + { "icbi", 0xfc0007fe, 0x7c0007ac, Op_A | Op_B }, + + { "stfiwx", 0xfc0007fe, 0x7c0007ae, Op_S | Op_A | Op_B }, + { "extsw", 0xfc0007fe, 0x7c0007b4, Op_S | Op_A | Op_Rc }, + { "dcbz", 0xfc0007fe, 0x7c0007ec, Op_A | Op_B }, + { "", 0x0, 0x0, 0 } +}; + +/* 3a * 4 = e8 */ +const struct opcode opcodes_3a[] = { + { "ld", 0xfc000003, 0xe8000000, Op_D | Op_A | Op_ds }, + { "ldu", 0xfc000003, 0xe8000001, Op_D | Op_A | Op_ds }, + { "lwa", 0xfc000003, 0xe8000002, Op_D | Op_A | Op_ds }, + { "", 0x0, 0x0, 0 } +}; +/* 3b * 4 = ec */ +const struct opcode opcodes_3b[] = { + { "fdisvs", 0xfc00003e, 0xec000024, Op_D | Op_A | Op_B | Op_Rc }, + { "fsubs", 0xfc00003e, 0xec000028, Op_D | Op_A | Op_B | Op_Rc }, + + { "fadds", 0xfc00003e, 0xec00002a, Op_D | Op_A | Op_B | Op_Rc }, + { "fsqrts", 0xfc00003e, 0xec00002c, Op_D | Op_B | Op_Rc }, + { "fres", 0xfc00003e, 0xec000030, Op_D | Op_B | Op_Rc }, + { "fmuls", 0xfc00003e, 0xec000032, Op_D | Op_A | Op_C | Op_Rc }, + { "fmsubs", 0xfc00003e, 0xec000038, Op_D | Op_A | Op_B | Op_C | Op_Rc }, + { "fmadds", 0xfc00003e, 0xec00003a, Op_D | Op_A | Op_B | Op_C | Op_Rc }, + { "fnmsubs", 0xfc00003e, 0xec00003c, Op_D | Op_A | Op_B | Op_C | Op_Rc }, + { "fnmadds", 0xfc00003e, 0xec00003e, Op_D | Op_A | Op_B | Op_C | Op_Rc }, + { "", 0x0, 0x0, 0 } +}; +/* 3e * 4 = f8 */ +const struct opcode opcodes_3e[] = { + { "std", 0xfc000003, 0xf8000000, Op_S | Op_A | Op_ds }, + { "stdu", 0xfc000003, 0xf8000001, Op_S | Op_A | Op_ds }, + { "", 0x0, 0x0, 0 } +}; + +/* 3f * 4 = fc */ +const struct opcode opcodes_3f[] = { + { "fcmpu", 0xfc0007fe, 0xfc000000, Op_crfD | Op_A | Op_B }, + { "frsp", 0xfc0007fe, 0xfc000018, Op_D | Op_B | Op_Rc }, +/* ? */ { "fctiw", 0xfc0007fe, 0xfc00001c, Op_D | Op_B | Op_Rc }, + { "fctiwz", 0xfc0007fe, 0xfc00001e, Op_D | Op_B | Op_Rc }, + + { "fdiv", 0xfc00003e, 0xfc000024, Op_D | Op_A | Op_B | Op_Rc }, + { "fsub", 0xfc00003e, 0xfc000028, Op_D | Op_A | Op_B | Op_Rc }, + { "fadd", 0xfc00003e, 0xfc00002a, Op_D | Op_A | Op_B | Op_Rc }, + { "fsqrt", 0xfc00003e, 0xfc00002c, Op_D | Op_B | Op_Rc }, + { "fsel", 0xfc00003e, 0xfc00002e, Op_D | Op_A | Op_B | Op_C | Op_Rc }, + { "fmul", 0xfc00003e, 0xfc000032, Op_D | Op_A | Op_C | Op_Rc }, + { "frsqrte", 0xfc00003e, 0xfc000034, Op_D | Op_B | Op_Rc }, + { "fmsub", 0xfc00003e, 0xfc000038, Op_D | Op_A | Op_B | Op_C | Op_Rc }, + { "fmadd", 0xfc00003e, 0xfc00003a, Op_D | Op_A | Op_B | Op_C | Op_Rc }, + { "fnmsub", 0xfc00003e, 0xfc00003c, Op_D | Op_A | Op_B | Op_C | Op_Rc }, + { "fnmadd", 0xfc00003e, 0xfc00003e, Op_D | Op_A | Op_B | Op_C | Op_Rc }, + + { "fcmpo", 0xfc0007fe, 0xfc000040, Op_crfD | Op_A | Op_B }, + { "mtfsb1", 0xfc0007fe, 0xfc00004c, Op_crfD | Op_Rc }, + { "fneg", 0xfc0007fe, 0xfc000050, Op_D | Op_B | Op_Rc }, + { "mcrfs", 0xfc0007fe, 0xfc000080, Op_D | Op_B | Op_Rc }, + { "mtfsb0", 0xfc0007fe, 0xfc00008c, Op_crfD | Op_Rc }, + { "fmr", 0xfc0007fe, 0xfc000090, Op_D | Op_B | Op_Rc }, + { "mtfsfi", 0xfc0007fe, 0xfc00010c, Op_crfD | Op_IMM | Op_Rc }, + + { "fnabs", 0xfc0007fe, 0xfc000110, Op_D | Op_B | Op_Rc }, + { "fabs", 0xfc0007fe, 0xfc000210, Op_D | Op_B | Op_Rc }, + { "mffs", 0xfc0007fe, 0xfc00048e, Op_D | Op_B | Op_Rc }, + { "mtfsf", 0xfc0007fe, 0xfc00058e, Op_FM | Op_B | Op_Rc }, + { "fctid", 0xfc0007fe, 0xfc00065c, Op_D | Op_B | Op_Rc }, + { "fctidz", 0xfc0007fe, 0xfc00065e, Op_D | Op_B | Op_Rc }, + { "fcfid", 0xfc0007fe, 0xfc00069c, Op_D | Op_B | Op_Rc }, + { "", 0x0, 0x0, 0 } +}; + +/* +typedef void (op_class_func) (instr_t); +*/ +void +op_ill(u_int32_t addr, instr_t instr) +{ + db_printf("illegal instruction %x\n", instr); +} + +u_int32_t +extract_field(u_int32_t value, u_int32_t base, u_int32_t width) +{ + u_int32_t mask = (1 << width) - 1; + return ((value >> base) & mask); +} + +const struct opcode * search_op(const struct opcode *); + +void +disasm_fields(u_int32_t addr, const struct opcode *popcode, instr_t instr, + char *disasm_str) +{ + char * pstr; + enum function_mask func; + + pstr = disasm_str; + + func = popcode->func; + if (func & Op_OE) { + u_int OE; + /* also for Op_S (they are the same) */ + OE = extract_field(instr, 31 - 21, 1); + if (OE) { + pstr += sprintf (pstr, "o"); + } + func &= ~Op_D; + } + switch (func & Op_LKM) { + case Op_Rc: + if (instr & 0x1) { + pstr += sprintf (pstr,". "); + } + break; + case Op_AA: + if (instr & 0x2) { + pstr += sprintf (pstr,"a"); + } + case Op_LK: + if (instr & 0x1) { + pstr += sprintf (pstr,"l "); + } + break; + default: + func &= ~Op_LKM; + } + pstr += sprintf (pstr, " "); + if (func & Op_D) { + u_int D; + /* also for Op_S (they are the same) */ + D = extract_field(instr, 31 - 10, 5); + pstr += sprintf (pstr, "r%d, ", D); + func &= ~Op_D; + } + if (func & Op_crbD) { + u_int crbD; + crbD = extract_field(instr, 31 - 10, 5); + pstr += sprintf (pstr, "crb%d, ", crbD); + func &= ~Op_crbD; + } + if (func & Op_crfD) { + u_int crfD; + crfD = extract_field(instr, 31 - 8, 3); + pstr += sprintf (pstr, "crf%d, ", crfD); + func &= ~Op_crfD; + } + if (func & Op_L) { + u_int L; + L = extract_field(instr, 31 - 10, 1); + if (L) { + pstr += sprintf (pstr, "L, "); + } + func &= ~Op_L; + } + if (func & Op_FM) { + u_int FM; + FM = extract_field(instr, 31 - 10, 8); + pstr += sprintf (pstr, "%d, ", FM); + func &= ~Op_FM; + } + if (func & Op_TO) { + u_int TO; + TO = extract_field(instr, 31 - 10, 1); + pstr += sprintf (pstr, "%d, ", TO); + func &= ~Op_TO; + } + if (func & Op_crfS) { + u_int crfS; + crfS = extract_field(instr, 31 - 13, 3); + pstr += sprintf (pstr, "%d, ", crfS); + func &= ~Op_crfS; + } + if (func & Op_BO) { + u_int BO; + BO = extract_field(instr, 31 - 10, 5); + pstr += sprintf (pstr ,"%d, ", BO); + func &= ~Op_BO; + } + if (func & Op_A) { + u_int A; + A = extract_field(instr, 31 - 15, 5); + pstr += sprintf (pstr, "r%d, ", A); + func &= ~Op_A; + } + if (func & Op_B) { + u_int B; + B = extract_field(instr, 31 - 20, 5); + pstr += sprintf (pstr, "r%d, ", B); + func &= ~Op_B; + } + if (func & Op_C) { + u_int C; + C = extract_field(instr, 31 - 25, 5); + pstr += sprintf (pstr, "r%d, ", C); + func &= ~Op_C; + } + if (func & Op_BI) { + u_int BI; + BI = extract_field(instr, 31 - 10, 5); + pstr += sprintf (pstr, "%d, ", BI); + func &= ~Op_BI; + } + if (func & Op_crbA) { + u_int crbA; + crbA = extract_field(instr, 31 - 15, 5); + pstr += sprintf (pstr, "%d, ", crbA); + func &= ~Op_crbA; + } + if (func & Op_crbB) { + u_int crbB; + crbB = extract_field(instr, 31 - 20, 5); + pstr += sprintf (pstr, "%d, ", crbB); + func &= ~Op_crbB; + } + if (func & Op_CRM) { + u_int CRM; + CRM = extract_field(instr, 31 - 19, 8); + pstr += sprintf (pstr, "0x%x, ", CRM); + func &= ~Op_CRM; + } + if (func & Op_LI) { + u_int LI; + LI = extract_field(instr, 31 - 29, 24); + LI = LI << 4; + if (LI & 0x04000000) { + LI &= ~0x07ffffff; + } + pstr += sprintf (pstr, "0x%x", addr + LI); + func &= ~Op_LI; + } + switch (func & Op_SIMM) { + u_int IMM; + case Op_SIMM: /* same as Op_d */ + IMM = extract_field(instr, 31 - 31, 16); + if (IMM & 0x8000) { + pstr += sprintf (pstr, "-"); + } + /* no break */ + func &= ~Op_SIMM; + case Op_UIMM: + IMM = extract_field(instr, 31 - 31, 16); + pstr += sprintf (pstr, "0x%x, ", IMM); + func &= ~Op_UIMM; + break; + default: + } + if (func & Op_BD ) { + u_int BD; + BD = extract_field(instr, 31 - 29, 14); + pstr += sprintf (pstr, "0x%x, ", BD); + func &= ~Op_BD; + } + if (func & Op_ds ) { + u_int ds; + ds = extract_field(instr, 31 - 29, 14) << 2; + pstr += sprintf (pstr, "0x%x, ", ds); + func &= ~Op_ds; + } + if (func & Op_spr ) { + u_int spr; + u_int sprl; + u_int sprh; + char *reg; + sprl = extract_field(instr, 31 - 15, 5); + sprh = extract_field(instr, 31 - 20, 5); + spr = sprh << 5 | sprl; + + /* this table could be written better */ + switch (spr) { + case 1: + reg = "xer"; + break; + case 8: + reg = "lr"; + break; + case 9: + reg = "ctr"; + break; + case 18: + reg = "dsisr"; + break; + case 19: + reg = "dar"; + break; + case 22: + reg = "dec"; + break; + case 25: + reg = "sdr1"; + break; + case 26: + reg = "srr0"; + break; + case 27: + reg = "srr1"; + break; + case 272: + reg = "SPRG0"; + break; + case 273: + reg = "SPRG1"; + break; + case 274: + reg = "SPRG3"; + break; + case 275: + reg = "SPRG3"; + break; + case 280: + reg = "asr"; + break; + case 282: + reg = "aer"; + break; + case 287: + reg = "pvr"; + break; + case 528: + reg = "ibat0u"; + break; + case 529: + reg = "ibat0l"; + break; + case 530: + reg = "ibat1u"; + break; + case 531: + reg = "ibat1l"; + break; + case 532: + reg = "ibat2u"; + break; + case 533: + reg = "ibat2l"; + break; + case 534: + reg = "ibat3u"; + break; + case 535: + reg = "ibat3l"; + break; + case 536: + reg = "dbat0u"; + break; + case 537: + reg = "dbat0l"; + break; + case 538: + reg = "dbat1u"; + break; + case 539: + reg = "dbat1l"; + break; + case 540: + reg = "dbat2u"; + break; + case 541: + reg = "dbat2l"; + break; + case 542: + reg = "dbat3u"; + break; + case 543: + reg = "dbat3l"; + break; + case 1013: + reg = "dabr"; + break; + default: + reg = 0; + } + if (reg == 0) { + pstr += sprintf (pstr, ", [unknown spr (%d)]", spr); + } else { + pstr += sprintf (pstr, ", %s", reg); + } + func &= ~Op_spr; + } + + if (func & Op_me) { + u_int me, mel, meh; + mel = extract_field(instr, 31 - 25, 4); + meh = extract_field(instr, 31 - 26, 1); + me = meh << 4 | mel; + pstr += sprintf (pstr, ", 0x%x", me); + func &= ~Op_me; + } + if ((func & Op_MB ) && (func & Op_sh_mb_sh)) { + u_int MB; + u_int ME; + MB = extract_field(instr, 31 - 20, 5); + pstr += sprintf (pstr, ", %d", MB); + ME = extract_field(instr, 31 - 25, 5); + pstr += sprintf (pstr, ", %d", ME); + } + if ((func & Op_SH ) && (func & Op_sh_mb_sh)) { + u_int SH; + SH = extract_field(instr, 31 - 20, 5); + pstr += sprintf (pstr, ", %d", SH); + } + if ((func & Op_sh ) && ! (func & Op_sh_mb_sh)) { + u_int sh, shl, shh; + shl = extract_field(instr, 31 - 19, 4); + shh = extract_field(instr, 31 - 20, 1); + sh = shh << 4 | shl; + pstr += sprintf (pstr, ", %d", sh); + } + if ((func & Op_mb ) && ! (func & Op_sh_mb_sh)) { + u_int mb, mbl, mbh; + mbl = extract_field(instr, 31 - 25, 4); + mbh = extract_field(instr, 31 - 26, 1); + mb = mbh << 4 | mbl; + pstr += sprintf (pstr, ", %d", mb); + } + if ((func & Op_me ) && ! (func & Op_sh_mb_sh)) { + u_int me, mel, meh; + mel = extract_field(instr, 31 - 25, 4); + meh = extract_field(instr, 31 - 26, 1); + me = meh << 4 | mel; + pstr += sprintf (pstr, ", %d", me); + } + if (func & Op_tbr ) { + u_int tbr; + u_int tbrl; + u_int tbrh; + char *reg; + tbrl = extract_field(instr, 31 - 15, 5); + tbrh = extract_field(instr, 31 - 20, 5); + tbr = tbrh << 5 | tbrl; + switch (tbr) { + case 268: + reg = "tbl"; + break; + case 269: + reg = "tbu"; + break; + default: + reg = 0; + } + if (reg == 0) { + pstr += sprintf (pstr, ", [unknown tbr %d ]", tbr); + } else { + pstr += sprintf (pstr, ", %s", reg); + } + func &= ~Op_tbr; + } + if (func & Op_SR) { + u_int SR; + SR = extract_field(instr, 31 - 15, 3); + pstr += sprintf (pstr, ", sr%d", SR); + func &= ~Op_SR; + } + if (func & Op_NB) { + u_int NB; + NB = extract_field(instr, 31 - 20, 5); + if (NB == 0 ) { + NB=32; + } + pstr += sprintf (pstr, ", %d", NB); + func &= ~Op_SR; + } + if (func & Op_IMM) { + u_int IMM; + IMM = extract_field(instr, 31 - 19, 4); + pstr += sprintf (pstr, ", %d", IMM); + func &= ~Op_SR; + } +} + +void +op_base(u_int32_t addr, instr_t instr) +{ + dis_ppc (addr, opcodes,instr); +} + +void +op_cl_x13(u_int32_t addr, instr_t instr) +{ + dis_ppc (addr, opcodes_13,instr); +} + +void +op_cl_x1e(u_int32_t addr, instr_t instr) +{ + dis_ppc (addr, opcodes_1e,instr); +} + +void +op_cl_x1f(u_int32_t addr, instr_t instr) +{ + dis_ppc (addr, opcodes_1f,instr); +} + +void +op_cl_x3a(u_int32_t addr, instr_t instr) +{ + dis_ppc (addr, opcodes_3a,instr); +} + +void +op_cl_x3b(u_int32_t addr, instr_t instr) +{ + dis_ppc (addr, opcodes_3b,instr); +} + +void +op_cl_x3e(u_int32_t addr, instr_t instr) +{ + dis_ppc (addr, opcodes_3e,instr); +} + +void +op_cl_x3f(u_int32_t addr, instr_t instr) +{ + dis_ppc (addr, opcodes_3f,instr); +} + +void +dis_ppc(u_int32_t addr, const struct opcode *opcodeset, instr_t instr) +{ + const struct opcode *op; + int found = 0; + int i; + char disasm_str[30]; + + for ( i=0, op = &opcodeset[0]; + found == 0 && op->mask != 0; + i++, op= &opcodeset[i] ) + { + if ((instr & op->mask) == op->code) { + found = 1; + disasm_fields(addr, op, instr, disasm_str); + db_printf("%s%s",op->name, disasm_str); + return; + } + } + op_ill(addr, instr); +} + +db_addr_t +db_disasm(db_addr_t loc, boolean_t extended) +{ + int class; + instr_t opcode; + opcode = *(instr_t *)(loc); + class = opcode >> 26; + (opcodes_base[class])(loc, opcode); + + return loc + 4; +} + + diff --git a/sys/arch/mvmeppc/ddb/db_interface.c b/sys/arch/mvmeppc/ddb/db_interface.c new file mode 100644 index 00000000000..fa9bda71272 --- /dev/null +++ b/sys/arch/mvmeppc/ddb/db_interface.c @@ -0,0 +1,102 @@ +/* $OpenBSD: db_interface.c,v 1.1 2001/06/26 21:57:39 smurph Exp $ */ + +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/systm.h> + +#include <machine/db_machdep.h> +#include <machine/frame.h> + +#include <ddb/db_sym.h> +#include <ddb/db_command.h> +#include <ddb/db_extern.h> +#include <ddb/db_access.h> +#include <ddb/db_output.h> + +extern label_t *db_recover; + +void ddb_trap __P((void)); /* Call into trap_subr.S */ +int ddb_trap_glue __P((struct trapframe *)); /* Called from trap_subr.S */ + +void +Debugger() +{ +#ifdef DDB + ddb_trap(); +#else + mvmeprom_retunr(); +#endif +} + +int +ddb_trap_glue(frame) + struct trapframe *frame; +{ + if (!(frame->srr1 & PSL_PR) + && (frame->exc == EXC_TRC + || (frame->exc == EXC_PGM + && (frame->srr1 & 0x20000)) + || frame->exc == EXC_BPT)) { + + bcopy(frame->fixreg, DDB_REGS->r, 32 * sizeof(u_int32_t)); + DDB_REGS->iar = frame->srr0; + DDB_REGS->msr = frame->srr1; + + db_trap(T_BREAKPOINT, 0); + + bcopy(DDB_REGS->r, frame->fixreg, 32 * sizeof(u_int32_t)); + + return 1; + } + return 0; +} + +struct db_command db_machine_cmds[] = +{ + {(char *) 0,} +}; + +void +kdb_init() +{ +#ifdef DB_MACHINE_COMMANDS + db_machine_commands_install(db_machine_cmds); +#endif + ddb_init(); + + db_printf("ddb enabled\n"); +} + +int +kdb_trap(type, v) + int type; + void *v; +{ + struct trapframe *frame = v; + + switch (type) { + case T_BREAKPOINT: + case -1: + break; + default: + if (db_recover != 0) { + db_error("Faulted in DDB; continuing...\n"); + /*NOTREACHED*/ + } + } + + /* XXX Should switch to kdb's own stack here. */ + + bcopy(frame->fixreg, DDB_REGS->r, 32 * sizeof(u_int32_t)); + DDB_REGS->iar = frame->srr0; + DDB_REGS->msr = frame->srr1; + + db_trap(T_BREAKPOINT, 0); + + bcopy(DDB_REGS->r, frame->fixreg, 32 * sizeof(u_int32_t)); + frame->srr0 = DDB_REGS->iar; + frame->srr1 = DDB_REGS->msr; + + return 1; +} + diff --git a/sys/arch/mvmeppc/ddb/db_memrw.c b/sys/arch/mvmeppc/ddb/db_memrw.c new file mode 100644 index 00000000000..57286301d8f --- /dev/null +++ b/sys/arch/mvmeppc/ddb/db_memrw.c @@ -0,0 +1,103 @@ +/* $OpenBSD: db_memrw.c,v 1.1 2001/06/26 21:57:39 smurph Exp $ */ +/* $NetBSD: db_memrw.c,v 1.1 1996/02/22 23:23:35 gwr Exp $ */ + +/* + * 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. + */ + +/* + * Interface to the debugger for virtual memory read/write. + * This is a simple version for kernels with writable text. + * For an example of read-only kernel text, see the file: + * sys/arch/sun3/sun3/db_memrw.c + * + * ALERT! If you want to access device registers with a + * specific size, then the read/write functions have to + * make sure to do the correct sized pointer access. + */ + +#include <sys/param.h> +#include <sys/proc.h> + +#include <vm/vm.h> + +#include <machine/db_machdep.h> + +#include <ddb/db_access.h> + +/* + * Read bytes from kernel address space for debugger. + */ +void +db_read_bytes(addr, size, data) + vm_offset_t addr; + register size_t size; + register char *data; +{ + register char *src = (char*)addr; + + if (size == 4) { + *((int*)data) = *((int*)src); + return; + } + + if (size == 2) { + *((short*)data) = *((short*)src); + return; + } + + while (size > 0) { + --size; + *data++ = *src++; + } +} + +/* + * Write bytes to kernel address space for debugger. + */ +void +db_write_bytes(addr, size, data) + vm_offset_t addr; + register size_t size; + register char *data; +{ + register char *dst = (char *)addr; + + if (size == 4) { + *((int*)dst) = *((int*)data); + return; + } + + if (size == 2) { + *((short*)dst) = *((short*)data); + return; + } + + while (size > 0) { + --size; + *dst++ = *data++; + } +} + diff --git a/sys/arch/mvmeppc/ddb/db_trace.c b/sys/arch/mvmeppc/ddb/db_trace.c new file mode 100644 index 00000000000..24608fd36c9 --- /dev/null +++ b/sys/arch/mvmeppc/ddb/db_trace.c @@ -0,0 +1,170 @@ +/* $OpenBSD: db_trace.c,v 1.1 2001/06/26 21:57:39 smurph Exp $ */ + +/* + * 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/proc.h> + +#include <machine/db_machdep.h> +#include <machine/signal.h> + +#include <ddb/db_access.h> +#include <ddb/db_sym.h> +#include <ddb/db_variables.h> + +struct db_variable db_regs[] = { + { "r0", (long *)&ddb_regs.r[0], FCN_NULL }, + { "r1", (long *)&ddb_regs.r[1], FCN_NULL }, + { "r2", (long *)&ddb_regs.r[2], FCN_NULL }, + { "r3", (long *)&ddb_regs.r[3], FCN_NULL }, + { "r4", (long *)&ddb_regs.r[4], FCN_NULL }, + { "r5", (long *)&ddb_regs.r[5], FCN_NULL }, + { "r6", (long *)&ddb_regs.r[6], FCN_NULL }, + { "r7", (long *)&ddb_regs.r[7], FCN_NULL }, + { "r8", (long *)&ddb_regs.r[8], FCN_NULL }, + { "r9", (long *)&ddb_regs.r[9], FCN_NULL }, + { "r10", (long *)&ddb_regs.r[10], FCN_NULL }, + { "r11", (long *)&ddb_regs.r[11], FCN_NULL }, + { "r12", (long *)&ddb_regs.r[12], FCN_NULL }, + { "r13", (long *)&ddb_regs.r[13], FCN_NULL }, + { "r14", (long *)&ddb_regs.r[14], FCN_NULL }, + { "r15", (long *)&ddb_regs.r[15], FCN_NULL }, + { "r16", (long *)&ddb_regs.r[16], FCN_NULL }, + { "r17", (long *)&ddb_regs.r[17], FCN_NULL }, + { "r18", (long *)&ddb_regs.r[18], FCN_NULL }, + { "r19", (long *)&ddb_regs.r[19], FCN_NULL }, + { "r20", (long *)&ddb_regs.r[20], FCN_NULL }, + { "r21", (long *)&ddb_regs.r[21], FCN_NULL }, + { "r22", (long *)&ddb_regs.r[22], FCN_NULL }, + { "r23", (long *)&ddb_regs.r[23], FCN_NULL }, + { "r24", (long *)&ddb_regs.r[24], FCN_NULL }, + { "r25", (long *)&ddb_regs.r[25], FCN_NULL }, + { "r26", (long *)&ddb_regs.r[26], FCN_NULL }, + { "r27", (long *)&ddb_regs.r[27], FCN_NULL }, + { "r28", (long *)&ddb_regs.r[28], FCN_NULL }, + { "r29", (long *)&ddb_regs.r[29], FCN_NULL }, + { "r30", (long *)&ddb_regs.r[30], FCN_NULL }, + { "r31", (long *)&ddb_regs.r[31], FCN_NULL }, + { "iar", (long *)&ddb_regs.iar, FCN_NULL }, + { "msr", (long *)&ddb_regs.msr, FCN_NULL }, +}; + +struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]); + +extern label_t *db_recover; + +/* + * this is probably hackery. + */ +void +db_save_regs(struct trapframe *frame) +{ + bcopy(frame->fixreg, DDB_REGS->r, 32 * sizeof(u_int32_t)); + DDB_REGS->iar = frame->srr0; + DDB_REGS->msr = frame->srr1; +} + +db_expr_t +db_dumpframe (u_int32_t pframe) +{ + u_int32_t nextframe; + u_int32_t lr; + u_int32_t *access; + int error; + + access = (u_int32_t *)(pframe); + nextframe = *access; + + access = (u_int32_t *)(pframe+4); + lr = *access; + + db_printf("lr %x fp %x nfp %x\n", lr, pframe, nextframe); + + return nextframe; +} +/* + * Frame tracing. + */ +void +db_stack_trace_cmd(addr, have_addr, count, modif) + db_expr_t addr; + int have_addr; + db_expr_t count; + char *modif; +{ + db_addr_t frame, lr, caller; + db_expr_t diff; + db_sym_t sym; + char *symname; + boolean_t kernel_only = TRUE; + boolean_t trace_thread = FALSE; + boolean_t full = FALSE; + + { + register char *cp = modif; + register char c; + + while ((c = *cp++) != 0) { + if (c == 't') + trace_thread = TRUE; + if (c == 'u') + kernel_only = FALSE; + if (c == 'f') + full = TRUE; + } + } + + frame = (db_addr_t)ddb_regs.r[1]; + while ((frame = *(db_addr_t *)frame) && count--) { + db_addr_t *args = (db_addr_t *)(frame + 8); + + lr = *(db_addr_t *)(frame + 4) - 4; + if ((lr & 3) || (lr < 0x10000)) { + printf("saved LR(0x%x) is invalid.", lr); + break; + } + if ((caller = (db_addr_t)vtophys(lr)) == 0) + caller = lr; + + + diff = 0; + symname = NULL; + sym = db_search_symbol(caller, DB_STGY_ANY, &diff); + db_symbol_values(sym, &symname, 0); + if (symname == NULL) + printf("%p ", caller); + else + printf("%s+%x ", symname, diff); + if (full) + /* Print all the args stored in that stackframe. */ + printf(" (%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx) %lx ", + args[0], args[1], args[2], args[3], + args[4], args[5], args[6], args[7], frame); + printf("\n"); + } +} + diff --git a/sys/arch/mvmeppc/dev/bugio.c b/sys/arch/mvmeppc/dev/bugio.c new file mode 100644 index 00000000000..f526c8a3a9e --- /dev/null +++ b/sys/arch/mvmeppc/dev/bugio.c @@ -0,0 +1,482 @@ +/* + * bug routines -- assumes that the necessary sections of memory + * are preserved. + */ +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/types.h> +#include <machine/prom.h> + + +/* BUG - timing routine */ +void +mvmeprom_delay(msec) + int msec; /* This is r3 */ +{ + unsigned long omsr = ppc_get_msr(); + ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE)); + asm volatile ("mr 3, %0" :: "r"(msec)); + MVMEPROM_CALL(MVMEPROM_DELAY); + ppc_set_msr(omsr); +} + +/* returns 0: success, nonzero: error */ +int +mvmeprom_diskrd(arg) + struct mvmeprom_dskio *arg; +{ + int ret; + unsigned long omsr = ppc_get_msr(); + ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE)); + + asm volatile ("mr 3, %0" :: "r"(arg)); + MVMEPROM_CALL(MVMEPROM_NETRD); + asm volatile ("mr %0, 3" : "=r" (ret)); + ppc_set_msr(omsr); + return ((ret & 0x8)); +} + +/* returns 0: success, nonzero: error */ +int +mvmeprom_diskwr(arg) + struct mvmeprom_dskio *arg; +{ + int ret; + unsigned long omsr = ppc_get_msr(); + ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE)); + + asm volatile ("mr 3, %0" :: "r"(arg)); + MVMEPROM_CALL(MVMEPROM_DSKWR); + asm volatile ("mr %0, 3" : "=r" (ret)); + ppc_set_msr(omsr); + return ((ret & 0x8)); +} + +/* BUG - query board routines */ +struct mvmeprom_brdid * +mvmeprom_brdid() +{ + struct mvmeprom_brdid *id; + unsigned long omsr = ppc_get_msr(); + ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE)); + + MVMEPROM_CALL(MVMEPROM_BRD_ID); + asm volatile ("mr %0, 3": "=r" (id):); + ppc_set_msr(omsr); + return (id); +} + +/* returns 0 if no characters ready to read */ +int +mvmeprom_getchar() +{ + int ret; + unsigned long omsr = ppc_get_msr(); + ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE)); + + MVMEPROM_CALL(MVMEPROM_INCHR); + asm volatile ("mr %0, 3" : "=r" (ret)); + ppc_set_msr(omsr); + return ret; +} + +/* returns 0 if no characters ready to read */ +int +mvmeprom_instat() +{ + int ret; + unsigned long omsr = ppc_get_msr(); + ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE)); + + MVMEPROM_CALL(MVMEPROM_INSTAT); + asm volatile ("mr %0, 3" : "=r" (ret)); + ppc_set_msr(omsr); + return (!(ret & 0x4)); +} + +/* returns 0: success, nonzero: error */ +int +mvmeprom_netctrl(arg) + struct mvmeprom_netctrl *arg; +{ + unsigned long omsr = ppc_get_msr(); + ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE)); + asm volatile ("mr 3, %0":: "r" (arg)); + MVMEPROM_CALL(MVMEPROM_NETCTRL); + ppc_set_msr(omsr); + return (arg->status); +} + +int +mvmeprom_netctrl_init(clun, dlun) +u_char clun; +u_char dlun; +{ + struct mvmeprom_netctrl niocall; + niocall.clun = clun; + niocall.dlun = dlun; + niocall.status = 0; + niocall.cmd = 0; /* init */ + niocall.addr = 0; + niocall.len = 0; + niocall.flags = 0; + mvmeprom_netctrl(&niocall); + return(niocall.status); +} + +int +mvmeprom_netctrl_hwa(clun, dlun, addr, len) +u_char clun; +u_char dlun; +void *addr; +u_long *len; +{ + struct mvmeprom_netctrl niocall; + unsigned long omsr = ppc_get_msr(); + ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE)); + niocall.clun = clun; + niocall.dlun = dlun; + niocall.status = 0; + niocall.cmd = 1; /* get hw address */ + niocall.addr = addr; + niocall.len = *len; + niocall.flags = 0; + mvmeprom_netctrl(&niocall); + *len = niocall.len; + return(niocall.status); +} + +int +mvmeprom_netctrl_tx(clun, dlun, addr, len) +u_char clun; +u_char dlun; +void *addr; +u_long *len; +{ + struct mvmeprom_netctrl niocall; + niocall.clun = clun; + niocall.dlun = dlun; + niocall.status = 0; + niocall.cmd = 2; /* transmit */ + niocall.addr = addr; + niocall.len = *len; + niocall.flags = 0; + mvmeprom_netctrl(&niocall); + *len = niocall.len; + return(niocall.status); +} + +int +mvmeprom_netctrl_rx(clun, dlun, addr, len) +u_char clun; +u_char dlun; +void *addr; +u_long *len; +{ + struct mvmeprom_netctrl niocall; + niocall.clun = clun; + niocall.dlun = dlun; + niocall.status = 0; + niocall.cmd = 3; /* receive */ + niocall.addr = addr; + niocall.len = *len; + niocall.flags = 0; + mvmeprom_netctrl(&niocall); + *len = niocall.len; + return(niocall.status); +} + +int +mvmeprom_netctrl_flush_rx(clun, dlun) +u_char clun; +u_char dlun; +{ + struct mvmeprom_netctrl niocall; + niocall.clun = clun; + niocall.dlun = dlun; + niocall.status = 0; + niocall.cmd = 4; /* reset */ + niocall.addr = 0; + niocall.len = 0; + niocall.flags = 0; + mvmeprom_netctrl(&niocall); + return(niocall.status); +} + +int +mvmeprom_netctrl_reset(clun, dlun) +u_char clun; +u_char dlun; +{ + struct mvmeprom_netctrl niocall; + niocall.clun = clun; + niocall.dlun = dlun; + niocall.status = 0; + niocall.cmd = 5; /* reset */ + niocall.addr = 0; + niocall.len = 0; + niocall.flags = 0; + mvmeprom_netctrl(&niocall); + return(niocall.status); +} + +/* returns 0: success, nonzero: error */ +int +mvmeprom_netfopen(arg) + struct mvmeprom_netfopen *arg; +{ + unsigned long omsr = ppc_get_msr(); + ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE)); + asm volatile ("mr 3, %0": : "r" (arg)); + MVMEPROM_CALL(MVMEPROM_NETFOPEN); + ppc_set_msr(omsr); + return (arg->status); +} + +/* returns 0: success, nonzero: error */ +int +mvmeprom_netfread(arg) + struct mvmeprom_netfread *arg; +{ + unsigned long omsr = ppc_get_msr(); + ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE)); + asm volatile ("mr 3, %0": : "r" (arg)); + MVMEPROM_CALL(MVMEPROM_NETFREAD); + ppc_set_msr(omsr); + return (arg->status); +} + +/* returns 0: success, nonzero: error */ +int +mvmeprom_netrd(arg) + struct mvmeprom_netio *arg; +{ + unsigned long omsr = ppc_get_msr(); + ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE)); + asm volatile ("mr 3, %0": : "r" (arg)); + MVMEPROM_CALL(MVMEPROM_NETRD); + ppc_set_msr(omsr); + return (arg->status); +} + +/* returns 0: success, nonzero: error */ +int +mvmeprom_netwr(arg) + struct mvmeprom_netio *arg; +{ + unsigned long omsr = ppc_get_msr(); + ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE)); + asm volatile ("mr 3, %0": : "r" (arg)); + MVMEPROM_CALL(MVMEPROM_NETWR); + ppc_set_msr(omsr); + return (arg->status); +} + +void +mvmeprom_outln(start, end) + char *start, *end; +{ + unsigned long omsr = ppc_get_msr(); + ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE)); + asm volatile ("mr 3, %0": : "r" (start)); + asm volatile ("mr 4, %0": : "r" (end)); + MVMEPROM_CALL(MVMEPROM_OUTLN); + ppc_set_msr(omsr); +} + +void +mvmeprom_outstr(start, end) + char *start, *end; +{ + unsigned long omsr = ppc_get_msr(); + ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE)); + asm volatile ("mr 3, %0": : "r" (start)); + asm volatile ("mr 4, %0": : "r" (end)); + MVMEPROM_CALL(MVMEPROM_OUTSTR); + ppc_set_msr(omsr); +} + +void +mvmeprom_outchar(c) + int c; +{ + unsigned long omsr = ppc_get_msr(); + ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE)); + asm volatile ("mr 3, %0" :: "r" (c)); + MVMEPROM_CALL(MVMEPROM_OUTCHR); + ppc_set_msr(omsr); +} + +/* BUG - return to bug routine */ +void +mvmeprom_return() +{ + unsigned long omsr = ppc_get_msr(); + ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE)); + MVMEPROM_CALL(MVMEPROM_RETURN); + ppc_set_msr(omsr); + /*NOTREACHED*/ +} + + +void +mvmeprom_rtc_rd(ptime) + struct mvmeprom_time *ptime; +{ + unsigned long omsr = ppc_get_msr(); + ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE)); + asm volatile ("mr 3, %0": : "r" (ptime)); + MVMEPROM_CALL(MVMEPROM_RTC_RD); + ppc_set_msr(omsr); +} + +int +bugenvsz(void) +{ + register int ret; + char tmp[1]; + void *ptr = tmp; + unsigned long omsr = ppc_get_msr(); + ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE)); + + asm volatile ("mr 3, %0": : "r" (ptr)); + asm volatile ("li 5, 0x1"); + asm volatile ("li 5, 0x0"); /* get size */ + MVMEPROM_CALL(MVMEPROM_ENVIRON); + asm volatile ("mr %0, 3" : "=r" (ret)); + ppc_set_msr(omsr); + + return(ret); +} + +struct bugenviron bugenviron; +int bugenv_init = 0; +char bugenv_buf[1024]; + +#ifdef BUG_DEBUG +void bug_printenv(void); + +void +bug_printenv(void) +{ + printf("Startup Mode: %c\n", bugenviron.s.s_mode); + printf("Startup Menu: %c\n", bugenviron.s.s_menu); + printf("Remote Start: %c\n", bugenviron.s.s_remotestart); + printf("Probe Devs: %c\n", bugenviron.s.s_probe); + printf("Negate Sysfail: %c\n", bugenviron.s.s_negsysfail); + printf("Reset SCSI Bus: %c\n", bugenviron.s.s_resetscsi); + printf("Ignore CFNA Block: %c\n", bugenviron.s.s_nocfblk); + printf("SCSI sync method: %c\n", bugenviron.s.s_scsisync); + + printf("Auto Boot Enable: %c\n", bugenviron.b.b_enable); + printf("Auto Boot on power-up Only: %c\n", bugenviron.b.b_poweruponly); + printf("Auto Boot CLUN: %02x\n", bugenviron.b.b_clun); + printf("Auto Boot DLUN: %02x\n", bugenviron.b.b_dlun); + printf("Auto Boot Delay: %02x\n", bugenviron.b.b_delay); + printf("Auto Boot String: %s\n", bugenviron.b.b_string); + + printf("ROM Boot Enable: %c\n", bugenviron.r.r_enable); + printf("ROM Boot on power-up Only: %c\n", bugenviron.r.r_poweruponly); + printf("ROM Boot Scan VME bus: %c\n", bugenviron.r.r_bootvme); + printf("ROM Boot Delay: %02x\n", bugenviron.r.r_delay); + printf("ROM Boot Start: %08x\n", bugenviron.r.r_start); + printf("ROM Boot End: %08x\n", bugenviron.r.r_end); + + printf("Net Boot Enable: %c\n", bugenviron.n.n_enable); + printf("Net Boot on power-up Only: %c\n", bugenviron.n.n_poweruponly); + printf("Net Boot CLUN: %02x\n", bugenviron.n.n_clun); + printf("Net Boot DLUN: %02x\n", bugenviron.n.n_dlun); + printf("Net Boot Delay: %02x\n", bugenviron.n.n_delay); + printf("Net Boot CFG param pointer: %08x\n", bugenviron.n.n_param); + + printf("Memory Size Enable: %c\n", bugenviron.m.m_sizeenable); + printf("Memory Start: %08x\n", bugenviron.m.m_start); + printf("Memory End: %08x\n", bugenviron.m.m_end); + + Debugger(); +} +#else +#define bug_printenv() +#endif + +struct bugenviron * +mvmeprom_envrd(void) +{ + register int ret; + char *ptr, *dptr, *ptr_end; + int env_size = 0; + int pkt_typ, pkt_len; + unsigned long omsr = ppc_get_msr(); + ppc_set_msr(((omsr | PSL_IP) &~ PSL_EE)); + + env_size = bugenvsz(); + bzero(&bugenviron, sizeof(struct bugenviron)); + bzero(&bugenv_buf[0], 1024); + ptr = bugenv_buf; + + if (ptr != NULL) { + + asm volatile ("mr 3, %0": : "r" (ptr)); + asm volatile ("mr 4, %0": : "r" (env_size)); + asm volatile ("li 5, 0x2"); + MVMEPROM_CALL(MVMEPROM_ENVIRON); + asm volatile ("mr %0, 3" : "=r" (ret)); + + if (ret) { /* scram if we have an error */ + ppc_set_msr(omsr); + return NULL; + } + ptr_end = ptr + env_size; + while (ptr <= ptr_end) { + pkt_typ = *ptr++; + pkt_len = *ptr++; + dptr = ptr; + switch (pkt_typ) { + case BUG_ENV_END: + bugenv_init = 1; /* we have read the env */ + bug_printenv(); + ppc_set_msr(omsr); + return(&bugenviron); + break; + case BUG_STARTUP_PARAM: + /* All chars. We can use bcopy. */ + bcopy(dptr, &bugenviron.s.s_mode, pkt_len); + break; + case BUG_AUTOBOOT_INFO: + /* All chars. We can use bcopy. */ + bcopy(dptr, &bugenviron.b.b_enable, pkt_len); + break; + case BUG_ROMBOOT_INFO: + /* This data stream has integer info that + * may not be word aligned. We can't use + * bcopy for the whole struct in this + * instance. */ + bcopy(dptr, &bugenviron.r.r_enable, 4); + dptr+=4; + bcopy(dptr, &bugenviron.r.r_start, 4); + dptr+=4; + bcopy(dptr, &bugenviron.r.r_end, 4); + break; + case BUG_NETBOOT_INFO: + /* This data stream has integer info that + * may not be word aligned. We can't use + * bcopy for the whole struct in this + * instance. */ + bcopy(dptr, &bugenviron.n.n_enable, 5); + dptr+=5; + bcopy(dptr, &bugenviron.n.n_param, 4); + break; + case BUG_MEMORY_INFO: + bugenviron.m.m_sizeenable = *dptr++; + bcopy(dptr, &bugenviron.m.m_start, 4); + dptr+=4; + bcopy(dptr, &bugenviron.m.m_end, 4); + break; + } + ptr += pkt_len; + } + } + ppc_set_msr(omsr); + return NULL; +} + diff --git a/sys/arch/mvmeppc/dev/bugtty.c b/sys/arch/mvmeppc/dev/bugtty.c new file mode 100644 index 00000000000..fc38b8f9127 --- /dev/null +++ b/sys/arch/mvmeppc/dev/bugtty.c @@ -0,0 +1,492 @@ +/* $OpenBSD: bugtty.c,v 1.1 2001/06/26 21:57:40 smurph Exp $ */ +/* Copyright (c) 1998 Steve Murphree, Jr. + * Copyright (c) 1995 Dale Rahn. + * 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 Dale Rahn. + * 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. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/ioctl.h> +#include <sys/device.h> +#include <sys/tty.h> +#include <sys/proc.h> +#include <sys/conf.h> +#include <sys/uio.h> +#include <sys/queue.h> +#include <dev/cons.h> + +#include <machine/autoconf.h> +#include <machine/prom.h> +#include <machine/cpu.h> + +#include "bugtty.h" + +int bugttymatch __P((struct device *parent, void *self, void *aux)); +void bugttyattach __P((struct device *parent, struct device *self, void *aux)); + +struct cfattach bugtty_ca = { + sizeof(struct device), bugttymatch, bugttyattach +}; + +struct cfdriver bugtty_cd = { + NULL, "bugtty", DV_TTY, 0 +}; + +/* prototypes */ +int bugttycnprobe __P((struct consdev *cp)); +int bugttycninit __P((struct consdev *cp)); +int bugttycngetc __P((dev_t dev)); +void bugttycnputc __P((dev_t dev, char c)); + +int bugttyopen __P((dev_t dev, int flag, int mode, struct proc *p)); +int bugttyclose __P((dev_t dev, int flag, int mode, struct proc *p)); +int bugttyread __P((dev_t dev, struct uio *uio, int flag)); +int bugttywrite __P((dev_t dev, struct uio *uio, int flag)); +int bugttyioctl __P((dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)); +int bugttystop __P((struct tty *tp, int flag)); + +struct tty *bugttytty __P((dev_t dev)); +int bugttymctl __P((dev_t dev, int bits, int how)); +int bugttyparam __P((struct tty *tp, struct termios *tm)); + +#define DIALOUT(x) ((x) & 0x80) +#define SWFLAGS(dev) (bugttyswflags | (DIALOUT(dev) ? TIOCFLAG_SOFTCAR : 0)) + +#define BUGBUF 80 +char bugtty_ibuffer[BUGBUF+1]; +volatile char *pinchar = bugtty_ibuffer; +char bug_obuffer[BUGBUF+1]; + +struct tty *bugtty_tty[NBUGTTY]; + +/* + int ca_bustype; + void *ca_vaddr; + void *ca_paddr; + int ca_offset; + int ca_len; + int ca_ipl; + int ca_vec; + char *ca_name; + void *ca_master; points to bus-dependent data +*/ + +int +bugttymatch(parent, self, aux) + struct device *parent; + void *self; + void *aux; +{ + struct confargs *ca = aux; + return (1); +} + +void +bugttyattach(parent, self, aux) + struct device *parent; + struct device *self; + void *aux; +{ + printf(": bugtty\n"); +} + +#define BUGTTYUNIT(x) ((x) & (0x7f)) +void bugttyoutput __P((struct tty *tp)); + +int bugttydefaultrate = TTYDEF_SPEED; +int bugttyswflags; + +struct tty * +bugttytty(dev) + dev_t dev; +{ + int unit; + unit = BUGTTYUNIT(dev); + if (unit >= 4) { + return (NULL); + } + return bugtty_tty[unit]; +} + +int +bugttymctl(dev, bits, how) + dev_t dev; + int bits, how; +{ + int s; + + /*printf("mctl: dev %x, bits %x, how %x,",dev, bits, how);*/ + + /* settings are currently ignored */ + s = spltty(); + switch (how) { + case DMSET: + break; + case DMBIC: + break; + case DMBIS: + break; + case DMGET: + break; + } + (void)splx(s); + + bits = 0; + /* proper defaults? */ + bits |= TIOCM_DTR; + bits |= TIOCM_RTS; + bits |= TIOCM_CTS; + bits |= TIOCM_CD; + /* bits |= TIOCM_RI; */ + bits |= TIOCM_DSR; + + /* printf("retbits %x\n", bits); */ + return (bits); +} + +int +bugttyopen(dev, flag, mode, p) + dev_t dev; + int flag, mode; + struct proc *p; +{ + int s, unit = BUGTTYUNIT(dev); + struct tty *tp; + + s = spltty(); + if (bugtty_tty[unit]) { + tp = bugtty_tty[unit]; + } else { + tp = bugtty_tty[unit] = ttymalloc(); + } + tp->t_oproc = bugttyoutput; + tp->t_param = NULL; + tp->t_dev = dev; + + if ((tp->t_state & TS_ISOPEN) == 0) { + tp->t_state |= TS_WOPEN; + ttychars(tp); + if (tp->t_ispeed == 0) { + /* + * only when cleared do we reset to defaults. + */ + tp->t_iflag = TTYDEF_IFLAG; + tp->t_oflag = TTYDEF_OFLAG; + tp->t_cflag = TTYDEF_CFLAG; + tp->t_lflag = TTYDEF_LFLAG; + tp->t_ispeed = tp->t_ospeed = bugttydefaultrate; + } + /* bugtty does not have carrier */ + tp->t_cflag |= CLOCAL; + /* + * do these all the time + */ + if (bugttyswflags & TIOCFLAG_CLOCAL) + tp->t_cflag |= CLOCAL; + if (bugttyswflags & TIOCFLAG_CRTSCTS) + tp->t_cflag |= CRTSCTS; + if (bugttyswflags & TIOCFLAG_MDMBUF) + tp->t_cflag |= MDMBUF; + bugttyparam(tp, &tp->t_termios); + ttsetwater(tp); + + (void)bugttymctl(dev, TIOCM_DTR | TIOCM_RTS, DMSET); + /* + if ((SWFLAGS(dev) & TIOCFLAG_SOFTCAR) || + (bugttymctl(dev, 0, DMGET) & TIOCM_CD)) + tp->t_state |= TS_CARR_ON; + else + tp->t_state &= ~TS_CARR_ON; + */ + tp->t_state |= TS_CARR_ON; + } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) { + splx(s); + return (EBUSY); + } + + /* + * if NONBLOCK requested, ignore carrier + */ +/* + if (flag & O_NONBLOCK) + goto done; +*/ + + splx(s); + /* + * Reset the tty pointer, as there could have been a dialout + * use of the tty with a dialin open waiting. + */ + tp->t_dev = dev; + return ((*linesw[tp->t_line].l_open)(dev, tp)); +} + +int +bugttyparam(tp, tm) + struct tty *tp; + struct termios *tm; +{ + return (0); +} + +void +bugttyoutput(tp) + struct tty *tp; +{ + int cc, s, cnt ; + + /* only supports one unit */ + + if ((tp->t_state & TS_ISOPEN) == 0) + return; + + s = spltty(); + cc = tp->t_outq.c_cc; + while (cc > 0) { + cnt = min(BUGBUF, cc); + cnt = q_to_b(&tp->t_outq, bug_obuffer, cnt); + mvmeprom_outstr(bug_obuffer, &bug_obuffer[cnt]); + cc -= cnt; + } + splx(s); +} + +int +bugttyclose(dev, flag, mode, p) + dev_t dev; + int flag, mode; + struct proc *p; +{ + int unit = BUGTTYUNIT(dev); + struct tty *tp = bugtty_tty[unit]; + + (*linesw[tp->t_line].l_close)(tp, flag); + + ttyclose(tp); +#if 0 + bugtty_tty[unit] = NULL; +#endif + return (0); +} + +int +bugttyread(dev, uio, flag) + dev_t dev; + struct uio *uio; + int flag; +{ + struct tty *tp; + + if ((tp = bugtty_tty[BUGTTYUNIT(dev)]) == NULL) + return (ENXIO); + return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); +} + +/* only to be called at splclk() */ +void +bugtty_chkinput() +{ + struct tty *tp; + int rc = 0; + tp = bugtty_tty[0]; /* Kinda ugly hack */ + if (tp == NULL ) + return; + + if ((rc = mvmeprom_instat()) != 0) { + while (mvmeprom_instat() != 0) { + u_char c = mvmeprom_getchar() & 0xff; + (*linesw[tp->t_line].l_rint)(c, tp); + } + /* + wakeup(tp); + */ + } +} + +int +bugttywrite(dev, uio, flag) + dev_t dev; + struct uio *uio; + int flag; +{ +#if 0 + /* bypass tty output routines. */ + int i, cnt, s; + int oldoff; + + s = spltty(); + oldoff = uio->uio_offset; + do { + uiomove(bug_obuffer, BUGBUF, uio); + bugoutstr(bug_obuffer, &bug_obuffer[uio->uio_offset - oldoff]); + oldoff = uio->uio_offset; + } while (uio->uio_resid != 0); + splx(s); + + return (0); +#else + struct tty *tp; + if((tp = bugtty_tty[BUGTTYUNIT(dev)]) == NULL) + return (ENXIO); + return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); +#endif +} + +int +bugttyioctl(dev, cmd, data, flag, p) + dev_t dev; + int cmd; + caddr_t data; + int flag; + struct proc *p; +{ + int unit = BUGTTYUNIT(dev); + struct tty *tp = bugtty_tty[unit]; + int error; + + if (!tp) + return (ENXIO); + + 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); + + switch (cmd) { + case TIOCSBRK: + /* */ + break; + + case TIOCCBRK: + /* */ + break; + + case TIOCSDTR: + (void) bugttymctl(dev, TIOCM_DTR | TIOCM_RTS, DMBIS); + break; + + case TIOCCDTR: + (void) bugttymctl(dev, TIOCM_DTR | TIOCM_RTS, DMBIC); + break; + + case TIOCMSET: + (void) bugttymctl(dev, *(int *) data, DMSET); + break; + + case TIOCMBIS: + (void) bugttymctl(dev, *(int *) data, DMBIS); + break; + + case TIOCMBIC: + (void) bugttymctl(dev, *(int *) data, DMBIC); + break; + + case TIOCMGET: + *(int *)data = bugttymctl(dev, 0, DMGET); + break; + case TIOCGFLAGS: + *(int *)data = SWFLAGS(dev); + break; + case TIOCSFLAGS: + error = suser(p->p_ucred, &p->p_acflag); + if (error != 0) + return (EPERM); + + bugttyswflags = *(int *)data; + bugttyswflags &= /* only allow valid flags */ + (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | TIOCFLAG_CRTSCTS); + break; + default: + return (ENOTTY); + } + + return (0); +} + +int +bugttystop(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); +} + +/* + * bugtty is the last possible choice for a console device. + */ +int +bugttycnprobe(cp) + struct consdev *cp; +{ + int maj; + + /* locate the major number */ + for (maj = 0; maj < nchrdev; maj++) + if (cdevsw[maj].d_open == bugttyopen) + break; + + cp->cn_dev = makedev(maj, 0); + cp->cn_pri = CN_NORMAL; + return (1); +} + +int +bugttycninit(cp) + struct consdev *cp; +{ + /* Nothing to do */ + return 0; +} + +int +bugttycngetc(dev) + dev_t dev; +{ + return (mvmeprom_getchar()); +} + +void +bugttycnputc(dev, c) + dev_t dev; + char c; +{ + if (c == '\n') + mvmeprom_outchar('\r'); + mvmeprom_outchar(c); +} diff --git a/sys/arch/mvmeppc/dev/clock.c b/sys/arch/mvmeppc/dev/clock.c new file mode 100644 index 00000000000..a5e7af5d53b --- /dev/null +++ b/sys/arch/mvmeppc/dev/clock.c @@ -0,0 +1,397 @@ +/* $OpenBSD: clock.c,v 1.1 2001/06/26 21:57:40 smurph Exp $ */ +/* $NetBSD: clock.c,v 1.1 1996/09/30 16:34:40 ws Exp $ */ + +/* + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/kernel.h> + +#include <machine/pio.h> +#include <machine/intr.h> +#include <machine/powerpc.h> + +void resettodr(); +/* + * Initially we assume a processor with a bus frequency of 12.5 MHz. + */ +static u_long ticks_per_sec = 3125000; +static u_long ns_per_tick = 320; +static long ticks_per_intr = 0; +static volatile u_long lasttb; + +/* + * BCD to decimal and decimal to BCD. + */ +#define FROMBCD(x) (((x) >> 4) * 10 + ((x) & 0xf)) +#define TOBCD(x) (((x) / 10 * 16) + ((x) % 10)) + +#define SECDAY (24 * 60 * 60) +#define SECYR (SECDAY * 365) +#define LEAPYEAR(y) (((y) & 3) == 0) +#define YEAR0 1900 + +static u_long +chiptotime __P((int sec, int min, int hour, int day, int mon, int year)); + +struct chiptime { + int sec; + int min; + int hour; + int wday; + int day; + int mon; + int year; +}; + +static void timetochip __P((struct chiptime *c)); + +/* + * For now we let the machine run with boot time, not changing the clock + * at inittodr at all. + * + * We might continue to do this due to setting up the real wall clock with + * a user level utility in the future. + */ + +/* ARGSUSED */ +void +inittodr(base) +time_t base; +{ + int sec, min, hour, day, mon, year; + + int badbase = 0, waszero = base == 0; + + if (base < 5 * SECYR) { + /* + * If base is 0, assume filesystem time is just unknown + * instead of preposterous. Don't bark. + */ + if (base != 0) + printf("WARNING: preposterous time in file system\n"); + /* not going to use it anyway, if the chip is readable */ + base = 21*SECYR + 186*SECDAY + SECDAY/2; + badbase = 1; + } + + if (fw->clock_read != NULL ) { + (fw->clock_read)( &sec, &min, &hour, &day, &mon, &year); + time.tv_sec = chiptotime(sec, min, hour, day, mon, year); + } else if (fw->time_read != NULL) { + u_long cursec; + (fw->time_read)(&cursec); + time.tv_sec = cursec; + } else { + /* force failure */ + time.tv_sec = 0; + } + if (time.tv_sec == 0) { + printf("WARNING: unable to get date/time"); + /* + * Believe the time in the file system for lack of + * anything better, resetting the clock. + */ + time.tv_sec = base; + if (!badbase) + resettodr(); + } else { + int deltat; + + time.tv_sec += tz.tz_minuteswest * 60; + if (tz.tz_dsttime) + time.tv_sec -= 3600; + + deltat = time.tv_sec - base; + + if (deltat < 0) + deltat = -deltat; + if (waszero || deltat < 2 * SECDAY) + return; + printf("WARNING: clock %s %d days", + time.tv_sec < base ? "lost" : "gained", deltat / SECDAY); + } + printf(" -- CHECK AND RESET THE DATE!\n"); +} + +/* + * This code is defunct after 2068. + * Will Unix still be here then?? + */ +const short dayyr[12] = +{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; + +static u_long +chiptotime(sec, min, hour, day, mon, year) +int sec, min, hour, day, mon, year; +{ + int days, yr; + + sec = FROMBCD(sec); + min = FROMBCD(min); + hour = FROMBCD(hour); + day = FROMBCD(day); + mon = FROMBCD(mon); + year = FROMBCD(year) + YEAR0; + + /* simple sanity checks */ + if (year < 1970 || mon < 1 || mon > 12 || day < 1 || day > 31) + return (0); + days = 0; + for (yr = 1970; yr < year; yr++) + days += LEAPYEAR(yr) ? 366 : 365; + days += dayyr[mon - 1] + day - 1; + if (LEAPYEAR(yr) && mon > 2) + days++; + /* now have days since Jan 1, 1970; the rest is easy... */ + return (days * SECDAY + hour * 3600 + min * 60 + sec); +} + +void +timetochip(c) + register struct chiptime *c; +{ + register int t, t2, t3, now = time.tv_sec; + + /* January 1 1970 was a Thursday (4 in unix wdays) */ + /* compute the days since the epoch */ + t2 = now / SECDAY; + + t3 = (t2 + 4) % 7; /* day of week */ + c->wday = TOBCD(t3 + 1); + + /* compute the year */ + t = 69; + while (t2 >= 0) { /* whittle off years */ + t3 = t2; + t++; + t2 -= LEAPYEAR(t) ? 366 : 365; + } + c->year = t; + + /* t3 = month + day; separate */ + t = LEAPYEAR(t); + for (t2 = 1; t2 < 12; t2++) + if (t3 < (dayyr[t2] + ((t && (t2 > 1)) ? 1:0))) + break; + + /* t2 is month */ + c->mon = t2; + c->day = t3 - dayyr[t2 - 1] + 1; + if (t && t2 > 2) + c->day--; + + /* the rest is easy */ + t = now % SECDAY; + c->hour = t / 3600; + t %= 3600; + c->min = t / 60; + c->sec = t % 60; + + c->sec = TOBCD(c->sec); + c->min = TOBCD(c->min); + c->hour = TOBCD(c->hour); + c->day = TOBCD(c->day); + c->mon = TOBCD(c->mon); + c->year = TOBCD((c->year - YEAR0) % 100); +} + + +/* + * Similar to the above + */ +void +resettodr() +{ + struct timeval curtime = time; + if (fw->clock_write != NULL) { + struct chiptime c; + timetochip(&c); + (fw->clock_write)(c.sec, c.min, c.hour, c.day, c.mon, c.year); + } else if (fw->time_write != NULL) { + curtime.tv_sec -= tz.tz_minuteswest * 60; + if (tz.tz_dsttime) { + curtime.tv_sec += 3600; + } + (fw->time_write)(curtime.tv_sec); + } +} + +void +decr_intr(frame) +struct clockframe *frame; +{ + int msr; + u_long tb; + long tick; + int nticks; + int pri; + + /* + * Check whether we are initialized. + */ + if (!ticks_per_intr) + return; + + intrcnt[PPC_CLK_IRQ]++; + + /* + * Based on the actual time delay since the last decrementer reload, + * we arrange for earlier interrupt next time. + */ + asm ("mftb %0; mfdec %1" : "=r"(tb), "=r"(tick)); + for (nticks = 0; tick < 0; nticks++) + tick += ticks_per_intr; + asm volatile ("mtdec %0" :: "r"(tick)); + /* + * lasttb is used during microtime. Set it to the virtual + * start of this tick interval. + */ + lasttb = tb + tick - ticks_per_intr; + + pri = splclock(); + + if (pri & SPL_CLOCK) { + tickspending += nticks; + } else { + nticks += tickspending; + tickspending = 0; + /* + * Reenable interrupts + */ + asm volatile ("mfmsr %0; ori %0, %0, %1; mtmsr %0" + : "=r"(msr) : "K"(PSL_EE)); + + /* + * Do standard timer interrupt stuff. + * Do softclock stuff only on the last iteration. + */ + frame->pri = pri | SINT_CLOCK; + while (--nticks > 0) + hardclock(frame); + frame->pri = pri; + hardclock(frame); + } + splx(pri); +} + +void +cpu_initclocks() +{ + int msr, scratch; + asm volatile ("mfmsr %0; andi. %1, %0, %2; mtmsr %1" + : "=r"(msr), "=r"(scratch) : "K"((u_short)~PSL_EE)); + asm volatile ("mftb %0" : "=r"(lasttb)); + asm volatile ("mtdec %0" :: "r"(ticks_per_intr)); + asm volatile ("mtmsr %0" :: "r"(msr)); +} + +void +calc_delayconst() +{ + int qhandle, phandle; + char name[32]; + int msr, scratch; + + ticks_per_sec = ppc_tps(); + asm volatile ("mfmsr %0; andi. %1, %0, %2; mtmsr %1" + : "=r"(msr), "=r"(scratch) : "K"((u_short)~PSL_EE)); + ns_per_tick = 1000000000 / ticks_per_sec; + ticks_per_intr = ticks_per_sec / hz; + asm volatile ("mtmsr %0" :: "r"(msr)); +} + +static inline u_quad_t +mftb() +{ + u_long scratch; + u_quad_t tb; + + asm ("1: mftbu %0; mftb %0+1; mftbu %1; cmpw 0,%0,%1; bne 1b" + : "=r"(tb), "=r"(scratch)); + return tb; +} + +/* + * Fill in *tvp with current time with microsecond resolution. + */ +void +microtime(tvp) +struct timeval *tvp; +{ + u_long tb; + u_long ticks; + int msr, scratch; + + asm volatile ("mfmsr %0; andi. %1,%0,%2; mtmsr %1" + : "=r"(msr), "=r"(scratch) : "K"((u_short)~PSL_EE)); + asm ("mftb %0" : "=r"(tb)); + ticks = (tb - lasttb) * ns_per_tick; + *tvp = time; + asm volatile ("mtmsr %0" :: "r"(msr)); + ticks /= 1000; + tvp->tv_usec += ticks; + while (tvp->tv_usec >= 1000000) { + tvp->tv_usec -= 1000000; + tvp->tv_sec++; + } +} + +/* + * Wait for about n microseconds (us) (at least!). + */ +void +delay(n) +unsigned n; +{ + u_quad_t tb; + u_long tbh, tbl, scratch; + + tb = mftb(); + tb += (n * 1000 + ns_per_tick - 1) / ns_per_tick; + tbh = tb >> 32; + tbl = tb; + asm ("1: mftbu %0; cmplw %0,%1; blt 1b; bgt 2f;" + " mftb %0; cmplw %0,%2; blt 1b; 2:" + :: "r"(scratch), "r"(tbh), "r"(tbl)); + + tb = mftb(); +} + +/* + * Nothing to do. + */ +void +setstatclockrate(arg) +int arg; +{ + /* Do nothing */ +} diff --git a/sys/arch/mvmeppc/dev/cpu.c b/sys/arch/mvmeppc/dev/cpu.c new file mode 100644 index 00000000000..253c2ed0030 --- /dev/null +++ b/sys/arch/mvmeppc/dev/cpu.c @@ -0,0 +1,267 @@ +/* $OpenBSD: cpu.c,v 1.1 2001/06/26 21:57:41 smurph Exp $ */ + +/* + * Copyright (c) 1997 Per Fogelstrom + * Copyright (c) 1997 RTMX Inc + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed under OpenBSD for RTMX Inc + * North Carolina, USA, by Per Fogelstrom, Opsycon AB, Sweden. + * 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. + * + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/proc.h> +#include <sys/user.h> +#include <sys/device.h> + +#include <machine/autoconf.h> + +char cpu_model[80]; +char machine[] = "powerpc"; /* cpu architecture */ + +/* Definition of the driver for autoconfig. */ +static int cpumatch(struct device *, void *, void *); +static void cpuattach(struct device *, struct device *, void *); + +struct cfattach cpu_ca = { + sizeof(struct device), cpumatch, cpuattach +}; +struct cfdriver cpu_cd = { + NULL, "cpu", DV_DULL, NULL, 0 +}; + +static int +cpumatch(parent, cfdata, aux) + struct device *parent; + void *cfdata; + void *aux; +{ + struct confargs *ca = aux; + + /* make sure that we're looking for a CPU. */ + if (strcmp(ca->ca_name, cpu_cd.cd_name) != 0) + return (0); + + return (1); +} +void config_l2cr(); + +static void +cpuattach(parent, dev, aux) + struct device *parent; + struct device *dev; + void *aux; +{ + int cpu, pvr; + char name[32]; + int qhandle, phandle; + unsigned int clock_freq = 0; + + __asm__ ("mfpvr %0" : "=r"(pvr)); + cpu = pvr >> 16; + switch (cpu) { + case 1: + sprintf(cpu_model, "601"); + break; + case 3: + sprintf(cpu_model, "603"); + break; + case 4: + sprintf(cpu_model, "604"); + break; + case 5: + sprintf(cpu_model, "602"); + break; + case 6: + sprintf(cpu_model, "603e"); + break; + case 7: + sprintf(cpu_model, "603ev"); + break; + case 8: + sprintf(cpu_model, "750"); + break; + case 9: + sprintf(cpu_model, "604ev"); + break; + case 12: + sprintf(cpu_model, "7400(G4)"); + break; + case 20: + sprintf(cpu_model, "620"); + break; + default: + sprintf(cpu_model, "Version %x", cpu); + break; + } + sprintf(cpu_model + strlen(cpu_model), " (Revision %x)", pvr & 0xffff); + printf(": %s", cpu_model); + + /* This should only be executed on openfirmware systems... */ +#ifdef OFW + for (qhandle = OF_peer(0); qhandle; qhandle = phandle) { + if (OF_getprop(qhandle, "device_type", name, sizeof name) >= 0 + && !strcmp(name, "cpu") + && OF_getprop(qhandle, "clock-frequency", + &clock_freq , sizeof clock_freq ) >= 0) + { + break; + } + if (phandle = OF_child(qhandle)) + continue; + while (qhandle) { + if (phandle = OF_peer(qhandle)) + break; + qhandle = OF_parent(qhandle); + } + } + + if (clock_freq != 0) { + /* Openfirmware stores clock in HZ, not Mhz */ + clock_freq /= 1000000; + printf(": %d Mhz", clock_freq); + + } +#endif + /* if processor is G3 or G4, configure l2 cache */ + if ( (cpu == 8) || (cpu == 12) ) { + config_l2cr(); + } + printf("\n"); + + +} + +#define L2CR 1017 + +#define L2CR_L2E 0x80000000 /* 0: L2 enable */ +#define L2CR_L2PE 0x40000000 /* 1: L2 data parity enable */ +#define L2CR_L2SIZ 0x30000000 /* 2-3: L2 size */ +#define L2SIZ_RESERVED 0x00000000 +#define L2SIZ_256K 0x10000000 +#define L2SIZ_512K 0x20000000 +#define L2SIZ_1M 0x30000000 +#define L2CR_L2CLK 0x0e000000 /* 4-6: L2 clock ratio */ +#define L2CLK_DIS 0x00000000 /* disable L2 clock */ +#define L2CLK_10 0x02000000 /* core clock / 1 */ +#define L2CLK_15 0x04000000 /* / 1.5 */ +#define L2CLK_20 0x08000000 /* / 2 */ +#define L2CLK_25 0x0a000000 /* / 2.5 */ +#define L2CLK_30 0x0c000000 /* / 3 */ +#define L2CR_L2RAM 0x01800000 /* 7-8: L2 RAM type */ +#define L2RAM_FLOWTHRU_BURST 0x00000000 +#define L2RAM_PIPELINE_BURST 0x01000000 +#define L2RAM_PIPELINE_LATE 0x01800000 +#define L2CR_L2DO 0x00400000 /* 9: L2 data-only. + Setting this bit disables instruction + caching. */ +#define L2CR_L2I 0x00200000 /* 10: L2 global invalidate. */ +#define L2CR_L2CTL 0x00100000 /* 11: L2 RAM control (ZZ enable). + Enables automatic operation of the + L2ZZ (low-power mode) signal. */ +#define L2CR_L2WT 0x00080000 /* 12: L2 write-through. */ +#define L2CR_L2TS 0x00040000 /* 13: L2 test support. */ +#define L2CR_L2OH 0x00030000 /* 14-15: L2 output hold. */ +#define L2CR_L2SL 0x00008000 /* 16: L2 DLL slow. */ +#define L2CR_L2DF 0x00004000 /* 17: L2 differential clock. */ +#define L2CR_L2BYP 0x00002000 /* 18: L2 DLL bypass. */ +#define L2CR_L2IP 0x00000001 /* 31: L2 global invalidate in progress + (read only). */ +#ifdef L2CR_CONFIG +u_int l2cr_config = L2CR_CONFIG; +#else +u_int l2cr_config = 0; +#endif + +void +config_l2cr() +{ + u_int l2cr, x; + + __asm __volatile ("mfspr %0, 1017" : "=r"(l2cr)); + + /* + * Configure L2 cache if not enabled. + */ + if ((l2cr & L2CR_L2E) == 0 && l2cr_config != 0) { + l2cr = l2cr_config; + asm volatile ("mtspr 1017,%0" :: "r"(l2cr)); + + /* Wait for L2 clock to be stable (640 L2 clocks). */ + delay(100); + + /* Invalidate all L2 contents. */ + l2cr |= L2CR_L2I; + asm volatile ("mtspr 1017,%0" :: "r"(l2cr)); + do { + asm volatile ("mfspr %0, 1017" : "=r"(x)); + } while (x & L2CR_L2IP); + + /* Enable L2 cache. */ + l2cr &= ~L2CR_L2I; + l2cr |= L2CR_L2E; + asm volatile ("mtspr 1017,%0" :: "r"(l2cr)); + } + + if (l2cr & L2CR_L2E) { + switch (l2cr & L2CR_L2SIZ) { + case L2SIZ_256K: + printf(": 256KB"); + break; + case L2SIZ_512K: + printf(": 512KB"); + break; + case L2SIZ_1M: + printf(": 1MB"); + break; + default: + printf(": unknown size"); + } +#if 0 + switch (l2cr & L2CR_L2RAM) { + case L2RAM_FLOWTHRU_BURST: + printf(" Flow-through synchronous burst SRAM"); + break; + case L2RAM_PIPELINE_BURST: + printf(" Pipelined synchronous burst SRAM"); + break; + case L2RAM_PIPELINE_LATE: + printf(" Pipelined synchronous late-write SRAM"); + break; + default: + printf(" unknown type"); + } + + if (l2cr & L2CR_L2PE) + printf(" with parity"); +#endif + printf(" backside cache"); + } else + printf(": L2 cache not enabled"); + +} diff --git a/sys/arch/mvmeppc/dev/mainbus.c b/sys/arch/mvmeppc/dev/mainbus.c new file mode 100644 index 00000000000..968d1cd5a78 --- /dev/null +++ b/sys/arch/mvmeppc/dev/mainbus.c @@ -0,0 +1,159 @@ +/* $OpenBSD: mainbus.c,v 1.1 2001/06/26 21:57:41 smurph Exp $ */ + +/* + * Copyright (c) 1994, 1995 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. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> +#include <sys/reboot.h> + +#include <machine/autoconf.h> + +struct mainbus_softc { + struct device sc_dv; + struct bushook sc_bus; +}; + +/* Definition of the mainbus driver. */ +static int mbmatch __P((struct device *, void *, void *)); +static void mbattach __P((struct device *, struct device *, void *)); +static int mbprint __P((void *, const char *)); + +struct cfattach mainbus_ca = { + sizeof(struct device), mbmatch, mbattach +}; +struct cfdriver mainbus_cd = { + NULL, "mainbus", DV_DULL, NULL, 0 +}; + +void mb_intr_establish __P((struct confargs *, int (*)(void *), void *)); +void mb_intr_disestablish __P((struct confargs *)); +caddr_t mb_cvtaddr __P((struct confargs *)); +int mb_matchname __P((struct confargs *, char *)); + +static int attached = 0; + +static int +mbmatch(parent, cfdata, aux) + struct device *parent; + void *cfdata; + void *aux; +{ + struct cfdata *cf = cfdata; + + /* + * That one mainbus is always here. + */ + if (!attached) { + return(1); + } else { + return(0); + } +} + +static void +mbattach(parent, self, aux) + struct device *parent; + struct device *self; + void *aux; +{ + struct mainbus_softc *sc = (struct mainbus_softc *)self; + struct confargs nca; + extern int system_type; + + printf("\n"); + + attached = 1; + + sc->sc_bus.bh_dv = (struct device *)sc; + sc->sc_bus.bh_type = BUS_MAIN; + sc->sc_bus.bh_intr_establish = mb_intr_establish; + sc->sc_bus.bh_intr_disestablish = mb_intr_disestablish; + sc->sc_bus.bh_matchname = mb_matchname; + + /* + * Try to find and attach all of the CPUs in the machine. + * ( Right now only one CPU so code is simple ) + */ + + nca.ca_name = "cpu"; + nca.ca_bus = &sc->sc_bus; + config_found(self, &nca, mbprint); + + /* The following machines have an ISA bus */ + /* Do ISA first so the interrupt controller is set up! */ + nca.ca_name = "isabr"; + nca.ca_bus = &sc->sc_bus; + config_found(self, &nca, mbprint); + + nca.ca_name = "mpcpcibr"; + nca.ca_bus = &sc->sc_bus; + config_found(self, &nca, mbprint); +} + +static int +mbprint(aux, pnp) + void *aux; + const char *pnp; +{ + if (pnp) + return (QUIET); + return (UNCONF); +} + +void +mb_intr_establish(ca, handler, val) + struct confargs *ca; + int (*handler) __P((void *)); + void *val; +{ + panic("can never mb_intr_establish"); +} + +void +mb_intr_disestablish(ca) + struct confargs *ca; +{ + panic("can never mb_intr_disestablish"); +} + +caddr_t +mb_cvtaddr(ca) + struct confargs *ca; +{ + + return (NULL); +} + +int +mb_matchname(ca, name) + struct confargs *ca; + char *name; +{ + return (strcmp(name, ca->ca_name) == 0); +} diff --git a/sys/arch/mvmeppc/dev/mem.c b/sys/arch/mvmeppc/dev/mem.c new file mode 100644 index 00000000000..25e15ccdd6b --- /dev/null +++ b/sys/arch/mvmeppc/dev/mem.c @@ -0,0 +1,176 @@ +/* $OpenBSD: mem.c,v 1.1 2001/06/26 21:57:41 smurph Exp $ */ +/* $NetBSD: mem.c,v 1.1 1996/09/30 16:34:50 ws Exp $ */ + +/* + * Copyright (c) 1988 University of Utah. + * Copyright (c) 1982, 1986, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * the Systems Programming Group of the University of Utah Computer + * Science Department. + * + * 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 University of + * California, Berkeley and its contributors. + * 4. 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. + * + * @(#)mem.c 8.3 (Berkeley) 1/12/94 + */ + +/* + * Memory special file + */ + +#include <sys/param.h> +#include <sys/conf.h> +#include <sys/buf.h> +#include <sys/systm.h> +#include <sys/uio.h> +#include <sys/malloc.h> + +#include <vm/vm.h> + +/*ARGSUSED*/ +int +mmopen(dev, flag, mode) + dev_t dev; + int flag, mode; +{ + + switch (minor(dev)) { + case 0: + case 1: + case 2: + case 12: + return (0); + default: + return (ENXIO); + } +} + +/*ARGSUSED*/ +int +mmclose(dev, flag, mode) + dev_t dev; + int flag, mode; +{ + + return 0; +} + +/*ARGSUSED*/ +int +mmrw(dev, uio, flags) + dev_t dev; + struct uio *uio; + int flags; +{ + vm_offset_t o, v; + u_int c; + struct iovec *iov; + int error = 0; + static caddr_t zeropage; + + 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)) { + +/* minor device 0 is physical memory */ + case 0: + v = uio->uio_offset; + c = uio->uio_resid; + /* This doesn't allow device mapping! XXX */ + pmap_real_memory(&v, &c); + error = uiomove((caddr_t)v, c, uio); + continue; + +/* minor device 1 is kernel memory */ + case 1: + v = uio->uio_offset; + c = min(iov->iov_len, MAXPHYS); + error = uiomove((caddr_t)v, c, uio); + continue; + +/* minor device 2 is EOF/RATHOLE */ + case 2: + if (uio->uio_rw == UIO_WRITE) + uio->uio_resid = 0; + return 0; + +/* minor device 12 (/dev/zero) is source of nulls on read, rathole on write */ + case 12: + if (uio->uio_rw == UIO_WRITE) { + c = iov->iov_len; + break; + } + if (zeropage == NULL) { + zeropage = (caddr_t)malloc(PAGE_SIZE, M_TEMP, M_WAITOK); + bzero(zeropage, PAGE_SIZE); + } + c = min(iov->iov_len, PAGE_SIZE); + error = uiomove(zeropage, c, uio); + continue; + + default: + return ENXIO; + } + if (error) + break; + iov->iov_base += c; + iov->iov_len -= c; + uio->uio_offset += c; + uio->uio_resid -= c; + } + return error; +} + +int +mmmmap(dev, off, prot) + dev_t dev; + int off, prot; +{ + return (-1); +} + +/*ARGSUSED*/ +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/mvmeppc/dev/nvramreg.h b/sys/arch/mvmeppc/dev/nvramreg.h new file mode 100644 index 00000000000..96c2737f75b --- /dev/null +++ b/sys/arch/mvmeppc/dev/nvramreg.h @@ -0,0 +1,86 @@ +/* $OpenBSD: nvramreg.h,v 1.1 2001/06/26 21:57:41 smurph 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. 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, Berkeley and its contributors. + * 4. 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. + * + * @(#)clockreg.h 8.1 (Berkeley) 6/11/93 + */ + +/* + * mvme2x00 Mostek TOD clock/NVRAM + */ + +/* + * Mostek MK48T59 clock. + * + * This chip is 8k in size. + * The first TOD clock starts at offset 0x1FF8. The following structure + * describes last 2K of it's 8K address space. The first 6K of the NVRAM + * space is used for various things as follows: + * 0000-0fff User Area + * 1000-10ff Networking Area + * 1100-16f7 Operating System Area + * 16f8-1ef7 ROM Debugger Area + * 1ef8-1ff7 Configuration Area (Ethernet address etc) + * 1ff8-1fff TOD clock + */ + +#define NVRAM_S0 0x80000074 +#define NVRAM_S1 0x80000075 +#define NVRAM_DATA 0x80000077 + +#define RTC_SECONDS 0x1FF9 +#define RTC_MINUTES 0x1FFA +#define RTC_HOURS 0x1FFB +#define RTC_DAY_OF_WEEK 0x1FFC +#define RTC_DAY_OF_MONTH 0x1FFD +#define RTC_MONTH 0x1FFE +#define RTC_YEAR 0x1FFF + +#define RTC_CONTROLA 0x1FF8 +#define RTC_CA_WRITE 0x80 +#define RTC_CA_READ 0x40 +#define RTC_CA_CALIB_SIGN 0x20 +#define RTC_CA_CALIB_MASK 0x1f + +#define RTC_CONTROLB 0x1FF9 +#define RTC_CB_STOP 0x80 + diff --git a/sys/arch/mvmeppc/dev/openpic.c b/sys/arch/mvmeppc/dev/openpic.c new file mode 100644 index 00000000000..f4e2a391e2c --- /dev/null +++ b/sys/arch/mvmeppc/dev/openpic.c @@ -0,0 +1,1035 @@ +/* $OpenBSD: openpic.c,v 1.1 2001/06/26 21:57:41 smurph Exp $ */ + +/*- + * Copyright (c) 1995 Per Fogelstrom + * Copyright (c) 1993, 1994 Charles M. Hannum. + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz and Don Ahn. + * + * 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 University of + * California, Berkeley and its contributors. + * 4. 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. + * + * @(#)isa.c 7.2 (Berkeley) 5/12/91 + */ + +#if 0 +#define OP_DEBUG +#endif + +#include <sys/param.h> +#include <sys/device.h> +#include <sys/ioctl.h> +#include <sys/mbuf.h> +#include <sys/socket.h> +#include <sys/systm.h> +#ifdef UVM +#include <vm/vm.h> +#include <vm/vm_kern.h> +#include <uvm/uvm.h> +#endif + +#include <machine/autoconf.h> +#include <machine/intr.h> +#include <machine/psl.h> +#include <machine/pio.h> +#include <mvmeppc/dev/openpicreg.h> +#include <mvmeppc/dev/ravenvar.h> +#include <mvmeppc/dev/ravenreg.h> + +#define ICU_LEN 32 +#define LEGAL_IRQ(x) ((x >= 0) && (x < ICU_LEN)) +#define IO_ICU1 (RAVEN_P_ISA_IO_SPACE + 0x20) +#define IO_ICU2 (RAVEN_P_ISA_IO_SPACE + 0xA0) +#define IRQ_SLAVE 2 +#define ICU_OFFSET 16 +unsigned char icu1_val = 0xff; +unsigned char icu2_val = 0xff; + +#define SET_ICUS() (outb(IO_ICU1 + 1, imen), outb(IO_ICU2 + 1, imen >> 8)) + +static int intrtype[ICU_LEN], intrmask[ICU_LEN], intrlevel[ICU_LEN]; +static struct intrhand *intrhand[ICU_LEN] = { 0 }; +static int hwirq[ICU_LEN], virq[ICU_LEN]; +unsigned int imen /* = 0xffffffff */; /* XXX */ +static int virq_max = 0; + +struct evcnt evirq[ICU_LEN]; + +static int fakeintr __P((void *)); +static char *intr_typename(int type); +static void intr_calculatemasks(); +static __inline int cntlzw(int x); +static int mapirq(int irq); +static int read_irq(); +void openpic_enable_irq_mask(int irq_mask); + +static struct raven_reg *ravenp = (struct raven_reg *)NULL; + +#define HWIRQ_MAX 27 +#define HWIRQ_MASK 0x0fffffff + + +static __inline u_int openpic_read __P((int)); +static __inline void openpic_write __P((int, u_int)); +void openpic_enable_irq __P((int, int)); +void openpic_disable_irq __P((int)); +void openpic_init(); +void openpic_set_priority __P((int, int)); +void openpic_set_vec_pri __P((int, int)); +static __inline int openpic_read_irq __P((int)); +static __inline void openpic_eoi __P((int)); + +void i8259_init __P((void)); +int i8259_intr __P((void)); +void i8259_enable_irq __P((int)); +void i8259_disable_irq __P((int)); +void *i8259_intr_establish( void * lcv, int irq, int type, int level, + int (*ih_fun) __P((void *)), void *ih_arg, char *name); + +struct openpic_softc { + struct device sc_dev; +}; + +int openpic_match __P((struct device *parent, void *cf, void *aux)); +void openpic_attach __P((struct device *, struct device *, void *)); +void openpic_do_pending_int(); +void ext_intr_openpic(); + +struct cfattach openpic_ca = { + sizeof(struct openpic_softc), + openpic_match, + openpic_attach +}; + +struct cfdriver openpic_cd = { + NULL, "openpic", DV_DULL +}; + +struct pci_route { + int pci; + int openpic; +} pci_routes[] = { + 10, 2, + 11, 4, + 14, 3, + 15, 5, + 0, 0, +}; + +static int isaintrs = 0; + +int +openpic_match(parent, cf, aux) + struct device *parent; + void *cf; + void *aux; +{ + struct confargs *ca = aux; + + /* We must be a child of the raven device */ + if (strcmp(parent->dv_cfdata->cf_driver->cd_name, "raven") != 0) + return (0); + /* don't attach more than once. */ + if (ravenp != (struct raven_reg *)NULL){ +#ifdef DIAGNOSTIC + printf("openpic: trying to attach more than once!"); +#endif + return(0); + } + /* If there is a raven, then there is a mpic! */ + return 1; +} + +u_int8_t *interrupt_reg; +typedef void (void_f) (void); +extern void_f *pending_int_f; +static int abort_switch (void *arg); +static int i8259_dummy (void *arg); + +typedef int mac_intr_handle_t; + +typedef void *(intr_establish_t) __P((void *, mac_intr_handle_t, + int, int, int (*func)(void *), void *, char *)); +typedef void (intr_disestablish_t) __P((void *, void *)); + +vaddr_t openpic_base; +void * openpic_intr_establish( void * lcv, int irq, int type, int level, + int (*ih_fun) __P((void *)), void *ih_arg, char *name); +void openpic_intr_disestablish( void *lcp, void *arg); +void openpic_collect_preconf_intr(); + +void +openpic_attach(parent, self, aux) + struct device *parent, *self; + void *aux; +{ + struct confargs *ca = aux; + struct openpic_softc *sc = (void *)self; + extern intr_establish_t *intr_establish_func; + extern intr_disestablish_t *intr_disestablish_func; +#if 0 + extern intr_establish_t *mac_intr_establish_func; + extern intr_disestablish_t *mac_intr_disestablish_func; +#endif + openpic_base = (vaddr_t)MPCIC_REG/* mapiodev (MPCIC_REG, 0x22000)*/; + + printf(": version 0x%x", openpic_read(OPENPIC_FEATURE) & 0xFF); + + i8259_init(); + openpic_init(); + + pending_int_f = openpic_do_pending_int; + intr_establish_func = openpic_intr_establish; + intr_disestablish_func = openpic_intr_disestablish; +#if 0 + mac_intr_establish_func = openpic_intr_establish; + mac_intr_disestablish_func = openpic_intr_disestablish; +#endif + install_extint(ext_intr_openpic); + +#if 1 + openpic_collect_preconf_intr(); +#endif + +#if 1 + + intr_establish_func(parent, 0x00, IST_LEVEL, IPL_HIGH, + i8259_dummy, (void *)0x00, "8259 Interrupt"); + i8259_intr_establish(parent, 0x08, IST_EDGE, IPL_HIGH, + abort_switch, (void *)0x08, "abort button"); +#endif +/* + ppc_intr_enable(1); +*/ + printf("\n"); +} + +void +openpic_collect_preconf_intr() +{ + int i; + for (i = 0; i < ppc_configed_intr_cnt; i++) { +#ifdef DEBUG + printf("\n\t%s irq %d level %d fun %x arg %x", + ppc_configed_intr[i].ih_what, ppc_configed_intr[i].ih_irq, + ppc_configed_intr[i].ih_level, ppc_configed_intr[i].ih_fun, + ppc_configed_intr[i].ih_arg); +#endif + openpic_intr_establish(NULL, ppc_configed_intr[i].ih_irq, + IST_LEVEL, ppc_configed_intr[i].ih_level, + ppc_configed_intr[i].ih_fun, ppc_configed_intr[i].ih_arg, + ppc_configed_intr[i].ih_what); + } +} + +static int +abort_switch (void *arg) +{ +#ifdef DDB + printf("Abort button pressed, entering debugger.\n"); + Debugger(); +#else + printf("Abort button pressed, debugger not available.\n"); +#endif + return 1; +} + +static int +i8259_dummy (void *arg) +{ + return 1; +} + +static int +fakeintr(arg) + void *arg; +{ + + return 0; +} + +/* + * Register an interrupt handler. + */ +void * +i8259_intr_establish(lcv, irq, type, level, ih_fun, ih_arg, name) + void * lcv; + int irq; + int type; + int level; + int (*ih_fun) __P((void *)); + void *ih_arg; + char *name; +{ + struct intrhand **p, *q, *ih; + static struct intrhand fakehand; + extern int cold; + + fakehand.ih_next = NULL; + fakehand.ih_fun = fakeintr; + +#if 0 +printf("i8259_intr_establish, hI %d L %d ", irq, type); +#endif + isaintrs++; + irq = mapirq(irq + ICU_OFFSET); +#if 0 +printf("vI %d ", irq); +#endif + + /* no point in sleeping unless someone can free memory. */ + ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK); + if (ih == NULL) + panic("i8259_intr_establish: can't malloc handler info"); + + if (!LEGAL_IRQ(irq) || type == IST_NONE) + panic("i8259_intr_establish: bogus irq or type"); + + switch (intrtype[irq]) { + case IST_NONE: + intrtype[irq] = type; + break; + case IST_EDGE: + case IST_LEVEL: + if (type == intrtype[irq]) + break; + case IST_PULSE: + if (type != IST_NONE) + panic("intr_establish: can't share %s with %s", + intr_typename(intrtype[irq]), + intr_typename(type)); + break; + } + + /* + * Figure out where to put the handler. + * This is O(N^2), but we want to preserve the order, and N is + * generally small. + */ + for (p = &intrhand[irq]; (q = *p) != NULL; p = &q->ih_next) + ; + + /* + * Actually install a fake handler momentarily, since we might be doing + * this with interrupts enabled and DON'T WANt the real routine called + * until masking is set up. + */ + fakehand.ih_level = level; + *p = &fakehand; + + intr_calculatemasks(); + + /* + * Poke the real handler in now. + */ + ih->ih_fun = ih_fun; + ih->ih_arg = ih_arg; + ih->ih_count = 0; + ih->ih_next = NULL; + ih->ih_level = level; + ih->ih_irq = irq; + *p = ih; + + return (ih); +} + + +/* + * Register an interrupt handler. + */ +void * +openpic_intr_establish(lcv, irq, type, level, ih_fun, ih_arg, name) + void * lcv; + int irq; + int type; + int level; + int (*ih_fun) __P((void *)); + void *ih_arg; + char *name; +{ + struct intrhand **p, *q, *ih; + static struct intrhand fakehand; + struct pci_route *pr; + extern int cold; + + fakehand.ih_next = NULL; + fakehand.ih_fun = fakeintr; + +#if 0 +printf("mac_intr_establish, hI %d L %d ", irq, type); +#endif + + pr = pci_routes; + while (pr->pci !=0) { + irq = (pr->pci == irq) ? pr->openpic : irq; + pr++; + } + + irq = mapirq(irq); +#if 0 +printf("vI %d ", irq); +#endif + + /* no point in sleeping unless someone can free memory. */ + ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK); + if (ih == NULL) + panic("intr_establish: can't malloc handler info"); + + if (!LEGAL_IRQ(irq) || type == IST_NONE) + panic("intr_establish: bogus irq or type"); + + switch (intrtype[irq]) { + case IST_NONE: + intrtype[irq] = type; + break; + case IST_EDGE: + case IST_LEVEL: + if (type == intrtype[irq]) + break; + case IST_PULSE: + if (type != IST_NONE) + panic("intr_establish: can't share %s with %s", + intr_typename(intrtype[irq]), + intr_typename(type)); + break; + } + + /* + * Figure out where to put the handler. + * This is O(N^2), but we want to preserve the order, and N is + * generally small. + */ + for (p = &intrhand[irq]; (q = *p) != NULL; p = &q->ih_next) + ; + + /* + * Actually install a fake handler momentarily, since we might be doing + * this with interrupts enabled and DON'T WANt the real routine called + * until masking is set up. + */ + fakehand.ih_level = level; + *p = &fakehand; + + intr_calculatemasks(); + + /* + * Poke the real handler in now. + */ + ih->ih_fun = ih_fun; + ih->ih_arg = ih_arg; + ih->ih_count = 0; + ih->ih_next = NULL; + ih->ih_level = level; + ih->ih_irq = irq; + *p = ih; + + return (ih); +} + +/* + * Deregister an interrupt handler. + */ +void +openpic_intr_disestablish(lcp, arg) + void *lcp; + void *arg; +{ + struct intrhand *ih = arg; + int irq = ih->ih_irq; + struct intrhand **p, *q; + + if (!LEGAL_IRQ(irq)) + panic("intr_disestablish: bogus irq"); + + /* + * Remove the handler from the chain. + * This is O(n^2), too. + */ + for (p = &intrhand[irq]; (q = *p) != NULL && q != ih; p = &q->ih_next) + ; + if (q) + *p = q->ih_next; + else + panic("intr_disestablish: handler not registered"); + free((void *)ih, M_DEVBUF); + + intr_calculatemasks(); + + if (intrhand[irq] == NULL) + intrtype[irq] = IST_NONE; +} + + +static char * +intr_typename(type) + int type; +{ + + switch (type) { + case IST_NONE : + return ("none"); + case IST_PULSE: + return ("pulsed"); + case IST_EDGE: + return ("edge-triggered"); + case IST_LEVEL: + return ("level-triggered"); + default: + panic("intr_typename: invalid type %d", type); +#if 1 /* XXX */ + return ("unknown"); +#endif + } +} + +/* + * Recalculate the interrupt masks from scratch. + * We could code special registry and deregistry versions of this function that + * would be faster, but the code would be nastier, and we don't expect this to + * happen very much anyway. + */ +static void +intr_calculatemasks() +{ + int irq, level; + struct intrhand *q; +#ifdef OP_DEBUG + printf("intr_calculatemasks() "); +#endif + /* First, figure out which levels each IRQ uses. */ + for (irq = 0; irq < ICU_LEN; irq++) { + register int levels = 0; + for (q = intrhand[irq]; q; q = q->ih_next) + levels |= 1 << q->ih_level; + intrlevel[irq] = levels; + } + + /* Then figure out which IRQs use each level. */ + for (level = 0; level < 5; level++) { + register int irqs = 0; + for (irq = 0; irq < ICU_LEN; irq++) + if (intrlevel[irq] & (1 << level)) + irqs |= 1 << irq; + imask[level] = irqs | SINT_MASK; + } + + /* + * There are tty, network and disk drivers that use free() at interrupt + * time, so imp > (tty | net | bio). + */ + imask[IPL_IMP] |= imask[IPL_TTY] | imask[IPL_NET] | imask[IPL_BIO]; + + /* + * Enforce a hierarchy that gives slow devices a better chance at not + * dropping data. + */ + imask[IPL_TTY] |= imask[IPL_NET] | imask[IPL_BIO]; + imask[IPL_NET] |= imask[IPL_BIO]; + + /* + * These are pseudo-levels. + */ + imask[IPL_NONE] = 0x00000000; + imask[IPL_HIGH] = 0xffffffff; + + /* And eventually calculate the complete masks. */ + for (irq = 0; irq < ICU_LEN; irq++) { + register int irqs = 1 << irq; + for (q = intrhand[irq]; q; q = q->ih_next) + irqs |= imask[q->ih_level]; + intrmask[irq] = irqs | SINT_MASK; + } + + /* Lastly, determine which IRQs are actually in use. */ + { + register int irqs = 0; + for (irq = 0; irq < ICU_LEN; irq++) { + if (intrhand[irq]) { + irqs |= 1 << irq; + if (hwirq[irq] >= ICU_OFFSET) + i8259_enable_irq(hwirq[irq]); + else + openpic_enable_irq(hwirq[irq], intrtype[irq]); + } else { + if (hwirq[irq] >= ICU_OFFSET) + i8259_disable_irq(hwirq[irq]); + else + openpic_disable_irq(hwirq[irq]); + } + } + } +#if 0 + i8259_enable_irq(2); +#endif +} +/* + * Map 64 irqs into 32 (bits). + */ +static int +mapirq(irq) + int irq; +{ + int v; + + if (irq < 0 || irq >= ICU_LEN) + panic("invalid irq"); + virq_max++; + v = virq_max; + if (v > HWIRQ_MAX) + panic("virq overflow"); + + hwirq[v] = irq; + virq[irq] = v; +#if 0 +printf("\nmapirq %x to %x\n", irq, v); +#endif + + return v; +} + +/* + * Count leading zeros. + */ +static __inline int +cntlzw(x) + int x; +{ + int a; + + __asm __volatile ("cntlzw %0,%1" : "=r"(a) : "r"(x)); + + return a; +} + + +void +openpic_do_pending_int() +{ + struct intrhand *ih; + int irq; + int pcpl; + int hwpend; + int emsr, dmsr; + static int processing; + + if (processing) + return; + +#ifdef OP_DEBUG + printf("openpic_do_pending_int()\n"); +#endif + processing = 1; + pcpl = splhigh(); /* Turn off all */ + asm volatile("mfmsr %0" : "=r"(emsr)); + dmsr = emsr & ~PSL_EE; + asm volatile("mtmsr %0" :: "r"(dmsr)); + + hwpend = ipending & ~pcpl; /* Do now unmasked pendings */ + imen &= ~hwpend; + openpic_enable_irq_mask(~imen); + + hwpend &= HWIRQ_MASK; + while (hwpend) { + irq = 31 - cntlzw(hwpend); + hwpend &= ~(1L << irq); + ih = intrhand[irq]; + while(ih) { + (*ih->ih_fun)(ih->ih_arg); + ih = ih->ih_next; + } + + evirq[hwirq[irq]].ev_count++; + } + + /*out32rb(INT_ENABLE_REG, ~imen);*/ + + do { + if((ipending & SINT_CLOCK) & ~pcpl) { + ipending &= ~SINT_CLOCK; + softclock(); + } + if((ipending & SINT_NET) & ~pcpl) { + extern int netisr; + int pisr = netisr; + netisr = 0; + ipending &= ~SINT_NET; + softnet(pisr); + } + } while (ipending & (SINT_NET|SINT_CLOCK) & ~cpl); + ipending &= pcpl; + cpl = pcpl; /* Don't use splx... we are here already! */ + asm volatile("mtmsr %0" :: "r"(emsr)); + processing = 0; +} + +u_int +openpic_read(reg) + int reg; +{ + char *addr = (void *)(openpic_base + reg); + + return in32rb(addr); +} + +void +openpic_write(reg, val) + int reg; + u_int val; +{ + char *addr = (void *)(openpic_base + reg); + + out32rb(addr, val); +} + +void +openpic_enable_irq_mask(irq_mask) +int irq_mask; +{ + int irq; +#ifdef OP_DEBUG + printf("openpic_enable_irq_mask()\n"); +#endif + for ( irq = 0; irq <= virq_max; irq++) { + if (irq_mask & (1 << irq)) { + if (hwirq[irq] >= ICU_OFFSET) + i8259_enable_irq(hwirq[irq]); + else + openpic_enable_irq(hwirq[irq], intrtype[irq]); + } else { + if (hwirq[irq] >= ICU_OFFSET) + i8259_disable_irq(hwirq[irq]); + else + openpic_disable_irq(hwirq[irq]); + } + } +} + +void +openpic_enable_irq(irq, type) + int irq; + int type; +{ + u_int x; + /* skip invalid irqs */ + if (irq == -1) + return; + + x = openpic_read(OPENPIC_SRC_VECTOR(irq)); + x &= ~(OPENPIC_IMASK|OPENPIC_SENSE_LEVEL|OPENPIC_SENSE_EDGE); + if (type == IST_LEVEL) { + x |= OPENPIC_SENSE_LEVEL; + } else { + x |= OPENPIC_SENSE_EDGE; + } +#ifdef OP_DEBUG + printf("enabeling irq %d, type %d, val 0x%08x\n", irq, type, x); +#endif + + openpic_write(OPENPIC_SRC_VECTOR(irq), x); +} + +void +openpic_disable_irq(irq) + int irq; +{ + u_int x; + /* skip invalid irqs */ + if (irq == -1) + return; + + x = openpic_read(OPENPIC_SRC_VECTOR(irq)); + x |= OPENPIC_IMASK; +#ifdef OP_DEBUG + printf("disabeling irq %d, val 0x%08x\n", irq, x); +#endif + + openpic_write(OPENPIC_SRC_VECTOR(irq), x); +} + +void +i8259_set_irq_mask(void) +{ + if (icu2_val != 0xFF) { + /* Turn on the second IC */ + icu1_val &= ~(1 << 2); + } else { + icu1_val |= (1 << 2); + } + + outb(IO_ICU1 + 1, icu1_val); + outb(IO_ICU2 + 1, icu2_val); +} + +void +i8259_disable_irq(irq) +int irq; +{ + if (irq >= ICU_OFFSET) + irq -= ICU_OFFSET; + if (irq < 8) + icu1_val |= 1 << irq; + else + icu2_val |= 1 << (irq - 8); + i8259_set_irq_mask(); +#ifdef OP_DEBUG + printf("disabeling isa irq %d\n", irq); +#endif +} + +void +i8259_enable_irq(irq) +int irq; +{ + + if (irq >= ICU_OFFSET) + irq -= ICU_OFFSET; + if ( irq < 8 ) + icu1_val &= ~(1 << irq); + else + icu2_val &= ~(1 << (irq - 8)); + i8259_set_irq_mask(); +#ifdef OP_DEBUG + printf("enabeling isa irq %d\n", irq); +#endif + +} + +void +openpic_set_priority(cpu, pri) + int cpu, pri; +{ + u_int x; + + x = openpic_read(OPENPIC_CPU_PRIORITY(cpu)); + x &= ~OPENPIC_CPU_PRIORITY_MASK; + x |= pri; + openpic_write(OPENPIC_CPU_PRIORITY(cpu), x); +} + +int +openpic_read_irq(cpu) + int cpu; +{ + return openpic_read(OPENPIC_IACK(cpu)) & OPENPIC_VECTOR_MASK; +} + +void +openpic_eoi(cpu) + int cpu; +{ + openpic_write(OPENPIC_EOI(cpu), 0); + openpic_read(OPENPIC_EOI(cpu)); +} + +void i8259_init(void) +{ + /* initialize 8259's */ + outb(IO_ICU1, 0x11); /* reset; program device, four bytes */ + outb(IO_ICU1+1, ICU_OFFSET); /* starting at this vector index */ + outb(IO_ICU1+1, 1 << IRQ_SLAVE); /* slave on line 2 */ + outb(IO_ICU1+1, 1); /* 8086 mode */ + outb(IO_ICU1+1, 0xff); /* leave interrupts masked */ + /* init interrupt controller 2 */ + outb(IO_ICU2, 0x11); /* reset; program device, four bytes */ + outb(IO_ICU2+1, ICU_OFFSET+8); /* staring at this vector index */ + outb(IO_ICU2+1, IRQ_SLAVE); + outb(IO_ICU2+1, 1); /* 8086 mode */ + outb(IO_ICU2+1, 0xff); /* leave interrupts masked */ +} + +int i8259_intr(void) +{ + int irq; + + /* + * Perform an interrupt acknowledge cycle on controller 1 + */ + outb(IO_ICU1, 0x0C); + irq = inb(IO_ICU1) & 7; +#ifdef OP_DEBUG + printf("isa intr = %d\n", irq); +#endif + if (irq == 2) + { + /* + * Interrupt is cascaded so perform interrupt + * acknowledge on controller 2 + */ + outb(IO_ICU2, 0x0C); + irq = (inb(IO_ICU2) & 7) + 8; + } + else if (irq==7) + { + /* + * This may be a spurious interrupt + * + * Read the interrupt status register. If the most + * significant bit is not set then there is no valid + * interrupt + */ + outb(IO_ICU1, 0x0B); + if(~inb(IO_ICU1)&0x80) + return 0xFF; + } + return (ICU_OFFSET + irq); +} + +void +ext_intr_openpic() +{ + int irq, realirq; + int r_imen; + int pcpl; + struct intrhand *ih; + +#ifdef OP_DEBUG + printf("Interrupt!\n"); +#endif + pcpl = splhigh(); /* Turn off all */ + + realirq = openpic_read_irq(0); +#ifdef OP_DEBUG + printf("irq %d\n", realirq); +#endif + + while ((realirq != 0xFF) && (realirq != 0xAA)) { + if (realirq == 0x00){ + realirq = i8259_intr(); +#ifdef OP_DEBUG + printf("irq2 %d\n", realirq); +#endif + openpic_eoi(0); + if (realirq == 0xFF) + continue; + } + + irq = virq[realirq]; + intrcnt[realirq]++; + + /* XXX check range */ + + r_imen = 1 << irq; + + if ((pcpl & r_imen) != 0) { + ipending |= r_imen; /* Masked! Mark this as pending */ + if (realirq >= ICU_OFFSET) + i8259_disable_irq(realirq); + else + openpic_disable_irq(realirq); + } else { + ih = intrhand[irq]; + while (ih) { + (*ih->ih_fun)(ih->ih_arg); + ih = ih->ih_next; + } +#ifdef UVM + uvmexp.intrs++; +#else +#endif + evirq[realirq].ev_count++; + } + + openpic_eoi(0); + + realirq = openpic_read_irq(0); + } + + splx(pcpl); /* Process pendings. */ +} + +void openpic_set_vec_pri(int irq, int pri) +{ + u_int x; + x = openpic_read(OPENPIC_SRC_VECTOR(irq)); + x &= ~OPENPIC_PRIORITY_MASK; + x |= pri << OPENPIC_PRIORITY_SHIFT; + openpic_write(OPENPIC_SRC_VECTOR(irq), x); +} + +void openpic_initirq(int irq, int pri, int vec, int pol, int sense) +{ + u_int x; + x = (vec & OPENPIC_VECTOR_MASK); + x |= OPENPIC_IMASK; + x |= (pol ? OPENPIC_POLARITY_POSITIVE : OPENPIC_POLARITY_NEGATIVE); + x |= (sense ? OPENPIC_SENSE_LEVEL : OPENPIC_SENSE_EDGE); + x |= pri << OPENPIC_PRIORITY_SHIFT; + openpic_write(OPENPIC_SRC_VECTOR(irq), x); +} + +void +openpic_init() +{ + int irq; + u_int x; + + /* disable all interrupts and init hwirq[] */ + for (irq = 0; irq < ICU_LEN; irq++){ + hwirq[irq] = -1; + openpic_write(OPENPIC_SRC_VECTOR(irq), OPENPIC_IMASK); + } + openpic_set_priority(0, 15); + + /* we don't need 8259 pass through mode */ + x = openpic_read(OPENPIC_CONFIG); + x |= OPENPIC_CONFIG_8259_PASSTHRU_DISABLE; + openpic_write(OPENPIC_CONFIG, x); + + /* send all interrupts to cpu 0 */ + for (irq = 0; irq < ICU_LEN; irq++) + openpic_write(OPENPIC_SRC_DEST(irq), CPU(0)); + + /* special case for intr src 0 */ + openpic_initirq(0, 8, 0, 1, 0); + + for (irq = 1; irq < ICU_LEN; irq++) { + openpic_initirq(irq, 8, irq, 0, 1); + } + + /* XXX set spurious intr vector */ + openpic_write(OPENPIC_SPURIOUS_VECTOR, 0xFF); + + /* unmask interrupts for cpu 0 */ + openpic_set_priority(0, 0); + + /* clear all pending interrunts */ + for (irq = 0; irq < ICU_OFFSET; irq++) { + openpic_read_irq(0); + openpic_eoi(0); + } + + for (irq = 0; irq < ICU_OFFSET; irq++){ + i8259_disable_irq(irq); + openpic_disable_irq(irq); + } + + install_extint(ext_intr_openpic); +} diff --git a/sys/arch/mvmeppc/dev/openpicreg.h b/sys/arch/mvmeppc/dev/openpicreg.h new file mode 100644 index 00000000000..72fe1f17af0 --- /dev/null +++ b/sys/arch/mvmeppc/dev/openpicreg.h @@ -0,0 +1,90 @@ +/* $NetBSD: openpicreg.h,v 1.1 2000/02/14 12:45:53 tsubai Exp $ */ + +/*- + * Copyright (c) 2000 Tsubai Masanari. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the 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. + */ + +/* + * GLOBAL/TIMER register (IDU base + 0x1000) + */ + +/* feature reporting reg 0 */ +#define OPENPIC_FEATURE 0x1000 + +/* global config reg 0 */ +#define OPENPIC_CONFIG 0x1020 +#define OPENPIC_CONFIG_RESET 0x80000000 +#define OPENPIC_CONFIG_8259_PASSTHRU_DISABLE 0x20000000 + +/* vendor ID */ +#define OPENPIC_VENDOR_ID 0x1080 + +/* processor initialization reg */ +#define OPENPIC_PROC_INIT 0x1090 + +/* IPI vector/priority reg */ +#define OPENPIC_IPI_VECTOR(ipi) (0x10a0 + (ipi) * 0x10) + +/* spurious intr. vector */ +#define OPENPIC_SPURIOUS_VECTOR 0x10e0 + + +/* + * INTERRUPT SOURCE register (IDU base + 0x10000) + */ + +/* interrupt vector/priority reg */ +#define OPENPIC_SRC_VECTOR(irq) (0x10000 + (irq) * 0x20) +#define OPENPIC_SENSE_LEVEL 0x00400000 +#define OPENPIC_SENSE_EDGE 0x00000000 +#define OPENPIC_POLARITY_POSITIVE 0x00800000 +#define OPENPIC_POLARITY_NEGATIVE 0x00000000 +#define OPENPIC_IMASK 0x80000000 +#define OPENPIC_ACTIVITY 0x40000000 +#define OPENPIC_PRIORITY_MASK 0x000f0000 +#define OPENPIC_PRIORITY_SHIFT 16 +#define OPENPIC_VECTOR_MASK 0x000000ff + +/* interrupt destination cpu */ +#define OPENPIC_SRC_DEST(irq) (0x10010 + (irq) * 0x20) + +#define CPU(x) (1 << (x)) + +/* + * PROCESSOR register (IDU base + 0x20000) + */ + +/* IPI command reg */ +#define OPENPIC_IPI(cpu, ipi) (0x20040 + (cpu) * 0x1000 + (ipi)) + +/* current task priority reg */ +#define OPENPIC_CPU_PRIORITY(cpu) (0x20080 + (cpu) * 0x1000) +#define OPENPIC_CPU_PRIORITY_MASK 0x0000000f + +/* interrupt acknowledge reg */ +#define OPENPIC_IACK(cpu) (0x200a0 + (cpu) * 0x1000) + +/* end of interrupt reg */ +#define OPENPIC_EOI(cpu) (0x200b0 + (cpu) * 0x1000) diff --git a/sys/arch/mvmeppc/dev/raven.c b/sys/arch/mvmeppc/dev/raven.c new file mode 100644 index 00000000000..f198db8e83c --- /dev/null +++ b/sys/arch/mvmeppc/dev/raven.c @@ -0,0 +1,99 @@ +/* $OpenBSD: raven.c,v 1.1 2001/06/26 21:57:41 smurph Exp $ */ + +/* + * Copyright (c) 2001 Steve Murphree, Jr. + * + * 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 under OpenBSD for RTMX Inc + * by Per Fogelstrom, Opsycon AB. + * 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. + * + */ + +/* + * Motorola 'Raven' ASIC driver. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/malloc.h> +#include <sys/device.h> +#include <sys/proc.h> +#include <vm/vm.h> + +#include <machine/autoconf.h> + +#include <mvmeppc/dev/ravenreg.h> +#include <mvmeppc/dev/ravenvar.h> + +int raven_match __P((struct device *, void *, void *)); +void raven_attach __P((struct device *, struct device *, void *)); + +struct cfattach raven_ca = { + sizeof(struct raven_softc), raven_match, raven_attach, +}; + +struct cfdriver raven_cd = { + NULL, "raven", DV_DULL, +}; + +int +raven_match(parent, match, aux) + struct device *parent; + void *match, *aux; +{ + struct confargs *ca = aux; + unsigned *reg = (unsigned *)RAVEN_REG; + + /* check for a live address */ + if (badaddr((char *)reg, 4)) + return 0; + + /* now check and see if it's a raven ASIC */ + if (*reg != RAVEN_MAGIC) + return 0; + + return 1; +} + +void +raven_attach(parent, self, aux) + struct device *parent, *self; + void *aux; +{ + struct raven_softc *sc = (struct raven_softc *)self; + struct confargs *ca = aux; + struct mpic_feature *feature = (struct mpic_feature *)MPCIC_FEATURE; + + /* set system type */ + system_type = MVME; /* We are a Motorola MVME SBC */ + + printf(": RAVEN, Version 0x%x.\n", feature->vid); + while (config_found(self, NULL, NULL)) + ; +} + + diff --git a/sys/arch/mvmeppc/dev/ravenreg.h b/sys/arch/mvmeppc/dev/ravenreg.h new file mode 100644 index 00000000000..295e4b5e717 --- /dev/null +++ b/sys/arch/mvmeppc/dev/ravenreg.h @@ -0,0 +1,123 @@ +/* $OpenBSD: ravenreg.h,v 1.1 2001/06/26 21:57:41 smurph Exp $ */ + +/* + * Copyright (c) 2001 Steve Murphree, Jr. + * + * 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 under OpenBSD for RTMX Inc + * by Per Fogelstrom, Opsycon AB. + * 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. + * + * + * ravenreg.h: Motorola 'Raven' PowerPC to PCI bridge controller + */ + +#ifndef _MACHINE_RAVENREG_H_ +#define _MACHINE_RAVENREG_H_ + +#define RAVEN_REG 0xFEFF0000 +#define RAVEN_VENDOR 0xFEFF0000 +#define RAVEN_MAGIC 0x10574801 /* vendor information */ +#define RAVEN_DEVICE 0xFEFF0002 +#define RAVEN_REVID 0xFEFF0005 +#define RAVEN_GCSR 0xFEFF0008 +#define RAVEN_FEAT 0xFEFF000A +#define RAVEN_MARB 0xFEFF000E +#define RAVEN_PIACK 0xFEFF0030 + +#define RAVEN_MSADD0 0xFEFF0040 +#define RAVEN_MSADD0_PREP 0xC000FCFF +#define RAVEN_MSOFF0 0xFEFF0044 +#define RAVEN_MSOFF0_PREP 0x400000C2 +#define RAVEN_MSADD1 0xFEFF0048 +#define RAVEN_MSADD1_PREP 0x00000000 +#define RAVEN_MSOFF1 0xFEFF004C +#define RAVEN_MSOFF1_PREP 0x00000002 +#define RAVEN_MSADD2 0xFEFF0050 +#define RAVEN_MSADD2_PREP 0x00000000 +#define RAVEN_MSOFF2 0xFEFF0054 +#define RAVEN_MSOFF2_PREP 0x00000002 +#define RAVEN_MSADD3 0xFEFF0058 +#define RAVEN_MSADD3_PREP 0x8000BFFF +#define RAVEN_MSOFF3 0xFEFF005C +#define RAVEN_MSOFF3_PREP 0x800000C0 + +/* Where we map the PCI memory space - MAP A*/ +#define RAVEN_V_PCI_MEM_SPACE 0xc0000000 /* Viritual */ +#define RAVEN_P_PCI_MEM_SPACE 0xc0000000 /* Physical */ + +/* Where we map the PCI I/O space - MAP A*/ +#define RAVEN_P_ISA_IO_SPACE 0x80000000 +#define RAVEN_V_ISA_IO_SPACE 0x80000000 +#define RAVEN_V_PCI_IO_SPACE 0x80000000 +#define RAVEN_P_PCI_IO_SPACE 0x80000000 + +#define PREP_CONFIG_ADD 0x80000CF8 +#define PREP_CONFIG_DAT 0x80000CFC + +/* Where we map the config space */ +#define RAVEN_PCI_CONF_SPACE (RAVEN_V_ISA_IO_SPACE + 0x00800000) + +/* Where we map the PCI memory space - MAP B*/ +#define RAVEN_P_PCI_MEM_SPACE_MAP_B 0x80000000 /* Physical */ + +/* Where we map the PCI I/O space - MAP B*/ +#define RAVEN_P_PCI_IO_SPACE_MAP_B 0xfe000000 + +/* offsets from base pointer */ +#define RAVEN_REGOFFS(x) ((x) | 0x80000000) + +/* Where PCI devices sees CPU memory. */ +#define RAVEN_PCI_CPUMEM 0x80000000 + +#define RAVEN_PCI_VENDOR 0x00 +#define RAVEN_PCI_DEVICE 0x02 +#define RAVEN_PCI_CMD 0x04 +#define RAVEN_PCI_STAT 0x06 +#define RAVEN_PCI_REVID 0x08 +#define RAVEN_PCI_IO 0x10 +#define RAVEN_PCI_MEM 0x14 +#define RAVEN_PCI_PSADD0 0x80 +#define RAVEN_PCI_PSADD0_VAL 0x8000FBFF +#define RAVEN_PCI_PSOFF0 0x84 +#define RAVEN_PCI_PSOFF0_VAL 0x800000F0 +#define RAVEN_PCI_PSADD1 0x88 +#define RAVEN_PCI_PSADD1_VAL 0xC000FCFF +#define RAVEN_PCI_PSOFF1 0x8C +#define RAVEN_PCI_PSOFF1_VAL 0x400000F0 +#define RAVEN_PCI_PSADD2 0x90 +#define RAVEN_PCI_PSADD2_VAL 0x00000000 +#define RAVEN_PCI_PSOFF2 0x94 +#define RAVEN_PCI_PSOFF2_VAL 0x00000000 +#define RAVEN_PCI_PSADD3 0x98 +#define RAVEN_PCI_PSADD3_VAL 0x00000000 +#define RAVEN_PCI_PSOFF3 0x9C +#define RAVEN_PCI_PSOFF3_VAL 0x00000000 + +#define RAVEN_CMD_IOSP 0x0001 +#define RAVEN_CMD_MEMSP 0x0002 +#define RAVEN_CMD_MASTR 0x0004 + +#endif /* _MACHINE_RAVENREG_H_ */ diff --git a/sys/arch/mvmeppc/dev/ravenvar.h b/sys/arch/mvmeppc/dev/ravenvar.h new file mode 100644 index 00000000000..2d922a1bb80 --- /dev/null +++ b/sys/arch/mvmeppc/dev/ravenvar.h @@ -0,0 +1,387 @@ +/* $OpenBSD: ravenvar.h,v 1.1 2001/06/26 21:57:42 smurph Exp $ */ + +/* + * Copyright (c) 2001 Steve Murphree, Jr. + * + * 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 under OpenBSD for RTMX Inc + * by Per Fogelstrom, Opsycon AB. + * 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. + * + * + * ravenreg.h: Motorola 'Raven' PowerPC to PCI bridge controller + */ + +#ifndef _DEV_RAVENVAR_H_ +#define _DEV_RAVENREG_H_ + +#define MPCIC_REG 0xFC000000 +#define MPCIC_FEATURE (MPCIC_REG | 0x01000) +#define MPCIC_GCR (MPCIC_REG | 0x01020) +#define MPCIC_VID (MPCIC_REG | 0x01080) +#define MPCIC_PINIT (MPCIC_REG | 0x01090) +#define MPCIC_IPI0 (MPCIC_REG | 0x010A0) +#define MPCIC_IPI1 (MPCIC_REG | 0x010B0) +#define MPCIC_IPI2 (MPCIC_REG | 0x010C0) +#define MPCIC_IPI3 (MPCIC_REG | 0x010D0) +#define MPCIC_SP (MPCIC_REG | 0x010E0) +#define MPCIC_TFR (MPCIC_REG | 0x010F0) +#define MPCIC_T0CC (MPCIC_REG | 0x01100) +#define MPCIC_T0BC (MPCIC_REG | 0x01110) +#define MPCIC_T0VP (MPCIC_REG | 0x01120) +#define MPCIC_T0D (MPCIC_REG | 0x01130) +#define MPCIC_T1CC (MPCIC_REG | 0x01140) +#define MPCIC_T1BC (MPCIC_REG | 0x01150) +#define MPCIC_T1VP (MPCIC_REG | 0x01160) +#define MPCIC_T1D (MPCIC_REG | 0x01170) +#define MPCIC_T2CC (MPCIC_REG | 0x01180) +#define MPCIC_T2BC (MPCIC_REG | 0x01190) +#define MPCIC_T2VP (MPCIC_REG | 0x011A0) +#define MPCIC_T2D (MPCIC_REG | 0x011B0) +#define MPCIC_T3CC (MPCIC_REG | 0x011C0) +#define MPCIC_T3BC (MPCIC_REG | 0x011D0) +#define MPCIC_T3VP (MPCIC_REG | 0x011E0) +#define MPCIC_T3D (MPCIC_REG | 0x011F0) +#define MPCIC_INT0VP (MPCIC_REG | 0x10000) +#define MPCIC_INT0D (MPCIC_REG | 0x10010) +#define MPCIC_INT1VP (MPCIC_REG | 0x10020) +#define MPCIC_INT1D (MPCIC_REG | 0x10030) +#define MPCIC_INT2VP (MPCIC_REG | 0x10040) +#define MPCIC_INT2D (MPCIC_REG | 0x10050) +#define MPCIC_INT3VP (MPCIC_REG | 0x10060) +#define MPCIC_INT3D (MPCIC_REG | 0x10070) +#define MPCIC_INT4VP (MPCIC_REG | 0x10080) +#define MPCIC_INT4D (MPCIC_REG | 0x10090) +#define MPCIC_INT5VP (MPCIC_REG | 0x100A0) +#define MPCIC_INT5D (MPCIC_REG | 0x100B0) +#define MPCIC_INT6VP (MPCIC_REG | 0x100C0) +#define MPCIC_INT6D (MPCIC_REG | 0x100D0) +#define MPCIC_INT7VP (MPCIC_REG | 0x100E0) +#define MPCIC_INT7D (MPCIC_REG | 0x100F0) +#define MPCIC_INT8VP (MPCIC_REG | 0x10100) +#define MPCIC_INT8D (MPCIC_REG | 0x10110) +#define MPCIC_INT9VP (MPCIC_REG | 0x10120) +#define MPCIC_INT9D (MPCIC_REG | 0x10130) +#define MPCIC_INT10VP (MPCIC_REG | 0x10140) +#define MPCIC_INT10D (MPCIC_REG | 0x10150) +#define MPCIC_INT11VP (MPCIC_REG | 0x10160) +#define MPCIC_INT11D (MPCIC_REG | 0x10170) +#define MPCIC_INT12VP (MPCIC_REG | 0x10180) +#define MPCIC_INT12D (MPCIC_REG | 0x10190) +#define MPCIC_INT13VP (MPCIC_REG | 0x101A0) +#define MPCIC_INT13D (MPCIC_REG | 0x101B0) +#define MPCIC_INT14VP (MPCIC_REG | 0x101C0) +#define MPCIC_INT14D (MPCIC_REG | 0x101D0) +#define MPCIC_INT15VP (MPCIC_REG | 0x101E0) +#define MPCIC_INT15D (MPCIC_REG | 0x101F0) +#define MPCIC_EVP (MPCIC_REG | 0x10200) +#define MPCIC_ED (MPCIC_REG | 0x10210) +#define MPCIC_P0_IPI0_D (MPCIC_REG | 0x20040) +#define MPCIC_P0_IPI1_D (MPCIC_REG | 0x20050) +#define MPCIC_P0_IPI2_D (MPCIC_REG | 0x20060) +#define MPCIC_P0_IPI3_D (MPCIC_REG | 0x20070) +#define MPCIC_P0_TP (MPCIC_REG | 0x20080) +#define MPCIC_P0_IACK (MPCIC_REG | 0x200A0) +#define MPCIC_P0_EOI (MPCIC_REG | 0x200B0) +#define MPCIC_P1_IPI0_D (MPCIC_REG | 0x21040) +#define MPCIC_P1_IPI1_D (MPCIC_REG | 0x21050) +#define MPCIC_P1_IPI2_D (MPCIC_REG | 0x21060) +#define MPCIC_P1_IPI3_D (MPCIC_REG | 0x21070) +#define MPCIC_P1_TP (MPCIC_REG | 0x21080) +#define MPCIC_P1_IACK (MPCIC_REG | 0x210A0) +#define MPCIC_P1_EOI (MPCIC_REG | 0x210B0) + +#define PROC0 0x01 +#define PROC1 0x02 + +#define GCR_M 0x04 +#define VP_MASKED 0x00000080 +#define VP_LEVEL 0x00004000 +#define VP_POL 0x00008000 +#define VP_VEC(x) ((x) << 24) +#define VP_PRI(x) ((x) << 8) + +struct mpic_feature { + unsigned int res1 : 4, + nirq : 12, + res2 : 3, + ncpu : 5, + vid : 8; +}; + +struct mpic_gcr { + unsigned int reset : 1, + res1 : 1, + cmode : 1, + res2 : 29; +}; + +struct mpic_vid { + unsigned int res1 : 8, + stp : 8, + res2 : 16; +}; + + +struct mpic_ipivp { + unsigned int masked : 1, + act : 1, + res1 : 10, + pri : 4, + res2 : 8, + vec : 8; +}; + +struct mpic_timer_count { + unsigned int toggle : 1, + count : 31; +}; + +struct mpic_timer_bcount { + unsigned int inhib : 1, + count : 31; +}; + +struct mpic_timer_vp { + unsigned int masked : 1, + act : 1, + res1 : 10, + pri : 4, + res2 : 8, + vec : 8; +}; + +struct mpic_timer { + struct mpic_timer_count *cr; + struct mpic_timer_bcount *bcr; + struct mpic_timer_vp *vp; + unsigned char *dest; +}; + +struct mpic_ext_vp { + unsigned int masked : 1, + act : 1, + res1 : 6, + polarity : 1, + sense : 1, + res2 : 2, + pri : 4, + res3 : 8, + vec : 8; +}; + +struct mpic_ext_intr { + volatile unsigned int *vp; + volatile unsigned char *dest; +}; + +struct mpic_err_vp { + unsigned int masked : 1, + act : 1, + res3 : 7, + sense : 1, + res2 : 2, + pri : 4, + res1 : 8, + vec : 8; +}; + +#if 1 +struct raven_reg { + struct mpic_feature *feature; + unsigned int *gcr; + struct mpic_vid *vid; + char *p_init; + struct mpic_ipivp *ipi[4]; + char *sp; + unsigned int *timer_freq; + struct mpic_timer timer[4]; + /* external interrupt configuration registers */ + struct mpic_ext_intr extint[16]; + unsigned int *p0_ipi0d; + unsigned int *p0_ipi1d; + unsigned int *p0_ipi2d; + unsigned int *p0_ipi3d; + unsigned int *p1_ipi0d; + unsigned int *p1_ipi1d; + unsigned int *p1_ipi2d; + unsigned int *p1_ipi3d; + /* task priority registers (IPL) */ + unsigned char *tp[2]; + /* interrupt acknowledge registers */ + volatile unsigned char *iack[2]; + /* end of interrupt registers */ + volatile unsigned char *eio[2]; +}; + +#else +struct raven_reg { + struct mpic_feature *feature = (struct mpic_feature *)MPCIC_FEATURE; + struct mpic_gcr *gcr = (struct mpic_gcr *)MPCIC_GCR; + struct mpic_vid *vid = (struct mpic_vid *)MPCIC_VID; + char *p_init = (char *)MPCIC_PINIT; +#if 0 + struct mpic_ipivp *ipi0 = (struct mpic_ipivp *)MPCIC_IPI0; + struct mpic_ipivp *ipi1 = (struct mpic_ipivp *)MPCIC_IPI1; + struct mpic_ipivp *ipi2 = (struct mpic_ipivp *)MPCIC_IPI2; + struct mpic_ipivp *ipi3 = (struct mpic_ipivp *)MPCIC_IPI3; +#else + struct mpic_ipivp *ipi[4] = { + (struct mpic_ipivp *)MPCIC_IPI0, + (struct mpic_ipivp *)MPCIC_IPI1, + (struct mpic_ipivp *)MPCIC_IPI2, + (struct mpic_ipivp *)MPCIC_IPI3, + }; +#endif + char *sp = (char *)MPCIC_SP; + unsigned int *timer_freq = (unsigned int *)MPCIC_TFR; +#if 1 + struct mpic_timer timer[4] = { + {(struct mpic_timer_count *)MPCIC_T0CC, + (struct mpic_timer_bcount *)MPCIC_T0BC, + (struct mpic_timer_vp *)MPCIC_T0VP, + (unsigned char *)MPCIC_T0D}, + {(struct mpic_timer_count *)MPCIC_T1CC, + (struct mpic_timer_bcount *)MPCIC_T1BC, + (struct mpic_timer_vp *)MPCIC_T1VP, + (unsigned char *)MPCIC_T1D}, + {(struct mpic_timer_count *)MPCIC_T2CC, + (struct mpic_timer_bcount *)MPCIC_T2BC, + (struct mpic_timer_vp *)MPCIC_T2VP, + (unsigned char *)MPCIC_T2D}, + {(struct mpic_timer_count *)MPCIC_T3CC, + (struct mpic_timer_bcount *)MPCIC_T3BC, + (struct mpic_timer_vp *)MPCIC_T3VP, + (unsigned char *)MPCIC_T3D} + }; +#else + struct mpic_timer_count *t0c = (struct mpic_timer_count *)MPCIC_T0CC; + struct mpic_timer_bcount *t0bc = (struct mpic_timer_bcount *)MPCIC_T0BC; + struct mpic_timer_vp *t0vp = (struct mpic_timer_vp *)MPCIC_T0VP; + unsigned int *t0d = (unsigned int *)MPCIC_T0D; + struct mpic_timer_count *t1c = (struct mpic_timer_count *)MPCIC_T1CC; + struct mpic_timer_bcount *t1bc = (struct mpic_timer_bcount *)MPCIC_T1BC; + struct mpic_timer_vp *t1vp = (struct mpic_timer_vp *)MPCIC_T1VP; + unsigned int *t1d = (unsigned int *)MPCIC_T1D; + struct mpic_timer_count *t2c = (struct mpic_timer_count *)MPCIC_T2CC; + struct mpic_timer_bcount *t2bc = (struct mpic_timer_bcount *)MPCIC_T2BC; + struct mpic_timer_vp *t2vp = (struct mpic_timer_vp *)MPCIC_T2VP; + unsigned int *t2d = (unsigned int *)MPCIC_T2D; + struct mpic_timer_count *t3c = (struct mpic_timer_count *)MPCIC_T3CC; + struct mpic_timer_bcount *t3bc = (struct mpic_timer_bcount *)MPCIC_T3BC; + struct mpic_timer_vp *t3vp = (struct mpic_timer_vp *)MPCIC_T3VP; + unsigned int *t3d = (unsigned int *)MPCIC_T3D; +#endif + +#if 1 + /* external interrupt configuration registers */ + struct mpic_ext_intr extint[16] = { + {(struct mpic_ext_vp *)MPCIC_INT0VP, (unsigned char *)MPCIC_INT0D}, + {(struct mpic_ext_vp *)MPCIC_INT1VP, (unsigned char *)MPCIC_INT1D}, + {(struct mpic_ext_vp *)MPCIC_INT2VP, (unsigned char *)MPCIC_INT2D}, + {(struct mpic_ext_vp *)MPCIC_INT3VP, (unsigned char *)MPCIC_INT3D}, + {(struct mpic_ext_vp *)MPCIC_INT4VP, (unsigned char *)MPCIC_INT4D}, + {(struct mpic_ext_vp *)MPCIC_INT5VP, (unsigned char *)MPCIC_INT5D}, + {(struct mpic_ext_vp *)MPCIC_INT6VP, (unsigned char *)MPCIC_INT6D}, + {(struct mpic_ext_vp *)MPCIC_INT7VP, (unsigned char *)MPCIC_INT7D}, + {(struct mpic_ext_vp *)MPCIC_INT8VP, (unsigned char *)MPCIC_INT8D}, + {(struct mpic_ext_vp *)MPCIC_INT9VP, (unsigned char *)MPCIC_INT9D}, + {(struct mpic_ext_vp *)MPCIC_INT1VP, (unsigned char *)MPCIC_INT10D}, + {(struct mpic_ext_vp *)MPCIC_INT11VP, (unsigned char *)MPCIC_INT11D}, + {(struct mpic_ext_vp *)MPCIC_INT12VP, (unsigned char *)MPCIC_INT12D}, + {(struct mpic_ext_vp *)MPCIC_INT13VP, (unsigned char *)MPCIC_INT13D}, + {(struct mpic_ext_vp *)MPCIC_INT14VP, (unsigned char *)MPCIC_INT14D}, + {(struct mpic_ext_vp *)MPCIC_INT16VP, (unsigned char *)MPCIC_INT15D} + }; +#else + struct mpic_ext_vp *ext0vp = (struct mpic_ext_vp *)MPCIC_INT0VP; + unsigned int *ext0d = (unsigned int *)MPCIC_INT0D; + struct mpic_ext_vp *ext1vp = (struct mpic_ext_vp *)MPCIC_INT1VP; + unsigned int *ext1d = (unsigned int *)MPCIC_INT1D; + struct mpic_ext_vp *ext2vp = (struct mpic_ext_vp *)MPCIC_INT2VP; + unsigned int *ext2d = (unsigned int *)MPCIC_INT2D; + struct mpic_ext_vp *ext3vp = (struct mpic_ext_vp *)MPCIC_INT3VP; + unsigned int *ext3d = (unsigned int *)MPCIC_INT3D; + struct mpic_ext_vp *ext4vp = (struct mpic_ext_vp *)MPCIC_INT4VP; + unsigned int *ext4d = (unsigned int *)MPCIC_INT4D; + struct mpic_ext_vp *ext5vp = (struct mpic_ext_vp *)MPCIC_INT5VP; + unsigned int *ext5d = (unsigned int *)MPCIC_INT5D; + struct mpic_ext_vp *ext6vp = (struct mpic_ext_vp *)MPCIC_INT6VP; + unsigned int *ext6d = (unsigned int *)MPCIC_INT6D; + struct mpic_ext_vp *ext7vp = (struct mpic_ext_vp *)MPCIC_INT7VP; + unsigned int *ext7d = (unsigned int *)MPCIC_INT7D; + struct mpic_ext_vp *ext8vp = (struct mpic_ext_vp *)MPCIC_INT8VP; + unsigned int *ext8d = (unsigned int *)MPCIC_INT8D; + struct mpic_ext_vp *ext9vp = (struct mpic_ext_vp *)MPCIC_INT9VP; + unsigned int *ext9d = (unsigned int *)MPCIC_INT9D; + struct mpic_ext_vp *ext10vp = (struct mpic_ext_vp *)MPCIC_INT10VP; + unsigned int *ext10d = (unsigned int *)MPCIC_INT10D; + struct mpic_ext_vp *ext11vp = (struct mpic_ext_vp *)MPCIC_INT11VP; + unsigned int *ext11d = (unsigned int *)MPCIC_INT11D; + struct mpic_ext_vp *ext12vp = (struct mpic_ext_vp *)MPCIC_INT12VP; + unsigned int *ext12d = (unsigned int *)MPCIC_INT12D; + struct mpic_ext_vp *ext13vp = (struct mpic_ext_vp *)MPCIC_INT13VP; + unsigned int *ext13d = (unsigned int *)MPCIC_INT13D; + struct mpic_ext_vp *ext14vp = (struct mpic_ext_vp *)MPCIC_INT14VP; + unsigned int *ext14d = (unsigned int *)MPCIC_INT14D; + struct mpic_ext_vp *ext15vp = (struct mpic_ext_vp *)MPCIC_INT15VP; + unsigned int *ext15d = (unsigned int *)MPCIC_INT15D; + struct mpic_err_vp *errvp = (struct mpic_err_vp *)MPCIC_EVP; + unsigned int *errd = (unsigned int *)MPCIC_ED; +#endif + unsigned int *p0_ipi0d = (unsigned int *)MPCIC_P0_IPI0_D; + unsigned int *p0_ipi1d = (unsigned int *)MPCIC_P0_IPI1_D; + unsigned int *p0_ipi2d = (unsigned int *)MPCIC_P0_IPI2_D; + unsigned int *p0_ipi3d = (unsigned int *)MPCIC_P0_IPI3_D; + unsigned int *p1_ipi0d = (unsigned int *)MPCIC_P1_IPI0_D; + unsigned int *p1_ipi1d = (unsigned int *)MPCIC_P1_IPI1_D; + unsigned int *p1_ipi2d = (unsigned int *)MPCIC_P1_IPI2_D; + unsigned int *p1_ipi3d = (unsigned int *)MPCIC_P1_IPI3_D; + + /* task priority registers (IPL) */ + unsigned char *tp[2] = { + (unsigned char *)MPCIC_P0_TP, + (unsigned char *)MPCIC_P1_TP + }; + /* interrupt acknowledge registers */ + volatile unsigned char *iack[2] = { + (volatile unsigned char *)MPCIC_P0_IACK, + (volatile unsigned char *)MPCIC_P1_IACK + }; + /* end of interrupt registers */ + volatile unsigned char *eio[2] = { + (volatile unsigned char *)MPCIC_P0_EOI, + (volatile unsigned char *)MPCIC_P1_EOI, + }; +} +#endif + +struct raven_softc { + struct device sc_dev; + struct raven_reg *sc_reg; +}; + + +#endif /* _DEV_RAVENVAR_H_ */ diff --git a/sys/arch/mvmeppc/include/ansi.h b/sys/arch/mvmeppc/include/ansi.h new file mode 100644 index 00000000000..ba1e0b55b98 --- /dev/null +++ b/sys/arch/mvmeppc/include/ansi.h @@ -0,0 +1,84 @@ +/* $OpenBSD: ansi.h,v 1.1 2001/06/26 21:57:42 smurph Exp $ */ +/* $NetBSD: ansi.h,v 1.2 1996/11/15 22:38:57 jtc 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. 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, Berkeley and its contributors. + * 4. 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 _ANSI_H_ +#define _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_ unsigned long /* clock() */ +#define _BSD_PTRDIFF_T_ int /* ptr1 - ptr2 */ +#define _BSD_SIZE_T_ unsigned int /* sizeof() */ +#define _BSD_SSIZE_T_ int /* byte count or error */ +#define _BSD_TIME_T_ int /* time() */ +struct __va_list_tag; +#define _BSD_VA_LIST_ struct __va_list_tag * /* 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_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 /* _ANSI_H_ */ diff --git a/sys/arch/mvmeppc/include/asm.h b/sys/arch/mvmeppc/include/asm.h new file mode 100644 index 00000000000..ed098b5a24e --- /dev/null +++ b/sys/arch/mvmeppc/include/asm.h @@ -0,0 +1,106 @@ +/* $OpenBSD: asm.h,v 1.1 2001/06/26 21:57:42 smurph Exp $ */ +/* $NetBSD: asm.h,v 1.1 1996/09/30 16:34:20 ws Exp $ */ + +/* + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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 _PPC_ASM_H_ +#define _PPC_ASM_H_ + +/* XXX */ +#define TARGET_ELF + +#ifdef PIC +#define PIC_PROLOGUE XXX +#define PIC_EPILOGUE XXX +#ifdef __STDC__ +#define PIC_PLT(x) x ## @plt +#define PIC_GOT(x) XXX +#define PIC_GOTOFF(x) XXX +#else /* not __STDC__ */ +#define PIC_PLT(x) x/**/@plt +#define PIC_GOT(x) XXX +#define PIC_GOTOFF(x) XXX +#endif /* __STDC__ */ +#else +#define PIC_PROLOGUE +#define PIC_EPILOGUE +#define PIC_PLT(x) x +#define PIC_GOT(x) x +#define PIC_GOTOFF(x) x +#endif + +#ifdef TARGET_AOUT +#ifdef __STDC__ +# define _C_LABEL(x) _ ## x +#else +# define _C_LABEL(x) _/**/x +#endif +#endif + +#ifdef TARGET_ELF +# define _C_LABEL(x) x +#endif +#define _ASM_LABEL(x) x + +#ifdef __STDC__ +# define _TMP_LABEL(x) .L_ ## x +#else +# define _TMP_LABEL(x) .L_/**/x +#endif + +#define _ENTRY(x) \ + .text; .align 2; .globl x; .type x,@function; x: + +#ifdef PROF +# define _PROF_PROLOGUE(y) \ + .section ".data"; \ + .align 2; \ +_TMP_LABEL(y):; \ + .long 0; \ + .section ".text"; \ + mflr 0; \ + addis 11, 11, _TMP_LABEL(y)@ha; \ + stw 0, 4(1); \ + addi 0, 11,_TMP_LABEL(y)@l; \ + bl _mcount; +#else +# define _PROF_PROLOGUE(y) +#endif + +#define ENTRY(y) _ENTRY(_C_LABEL(y)); _PROF_PROLOGUE(y) +#define ASENTRY(y) _ENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE(y) + +#define ASMSTR .asciz + +#define RCSID(x) .text; .asciz x + +#endif /* !_PPC_ASM_H_ */ diff --git a/sys/arch/mvmeppc/include/autoconf.h b/sys/arch/mvmeppc/include/autoconf.h new file mode 100644 index 00000000000..d23d3cc9f0e --- /dev/null +++ b/sys/arch/mvmeppc/include/autoconf.h @@ -0,0 +1,103 @@ +/* $OpenBSD: autoconf.h,v 1.1 2001/06/26 21:57:43 smurph Exp $ */ + +/* + * Copyright (c) 1997 Per Fogelstrom + * + * 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 under OpenBSD for RTMX inc + * by Per Fogelstrom, Opsycon AB. + * 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. + * + */ +/* + * Machine-dependent structures of autoconfiguration + */ + +#ifndef _MACHINE_AUTOCONF_H_ +#define _MACHINE_AUTOCONF_H_ + +#include <machine/bus.h> + +/* + * System types. + */ +#define OFWMACH 0 /* Openfirmware drivers */ +#define POWER4e 1 /* V.I Power.4e board */ +#define PWRSTK 2 /* Motorola Powerstack series */ +#define APPL 3 /* Apple PowerMac machines (OFW?) */ +#define MVME 4 /* Motorola MVME SBCs */ + +extern int system_type; + +/**/ +struct confargs; + +typedef int (*intr_handler_t) __P((void *)); + +typedef struct bushook { + struct device *bh_dv; + int bh_type; + void (*bh_intr_establish) + __P((struct confargs *, intr_handler_t, void *)); + void (*bh_intr_disestablish) + __P((struct confargs *)); + int (*bh_matchname) + __P((struct confargs *, char *)); +} bushook_t; + +#define BUS_MAIN 1 /* mainbus */ +#define BUS_ISABR 2 /* ISA Bridge Bus */ +#define BUS_PCIBR 3 /* PCI bridge */ +#define BUS_VMEBR 4 /* VME bridge */ + +#define BUS_INTR_ESTABLISH(ca, handler, val) \ + (*(ca)->ca_bus->bh_intr_establish)((ca), (handler), (val)) +#define BUS_INTR_DISESTABLISH(ca) \ + (*(ca)->ca_bus->bh_intr_establish)(ca) +#define BUS_CVTADDR(ca) \ + (*(ca)->ca_bus->bh_cvtaddr)(ca) +#define BUS_MATCHNAME(ca, name) \ + (*(ca)->ca_bus->bh_matchname)((ca), (name)) + +struct confargs { + char *ca_name; /* Device name. */ + bushook_t *ca_bus; /* bus device resides on. */ + /* macobio hooks ?? */ + bus_space_tag_t ca_iot; + bus_space_tag_t ca_memt; /* XXX */ + u_int32_t ca_node; + int ca_nreg; + u_int32_t *ca_reg; + int ca_nintr; + int32_t *ca_intr; + u_int ca_baseaddr; + +}; + +void set_clockintr __P((void (*)(struct clockframe *))); +void set_iointr __P((void (*)(void *, int))); +int badaddr __P((void *, u_int32_t)); + +#endif /* _MACHINE_AUTOCONF_H_ */ diff --git a/sys/arch/mvmeppc/include/bat.h b/sys/arch/mvmeppc/include/bat.h new file mode 100644 index 00000000000..b2938749e9f --- /dev/null +++ b/sys/arch/mvmeppc/include/bat.h @@ -0,0 +1,54 @@ +/* $OpenBSD: bat.h,v 1.1 2001/06/26 21:57:43 smurph Exp $ */ + +/* + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_BAT_H_ +#define _MACHINE_BAT_H_ + +struct bat { + u_int32_t batu; + u_int32_t batl; +}; + +#define BATU(vaddr) (((vaddr)&0xf0000000)|0x1ffe) +#define BATL(raddr,wimg) (((raddr)&0xf0000000)|(wimg)|0x2) + +#define BAT_W 0x40 +#define BAT_I 0x20 +#define BAT_M 0x10 +#define BAT_G 0x08 + +#ifdef _KERNEL +extern struct bat battable[16]; +#endif + +#endif /* _MACHINE_BAT_H_ */ diff --git a/sys/arch/mvmeppc/include/bus.h b/sys/arch/mvmeppc/include/bus.h new file mode 100644 index 00000000000..454930f24a1 --- /dev/null +++ b/sys/arch/mvmeppc/include/bus.h @@ -0,0 +1,128 @@ +/* $NetBSD: bus.h,v 1.6 2001/06/15 15:50:05 nonaka Exp $ */ +/* $OpenBSD: bus.h,v 1.1 2001/06/26 21:57:43 smurph Exp $ */ + +/*- + * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center. + * + * 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. + */ + +/* + * Copyright (c) 1996 Charles M. Hannum. All rights reserved. + * Copyright (c) 1996 Jason R. Thorpe. All rights reserved. + * Copyright (c) 1996 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 + * for the NetBSD Project. + * 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. + */ + +/* + * Copyright (c) 1997 Per Fogelstrom. All rights reserved. + * Copyright (c) 1996 Niklas Hallqvist. 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 + * for the NetBSD Project. + * 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 _PREP_BUS_H_ +#define _PREP_BUS_H_ + +#define _POWERPC_BUS_DMA_PRIVATE +#include <machine/bus_mi.h> + +/* + * Values for the Be bus space tag, not to be used directly by MI code. + */ +#define PREP_BUS_SPACE_IO 0x80000000 /* i/o space */ +#define PREP_BUS_SPACE_MEM 0xC0000000 /* mem space */ + +/* + * Address conversion as seen from a PCI master. + */ +#define MPC105_DIRECT_MAPPED_SPACE 0x80000000 +#define PHYS_TO_PCI_MEM(x) ((x) | MPC105_DIRECT_MAPPED_SPACE) +#define PCI_MEM_TO_PHYS(x) ((x) & ~MPC105_DIRECT_MAPPED_SPACE) + +extern const struct ppc_bus_space prep_io_space_tag; +extern const struct ppc_bus_space prep_isa_io_space_tag; +extern const struct ppc_bus_space prep_mem_space_tag; +extern const struct ppc_bus_space prep_isa_mem_space_tag; + +#endif /* _PREP_BUS_H_ */ diff --git a/sys/arch/mvmeppc/include/bus_mi.h b/sys/arch/mvmeppc/include/bus_mi.h new file mode 100644 index 00000000000..b7ec2089081 --- /dev/null +++ b/sys/arch/mvmeppc/include/bus_mi.h @@ -0,0 +1,1146 @@ +/* $NetBSD: bus.h,v 1.1 2001/06/06 17:37:37 matt Exp $ */ +/* $OpenBSD: bus_mi.h,v 1.1 2001/06/26 21:57:43 smurph Exp $ */ + +/*- + * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center. + * + * 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. + */ + +/* + * Copyright (c) 1996 Charles M. Hannum. All rights reserved. + * Copyright (c) 1996 Jason R. Thorpe. All rights reserved. + * Copyright (c) 1996 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 + * for the NetBSD Project. + * 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. + */ + +/* + * Copyright (c) 1997 Per Fogelstrom. All rights reserved. + * Copyright (c) 1996 Niklas Hallqvist. 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 + * for the NetBSD Project. + * 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 _POWERPC_BUS_H_ +#define _POWERPC_BUS_H_ + +#include <machine/pio.h> + +typedef enum { + BUS_DMASYNC_POSTREAD, + BUS_DMASYNC_POSTWRITE, + BUS_DMASYNC_PREREAD, + BUS_DMASYNC_PREWRITE +} bus_dmasync_op_t; + +/* + * Bus access types. + */ +typedef u_int32_t bus_addr_t; +typedef u_int32_t bus_size_t; +typedef u_int32_t bus_space_handle_t; +typedef const struct ppc_bus_space *bus_space_tag_t; + +struct ppc_bus_space { + u_int32_t pbs_type; + bus_addr_t pbs_offset; + bus_addr_t pbs_base; + bus_addr_t pbs_limit; + int (*pbs_map) __P((bus_space_tag_t, bus_addr_t, bus_size_t, int, + bus_space_handle_t *)); + void (*pbs_unmap) __P((bus_space_tag_t, bus_space_handle_t, + bus_size_t)); + int (*pbs_alloc) __P((bus_space_tag_t, bus_addr_t, bus_addr_t, + bus_size_t, bus_size_t align, bus_size_t, int, bus_addr_t *, + bus_space_handle_t *)); + void (*pbs_free) __P((bus_space_tag_t, bus_space_handle_t, bus_size_t)); +}; + +#define BUS_SPACE_MAP_CACHEABLE 0x01 +#define BUS_SPACE_MAP_LINEAR 0x02 +#define BUS_SPACE_MAP_PREFETCHABLE 0x04 + +#ifdef __STDC__ +#define CAT(a,b) a##b +#define CAT3(a,b,c) a##b##c +#else +#define CAT(a,b) a/**/b +#define CAT3(a,b,c) a/**/b/**/c +#endif + +/* + * Access methods for bus resources + */ + +#define __BUS_SPACE_HAS_STREAM_METHODS + +/* + * int bus_space_map __P((bus_space_tag_t t, bus_addr_t addr, + * bus_size_t size, int flags, bus_space_handle_t *bshp)); + * + * Map a region of bus space. + */ + +#define bus_space_map(t, a, s, f, hp) \ + ((*(t)->pbs_map)((t), (a), (s), (f), (hp))) + +/* + * int bus_space_unmap __P((bus_space_tag_t t, + * bus_space_handle_t bsh, bus_size_t size)); + * + * Unmap a region of bus space. + */ + +#define bus_space_unmap(t, h, s) \ + ((void)(*(t)->pbs_unmap)((t), (h), (s))) + +/* + * int bus_space_subregion __P((bus_space_tag_t t, + * bus_space_handle_t bsh, bus_size_t offset, bus_size_t size, + * bus_space_handle_t *nbshp)); + * + * Get a new handle for a subregion of an already-mapped area of bus space. + */ + +#define bus_space_subregion(t, h, o, s, hp) \ + ((*(hp) = (h) + (o)), 0) + +/* + * int bus_space_alloc __P((bus_space_tag_t t, 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 *bpap, + * bus_space_handle_t *bshp)); + * + * Allocate a region of bus space. + */ + +#define bus_space_alloc(t, rs, re, s, a, b, f, ap, hp) \ + ((*(t)->pbs_alloc)((t), (rs), (re), (s), (a), (b), (f), (ap), (hp))) + +/* + * int bus_space_free __P((bus_space_tag_t t, + * bus_space_handle_t bsh, bus_size_t size)); + * + * Free a region of bus space. + */ + +#define bus_space_free(t, h, s) \ + ((void)(*(t)->pbs_free)((t), (h), (s))) + +/* + * u_intN_t bus_space_read_N __P((bus_space_tag_t tag, + * bus_space_handle_t bsh, bus_size_t offset)); + * + * Read a 1, 2, 4, or 8 byte quantity from bus space + * described by tag/handle/offset. + */ + +#define bus_space_read(n,m) \ +static __inline CAT3(u_int,m,_t) \ +CAT(bus_space_read_,n)(bus_space_tag_t tag, bus_space_handle_t bsh, \ + bus_size_t offset) \ +{ \ + return CAT3(in,m,rb)((volatile CAT3(u_int,m,_t) *)(bsh + (offset))); \ +} + +bus_space_read(1,8) +bus_space_read(2,16) +bus_space_read(4,32) +#define bus_space_read_8 !!! bus_space_read_8 unimplemented !!! + +/* + * u_intN_t bus_space_read_stream_N __P((bus_space_tag_t tag, + * bus_space_handle_t bsh, bus_size_t offset)); + * + * Read a 2, 4, or 8 byte stream quantity from bus space + * described by tag/handle/offset. + */ + +#define bus_space_read_stream(n,m) \ +static __inline CAT3(u_int,m,_t) \ +CAT(bus_space_read_stream_,n)(bus_space_tag_t tag, bus_space_handle_t bsh, \ + bus_size_t offset) \ +{ \ + return CAT(in,m)((volatile CAT3(u_int,m,_t) *)(bsh + (offset))); \ +} + +bus_space_read_stream(2,16) +bus_space_read_stream(4,32) +#define bus_space_read_stream_8 !!! bus_space_read_stream_8 unimplemented !!! + +/* + * void bus_space_read_multi_N __P((bus_space_tag_t tag, + * bus_space_handle_t bsh, bus_size_t offset, + * u_intN_t *addr, size_t count)); + * + * Read `count' 1, 2, 4, or 8 byte quantities from bus space + * described by tag/handle/offset and copy into buffer provided. + */ + +#define bus_space_read_multi(n,m) \ +static __inline void \ +CAT(bus_space_read_multi_,n)(bus_space_tag_t tag, bus_space_handle_t bsh, \ + bus_size_t offset, CAT3(u_int,m,_t) *addr, size_t count) \ +{ \ + CAT3(ins,m,rb)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)), \ + (CAT3(u_int,m,_t) *)addr, (size_t)count); \ +} + +bus_space_read_multi(1,8) +bus_space_read_multi(2,16) +bus_space_read_multi(4,32) +#define bus_space_read_multi_8 !!! bus_space_read_multi_8 not implemented !!! + +/* + * void bus_space_read_multi_stream_N __P((bus_space_tag_t tag, + * bus_space_handle_t bsh, bus_size_t offset, + * u_intN_t *addr, size_t count)); + * + * Read `count' 2, 4, or 8 byte stream quantities from bus space + * described by tag/handle/offset and copy into buffer provided. + */ + +#define bus_space_read_multi_stream(n,m) \ +static __inline void \ +CAT(bus_space_read_multi_stream_,n)(bus_space_tag_t tag, \ + bus_space_handle_t bsh, \ + bus_size_t offset, CAT3(u_int,m,_t) *addr, size_t count) \ +{ \ + CAT(ins,m)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)), \ + (CAT3(u_int,m,_t) *)addr, (size_t)count); \ +} + +bus_space_read_multi_stream(2,16) +bus_space_read_multi_stream(4,32) +#define bus_space_read_multi_stream_8 \ + !!! bus_space_read_multi_stream_8 not implemented !!! + +/* + * void bus_space_write_N __P((bus_space_tag_t tag, + * bus_space_handle_t bsh, bus_size_t offset, + * u_intN_t value)); + * + * Write the 1, 2, 4, or 8 byte value `value' to bus space + * described by tag/handle/offset. + */ + +#define bus_space_write(n,m) \ +static __inline void \ +CAT(bus_space_write_,n)(bus_space_tag_t tag, bus_space_handle_t bsh, \ + bus_size_t offset, CAT3(u_int,m,_t) x) \ +{ \ + CAT3(out,m,rb)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)), x); \ +} + +bus_space_write(1,8) +bus_space_write(2,16) +bus_space_write(4,32) +#define bus_space_write_8 !!! bus_space_write_8 unimplemented !!! + +/* + * void bus_space_write_stream_N __P((bus_space_tag_t tag, + * bus_space_handle_t bsh, bus_size_t offset, + * u_intN_t value)); + * + * Write the 2, 4, or 8 byte stream value `value' to bus space + * described by tag/handle/offset. + */ + +#define bus_space_write_stream(n,m) \ +static __inline void \ +CAT(bus_space_write_stream_,n)(bus_space_tag_t tag, bus_space_handle_t bsh, \ + bus_size_t offset, CAT3(u_int,m,_t) x) \ +{ \ + CAT(out,m)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)), x); \ +} + +bus_space_write_stream(2,16) +bus_space_write_stream(4,32) +#define bus_space_write_stream_8 !!! bus_space_write_stream_8 unimplemented !!! + +/* + * void bus_space_write_multi_N __P((bus_space_tag_t tag, + * bus_space_handle_t bsh, bus_size_t offset, + * const u_intN_t *addr, size_t count)); + * + * Write `count' 1, 2, 4, or 8 byte quantities from the buffer + * provided to bus space described by tag/handle/offset. + */ + +#define bus_space_write_multi(n,m) \ +static __inline void \ +CAT(bus_space_write_multi_,n)(bus_space_tag_t tag, bus_space_handle_t bsh, \ + bus_size_t offset, const CAT3(u_int,m,_t) *addr, size_t count) \ +{ \ + CAT3(outs,m,rb)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)), \ + (CAT3(u_int,m,_t) *)addr, (size_t)count); \ +} + +bus_space_write_multi(1,8) +bus_space_write_multi(2,16) +bus_space_write_multi(4,32) +#define bus_space_write_multi_8 !!! bus_space_write_multi_8 not implemented !!! + +/* + * void bus_space_write_multi_stream_N __P((bus_space_tag_t tag, + * bus_space_handle_t bsh, bus_size_t offset, + * const u_intN_t *addr, size_t count)); + * + * Write `count' 2, 4, or 8 byte stream quantities from the buffer + * provided to bus space described by tag/handle/offset. + */ + +#define bus_space_write_multi_stream(n,m) \ +static __inline void \ +CAT(bus_space_write_multi_stream_,n)(bus_space_tag_t tag, \ + bus_space_handle_t bsh, \ + bus_size_t offset, const CAT3(u_int,m,_t) *addr, size_t count) \ +{ \ + CAT(outs,m)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)), \ + (CAT3(u_int,m,_t) *)addr, (size_t)count); \ +} + +bus_space_write_multi_stream(2,16) +bus_space_write_multi_stream(4,32) +#define bus_space_write_multi_stream_8 \ + !!! bus_space_write_multi_stream_8 not implemented !!! + +/* + * void bus_space_read_region_N __P((bus_space_tag_t tag, + * bus_space_handle_t bsh, bus_size_t offset, + * u_intN_t *addr, size_t count)); + * + * Read `count' 1, 2, 4, or 8 byte quantities from bus space + * described by tag/handle and starting at `offset' and copy into + * buffer provided. + */ +static __inline void bus_space_read_region_1 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int8_t *, size_t)); +static __inline void bus_space_read_region_2 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int16_t *, size_t)); +static __inline void bus_space_read_region_4 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int32_t *, size_t)); + +static __inline void +bus_space_read_region_1(tag, bsh, offset, addr, count) + bus_space_tag_t tag; + bus_space_handle_t bsh; + bus_size_t offset; + u_int8_t *addr; + size_t count; +{ + volatile u_int8_t *s; + + s = (volatile u_int8_t *)(bsh + offset); + while (count--) + *addr++ = *s++; + __asm__ volatile("eieio; sync"); +} + +static __inline void +bus_space_read_region_2(tag, bsh, offset, addr, count) + bus_space_tag_t tag; + bus_space_handle_t bsh; + bus_size_t offset; + u_int16_t *addr; + size_t count; +{ + volatile u_int16_t *s; + + s = (volatile u_int16_t *)(bsh + offset); + while (count--) + __asm__ volatile("lhbrx %0, 0, %1" : + "=r"(*addr++) : "r"(s++)); + __asm__ volatile("eieio; sync"); +} + +static __inline void +bus_space_read_region_4(tag, bsh, offset, addr, count) + bus_space_tag_t tag; + bus_space_handle_t bsh; + bus_size_t offset; + u_int32_t *addr; + size_t count; +{ + volatile u_int32_t *s; + + s = (volatile u_int32_t *)(bsh + offset); + while (count--) + __asm__ volatile("lwbrx %0, 0, %1" : + "=r"(*addr++) : "r"(s++)); + __asm__ volatile("eieio; sync"); +} + +#define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!! + +/* + * void bus_space_read_region_stream_N __P((bus_space_tag_t tag, + * bus_space_handle_t bsh, bus_size_t offset, + * u_intN_t *addr, size_t count)); + * + * Read `count' 2, 4, or 8 byte stream quantities from bus space + * described by tag/handle and starting at `offset' and copy into + * buffer provided. + */ +static __inline void bus_space_read_region_stream_2 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int16_t *, size_t)); +static __inline void bus_space_read_region_stream_4 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int32_t *, size_t)); + +static __inline void +bus_space_read_region_stream_2(tag, bsh, offset, addr, count) + bus_space_tag_t tag; + bus_space_handle_t bsh; + bus_size_t offset; + u_int16_t *addr; + size_t count; +{ + volatile u_int16_t *s; + + s = (volatile u_int16_t *)(bsh + offset); + while (count--) + *addr++ = *s++; + __asm__ volatile("eieio; sync"); +} + +static __inline void +bus_space_read_region_stream_4(tag, bsh, offset, addr, count) + bus_space_tag_t tag; + bus_space_handle_t bsh; + bus_size_t offset; + u_int32_t *addr; + size_t count; +{ + volatile u_int32_t *s; + + s = (volatile u_int32_t *)(bsh + offset); + while (count--) + *addr++ = *s++; + __asm__ volatile("eieio; sync"); +} + +#define bus_space_read_region_stream_8 \ + !!! bus_space_read_region_stream_8 unimplemented !!! + +/* + * void bus_space_write_region_N __P((bus_space_tag_t tag, + * bus_space_handle_t bsh, bus_size_t offset, + * const u_intN_t *addr, size_t count)); + * + * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided + * to bus space described by tag/handle starting at `offset'. + */ +static __inline void bus_space_write_region_1 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, const u_int8_t *, size_t)); +static __inline void bus_space_write_region_2 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, const u_int16_t *, size_t)); +static __inline void bus_space_write_region_4 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, const u_int32_t *, size_t)); + +static __inline void +bus_space_write_region_1(tag, bsh, offset, addr, count) + bus_space_tag_t tag; + bus_space_handle_t bsh; + bus_size_t offset; + const u_int8_t *addr; + size_t count; +{ + volatile u_int8_t *d; + + d = (volatile u_int8_t *)(bsh + offset); + while (count--) + *d++ = *addr++; + __asm__ volatile("eieio; sync"); +} + +static __inline void +bus_space_write_region_2(tag, bsh, offset, addr, count) + bus_space_tag_t tag; + bus_space_handle_t bsh; + bus_size_t offset; + const u_int16_t *addr; + size_t count; +{ + volatile u_int16_t *d; + + d = (volatile u_int16_t *)(bsh + offset); + while (count--) + __asm__ volatile("sthbrx %0, 0, %1" :: + "r"(*addr++), "r"(d++)); + __asm__ volatile("eieio; sync"); +} + +static __inline void +bus_space_write_region_4(tag, bsh, offset, addr, count) + bus_space_tag_t tag; + bus_space_handle_t bsh; + bus_size_t offset; + const u_int32_t *addr; + size_t count; +{ + volatile u_int32_t *d; + + d = (volatile u_int32_t *)(bsh + offset); + while (count--) + __asm__ volatile("stwbrx %0, 0, %1" :: + "r"(*addr++), "r"(d++)); + __asm__ volatile("eieio; sync"); +} + +#define bus_space_write_region_8 !!! bus_space_write_region_8 unimplemented !!! + +/* + * void bus_space_write_region_stream_N __P((bus_space_tag_t tag, + * bus_space_handle_t bsh, bus_size_t offset, + * const u_intN_t *addr, size_t count)); + * + * Write `count' 2, 4, or 8 byte stream quantities from the buffer provided + * to bus space described by tag/handle starting at `offset'. + */ +static __inline void bus_space_write_region_stream_2 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, const u_int16_t *, size_t)); +static __inline void bus_space_write_region_stream_4 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, const u_int32_t *, size_t)); + +static __inline void +bus_space_write_region_stream_2(tag, bsh, offset, addr, count) + bus_space_tag_t tag; + bus_space_handle_t bsh; + bus_size_t offset; + const u_int16_t *addr; + size_t count; +{ + volatile u_int16_t *d; + + d = (volatile u_int16_t *)(bsh + offset); + while (count--) + *d++ = *addr++; + __asm__ volatile("eieio; sync"); +} + +static __inline void +bus_space_write_region_stream_4(tag, bsh, offset, addr, count) + bus_space_tag_t tag; + bus_space_handle_t bsh; + bus_size_t offset; + const u_int32_t *addr; + size_t count; +{ + volatile u_int32_t *d; + + d = (volatile u_int32_t *)(bsh + offset); + while (count--) + *d++ = *addr++; + __asm__ volatile("eieio; sync"); +} + +#define bus_space_write_region_stream_8 \ + !!! bus_space_write_region_stream_8 unimplemented !!! + +/* + * void bus_space_set_multi_N __P((bus_space_tag_t tag, + * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, + * size_t count)); + * + * Write the 1, 2, 4, or 8 byte value `val' to bus space described + * by tag/handle/offset `count' times. + */ +static __inline void bus_space_set_multi_1 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int8_t, size_t)); +static __inline void bus_space_set_multi_2 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int16_t, size_t)); +static __inline void bus_space_set_multi_4 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int32_t, size_t)); + +static __inline void +bus_space_set_multi_1(tag, bsh, offset, val, count) + bus_space_tag_t tag; + bus_space_handle_t bsh; + bus_size_t offset; + u_int8_t val; + size_t count; +{ + volatile u_int8_t *d; + + d = (volatile u_int8_t *)(bsh + offset); + while (count--) + *d = val; + __asm__ volatile("eieio; sync"); +} + +static __inline void +bus_space_set_multi_2(tag, bsh, offset, val, count) + bus_space_tag_t tag; + bus_space_handle_t bsh; + bus_size_t offset; + u_int16_t val; + size_t count; +{ + volatile u_int16_t *d; + + d = (volatile u_int16_t *)(bsh + offset); + while (count--) + __asm__ volatile("sthbrx %0, 0, %1" :: + "r"(val), "r"(d)); + __asm__ volatile("eieio; sync"); +} + +static __inline void +bus_space_set_multi_4(tag, bsh, offset, val, count) + bus_space_tag_t tag; + bus_space_handle_t bsh; + bus_size_t offset; + u_int32_t val; + size_t count; +{ + volatile u_int32_t *d; + + d = (volatile u_int32_t *)(bsh + offset); + while (count--) + __asm__ volatile("stwbrx %0, 0, %1" :: + "r"(val), "r"(d)); + __asm__ volatile("eieio; sync"); +} + +#define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!! + +/* + * void bus_space_set_multi_stream_N __P((bus_space_tag_t tag, + * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, + * size_t count)); + * + * Write the 2, 4, or 8 byte stream value `val' to bus space described + * by tag/handle/offset `count' times. + */ +static __inline void bus_space_set_multi_stream_2 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int16_t, size_t)); +static __inline void bus_space_set_multi_stream_4 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int32_t, size_t)); + +static __inline void +bus_space_set_multi_stream_2(tag, bsh, offset, val, count) + bus_space_tag_t tag; + bus_space_handle_t bsh; + bus_size_t offset; + u_int16_t val; + size_t count; +{ + volatile u_int16_t *d; + + d = (volatile u_int16_t *)(bsh + offset); + while (count--) + *d = val; + __asm__ volatile("eieio; sync"); +} + +static __inline void +bus_space_set_multi_stream_4(tag, bsh, offset, val, count) + bus_space_tag_t tag; + bus_space_handle_t bsh; + bus_size_t offset; + u_int32_t val; + size_t count; +{ + volatile u_int32_t *d; + + d = (volatile u_int32_t *)(bsh + offset); + while (count--) + *d = val; + __asm__ volatile("eieio; sync"); +} + +#define bus_space_set_multi_stream_8 \ + !!! bus_space_set_multi_stream_8 unimplemented !!! + +/* + * void bus_space_set_region_N __P((bus_space_tag_t tag, + * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, + * size_t count)); + * + * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described + * by tag/handle starting at `offset'. + */ +static __inline void bus_space_set_region_1 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int8_t, size_t)); +static __inline void bus_space_set_region_2 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int16_t, size_t)); +static __inline void bus_space_set_region_4 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int32_t, size_t)); + +static __inline void +bus_space_set_region_1(tag, bsh, offset, val, count) + bus_space_tag_t tag; + bus_space_handle_t bsh; + bus_size_t offset; + u_int8_t val; + size_t count; +{ + volatile u_int8_t *d; + + d = (volatile u_int8_t *)(bsh + offset); + while (count--) + *d++ = val; + __asm__ volatile("eieio; sync"); +} + +static __inline void +bus_space_set_region_2(tag, bsh, offset, val, count) + bus_space_tag_t tag; + bus_space_handle_t bsh; + bus_size_t offset; + u_int16_t val; + size_t count; +{ + volatile u_int16_t *d; + + d = (volatile u_int16_t *)(bsh + offset); + while (count--) + __asm__ volatile("sthbrx %0, 0, %1" :: + "r"(val), "r"(d++)); + __asm__ volatile("eieio; sync"); +} + +static __inline void +bus_space_set_region_4(tag, bsh, offset, val, count) + bus_space_tag_t tag; + bus_space_handle_t bsh; + bus_size_t offset; + u_int32_t val; + size_t count; +{ + volatile u_int32_t *d; + + d = (volatile u_int32_t *)(bsh + offset); + while (count--) + __asm__ volatile("stwbrx %0, 0, %1" :: + "r"(val), "r"(d++)); + __asm__ volatile("eieio; sync"); +} + +#define bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!! + +/* + * void bus_space_set_region_stream_N __P((bus_space_tag_t tag, + * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val, + * size_t count)); + * + * Write `count' 2, 4, or 8 byte stream value `val' to bus space described + * by tag/handle starting at `offset'. + */ +static __inline void bus_space_set_region_stream_2 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int16_t, size_t)); +static __inline void bus_space_set_region_stream_4 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, u_int32_t, size_t)); + + +static __inline void +bus_space_set_region_stream_2(tag, bsh, offset, val, count) + bus_space_tag_t tag; + bus_space_handle_t bsh; + bus_size_t offset; + u_int16_t val; + size_t count; +{ + volatile u_int16_t *d; + + d = (volatile u_int16_t *)(bsh + offset); + while (count--) + *d++ = val; + __asm__ volatile("eieio; sync"); +} + +static __inline void +bus_space_set_region_stream_4(tag, bsh, offset, val, count) + bus_space_tag_t tag; + bus_space_handle_t bsh; + bus_size_t offset; + u_int32_t val; + size_t count; +{ + volatile u_int32_t *d; + + d = (volatile u_int32_t *)(bsh + offset); + while (count--) + *d++ = val; + __asm__ volatile("eieio; sync"); +} + +#define bus_space_set_region_stream_8 \ + !!! bus_space_set_region_stream_8 unimplemented !!! + +/* + * void bus_space_copy_region_N __P((bus_space_tag_t tag, + * bus_space_handle_t bsh1, bus_size_t off1, + * bus_space_handle_t bsh2, bus_size_t off2, + * size_t count)); + * + * Copy `count' 1, 2, 4, or 8 byte values from bus space starting + * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. + */ + +static __inline void bus_space_copy_region_1 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, bus_space_handle_t, + bus_size_t, size_t)); +static __inline void bus_space_copy_region_2 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, bus_space_handle_t, + bus_size_t, size_t)); +static __inline void bus_space_copy_region_4 __P((bus_space_tag_t, + bus_space_handle_t, bus_size_t, bus_space_handle_t, + bus_size_t, size_t)); + +static __inline void +bus_space_copy_region_1(t, h1, o1, h2, o2, c) + bus_space_tag_t t; + bus_space_handle_t h1; + bus_size_t o1; + bus_space_handle_t h2; + bus_size_t o2; + size_t c; +{ + bus_addr_t addr1 = h1 + o1; + bus_addr_t addr2 = h2 + o2; + + if (addr1 >= addr2) { + /* src after dest: copy forward */ + for (; c != 0; c--, addr1++, addr2++) + *(volatile u_int8_t *)(addr2) = + *(volatile u_int8_t *)(addr1); + } else { + /* dest after src: copy backwards */ + for (addr1 += (c - 1), addr2 += (c - 1); + c != 0; c--, addr1--, addr2--) + *(volatile u_int8_t *)(addr2) = + *(volatile u_int8_t *)(addr1); + } +} + +static __inline void +bus_space_copy_region_2(t, h1, o1, h2, o2, c) + bus_space_tag_t t; + bus_space_handle_t h1; + bus_size_t o1; + bus_space_handle_t h2; + bus_size_t o2; + size_t c; +{ + bus_addr_t addr1 = h1 + o1; + bus_addr_t addr2 = h2 + o2; + + if (addr1 >= addr2) { + /* src after dest: copy forward */ + for (; c != 0; c--, addr1 += 2, addr2 += 2) + *(volatile u_int16_t *)(addr2) = + *(volatile u_int16_t *)(addr1); + } else { + /* dest after src: copy backwards */ + for (addr1 += 2 * (c - 1), addr2 += 2 * (c - 1); + c != 0; c--, addr1 -= 2, addr2 -= 2) + *(volatile u_int16_t *)(addr2) = + *(volatile u_int16_t *)(addr1); + } +} + +static __inline void +bus_space_copy_region_4(t, h1, o1, h2, o2, c) + bus_space_tag_t t; + bus_space_handle_t h1; + bus_size_t o1; + bus_space_handle_t h2; + bus_size_t o2; + size_t c; +{ + bus_addr_t addr1 = h1 + o1; + bus_addr_t addr2 = h2 + o2; + + if (addr1 >= addr2) { + /* src after dest: copy forward */ + for (; c != 0; c--, addr1 += 4, addr2 += 4) + *(volatile u_int32_t *)(addr2) = + *(volatile u_int32_t *)(addr1); + } else { + /* dest after src: copy backwards */ + for (addr1 += 4 * (c - 1), addr2 += 4 * (c - 1); + c != 0; c--, addr1 -= 4, addr2 -= 4) + *(volatile u_int32_t *)(addr2) = + *(volatile u_int32_t *)(addr1); + } +} + +#define bus_space_copy_region_8 !!! bus_space_copy_region_8 unimplemented !!! + +/* + * Bus read/write barrier methods. + * + * void bus_space_barrier __P((bus_space_tag_t tag, + * bus_space_handle_t bsh, bus_size_t offset, + * bus_size_t len, int flags)); + * + */ +#define bus_space_barrier(t, h, o, l, f) \ + ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f))) +#define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ +#define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ + +#define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t) + +/* + * Bus DMA methods. + */ + +/* + * Flags used in various bus DMA methods. + */ +#define BUS_DMA_WAITOK 0x00 /* safe to sleep (pseudo-flag) */ +#define BUS_DMA_NOWAIT 0x01 /* not safe to sleep */ +#define BUS_DMA_ALLOCNOW 0x02 /* perform resource allocation now */ +#define BUS_DMA_COHERENT 0x04 /* hint: map memory DMA coherent */ +#define BUS_DMA_STREAMING 0x08 /* hint: sequential, unidirectional */ +#define BUS_DMA_BUS1 0x10 /* placeholders for bus functions... */ +#define BUS_DMA_BUS2 0x20 +#define BUS_DMA_BUS3 0x40 +#define BUS_DMA_BUS4 0x80 + +/* Forwards needed by prototypes below. */ +struct mbuf; +struct uio; + +/* + * Operations performed by bus_dmamap_sync(). + */ +#define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */ +#define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */ +#define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */ +#define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */ + +typedef struct powerpc_bus_dma_tag *bus_dma_tag_t; +typedef struct powerpc_bus_dmamap *bus_dmamap_t; + +/* + * bus_dma_segment_t + * + * Describes a single contiguous DMA transaction. Values + * are suitable for programming into DMA registers. + */ +struct powerpc_bus_dma_segment { + bus_addr_t ds_addr; /* DMA address */ + bus_size_t ds_len; /* length of transfer */ +}; +typedef struct powerpc_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 powerpc_bus_dma_tag { + /* + * The `bounce threshold' is checked while we are loading + * the DMA map. If the physical address of the segment + * exceeds the threshold, an error will be returned. The + * caller can then take whatever action is necessary to + * bounce the transfer. If this value is 0, it will be + * ignored. + */ + bus_addr_t _bounce_thresh; + + /* + * DMA mapping methods. + */ + int (*_dmamap_create) __P((bus_dma_tag_t, bus_size_t, int, + bus_size_t, bus_size_t, int, bus_dmamap_t *)); + void (*_dmamap_destroy) __P((bus_dma_tag_t, bus_dmamap_t)); + int (*_dmamap_load) __P((bus_dma_tag_t, bus_dmamap_t, void *, + bus_size_t, struct proc *, int)); + int (*_dmamap_load_mbuf) __P((bus_dma_tag_t, bus_dmamap_t, + struct mbuf *, int)); + int (*_dmamap_load_uio) __P((bus_dma_tag_t, bus_dmamap_t, + struct uio *, int)); + int (*_dmamap_load_raw) __P((bus_dma_tag_t, bus_dmamap_t, + bus_dma_segment_t *, int, bus_size_t, int)); + void (*_dmamap_unload) __P((bus_dma_tag_t, bus_dmamap_t)); + void (*_dmamap_sync) __P((bus_dma_tag_t , bus_dmamap_t, bus_dmasync_op_t)); + + /* + * DMA memory utility functions. + */ + int (*_dmamem_alloc) __P((bus_dma_tag_t, bus_size_t, bus_size_t, + bus_size_t, bus_dma_segment_t *, int, int *, int)); + void (*_dmamem_free) __P((bus_dma_tag_t, + bus_dma_segment_t *, int)); + int (*_dmamem_map) __P((bus_dma_tag_t, bus_dma_segment_t *, + int, size_t, caddr_t *, int)); + void (*_dmamem_unmap) __P((bus_dma_tag_t, caddr_t, size_t)); + paddr_t (*_dmamem_mmap) __P((bus_dma_tag_t, bus_dma_segment_t *, + int, off_t, int, int)); +}; + +#define bus_dmamap_create(t, s, n, m, b, f, p) \ + (*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p)) +#define bus_dmamap_destroy(t, p) \ + (*(t)->_dmamap_destroy)((t), (p)) +#define bus_dmamap_load(t, m, b, s, p, f) \ + (*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f)) +#define bus_dmamap_load_mbuf(t, m, b, f) \ + (*(t)->_dmamap_load_mbuf)((t), (m), (b), (f)) +#define bus_dmamap_load_uio(t, m, u, f) \ + (*(t)->_dmamap_load_uio)((t), (m), (u), (f)) +#define bus_dmamap_load_raw(t, m, sg, n, s, f) \ + (*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f)) +#define bus_dmamap_unload(t, p) \ + (*(t)->_dmamap_unload)((t), (p)) +#define bus_dmamap_sync(t, p, o) \ + (void)((t)->_dmamap_sync ? \ + (*(t)->_dmamap_sync)((t), (p), (o)) : (void)0) + +#define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \ + (*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f)) +#define bus_dmamem_free(t, sg, n) \ + (*(t)->_dmamem_free)((t), (sg), (n)) +#define bus_dmamem_map(t, sg, n, s, k, f) \ + (*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f)) +#define bus_dmamem_unmap(t, k, s) \ + (*(t)->_dmamem_unmap)((t), (k), (s)) +#define bus_dmamem_mmap(t, sg, n, o, p, f) \ + (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f)) + +/* + * bus_dmamap_t + * + * Describes a DMA mapping. + */ +struct powerpc_bus_dmamap { + /* + * PRIVATE MEMBERS: not for use my 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 */ + bus_addr_t _dm_bounce_thresh; /* bounce threshold; see tag */ + 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 */ +}; + +#ifdef _POWERPC_BUS_DMA_PRIVATE +int _bus_dmamap_create __P((bus_dma_tag_t, bus_size_t, int, bus_size_t, + bus_size_t, int, bus_dmamap_t *)); +void _bus_dmamap_destroy __P((bus_dma_tag_t, bus_dmamap_t)); +int _bus_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *, + bus_size_t, struct proc *, int)); +int _bus_dmamap_load_mbuf __P((bus_dma_tag_t, bus_dmamap_t, + struct mbuf *, int)); +int _bus_dmamap_load_uio __P((bus_dma_tag_t, bus_dmamap_t, + struct uio *, int)); +int _bus_dmamap_load_raw __P((bus_dma_tag_t, bus_dmamap_t, + bus_dma_segment_t *, int, bus_size_t, int)); +void _bus_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t)); +void _bus_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, bus_dmasync_op_t)); + +int _bus_dmamem_alloc __P((bus_dma_tag_t tag, bus_size_t size, + bus_size_t alignment, bus_size_t boundary, + bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags)); +void _bus_dmamem_free __P((bus_dma_tag_t tag, bus_dma_segment_t *segs, + int nsegs)); +int _bus_dmamem_map __P((bus_dma_tag_t tag, bus_dma_segment_t *segs, + int nsegs, size_t size, caddr_t *kvap, int flags)); +void _bus_dmamem_unmap __P((bus_dma_tag_t tag, caddr_t kva, + size_t size)); +paddr_t _bus_dmamem_mmap __P((bus_dma_tag_t tag, bus_dma_segment_t *segs, + int nsegs, off_t off, int prot, int flags)); + +int _bus_dmamem_alloc_range __P((bus_dma_tag_t tag, bus_size_t size, + bus_size_t alignment, bus_size_t boundary, + bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags, + paddr_t low, paddr_t high)); +#endif /* _POWERPC_BUS_DMA_PRIVATE */ +#endif /* _POWERPC_BUS_H_ */ diff --git a/sys/arch/mvmeppc/include/cdefs.h b/sys/arch/mvmeppc/include/cdefs.h new file mode 100644 index 00000000000..aefb56bbc02 --- /dev/null +++ b/sys/arch/mvmeppc/include/cdefs.h @@ -0,0 +1,43 @@ +/* $OpenBSD: cdefs.h,v 1.1 2001/06/26 21:57:43 smurph Exp $ */ +/* $NetBSD: cdefs.h,v 1.1 1996/09/30 16:34:21 ws Exp $ */ + +/* + * Written by J.T. Conklin <jtc@wimsey.com> 01/17/95. + * Public domain. + */ + +#ifndef _MACHINE_CDEFS_H_ +#define _MACHINE_CDEFS_H_ + +#ifdef __STDC__ +#define _C_LABEL(x) _STRING(_ ## x) +#else +#define _C_LABEL(x) _STRING(_/**/x) +#endif + +#if 0 +#ifdef __GNUC__ +#ifdef __STDC__ +#define __indr_reference(sym,alias) \ + __asm__(".stabs \"_" #alias "\",11,0,0,0"); \ + __asm__(".stabs \"_" #sym "\",1,0,0,0") +#define __warn_references(sym,msg) \ + __asm__(".stabs \"" msg "\",30,0,0,0"); \ + __asm__(".stabs \"_" #sym "\",1,0,0,0") +#else +#define __indr_reference(sym,alias) \ + __asm__(".stabs \"_/**/alias\",11,0,0,0"); \ + __asm__(".stabs \"_/**/sym\",1,0,0,0") +#define __warn_references(sym,msg) \ + __asm__(".stabs msg,30,0,0,0"); \ + __asm__(".stabs \"_/**/sym\",1,0,0,0") +#endif +#endif +#else +#define __warn_references(sym,msg) +/* +#define __indr_reference(sym,alias) +*/ +#endif + +#endif /* !_MACHINE_CDEFS_H_ */ diff --git a/sys/arch/mvmeppc/include/cpu.h b/sys/arch/mvmeppc/include/cpu.h new file mode 100644 index 00000000000..f2fe9897e39 --- /dev/null +++ b/sys/arch/mvmeppc/include/cpu.h @@ -0,0 +1,100 @@ +/* $OpenBSD: cpu.h,v 1.1 2001/06/26 21:57:44 smurph Exp $ */ +/* $NetBSD: cpu.h,v 1.1 1996/09/30 16:34:21 ws Exp $ */ + +/* + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_CPU_H_ +#define _MACHINE_CPU_H_ + +#include <machine/frame.h> + +#include <machine/psl.h> + +#define CLKF_USERMODE(frame) (((frame)->srr1 & PSL_PR) != 0) +#define CLKF_BASEPRI(frame) ((frame)->pri == 0) +#define CLKF_PC(frame) ((frame)->srr0) +#define CLKF_INTR(frame) ((frame)->depth != 0) + +#define cpu_swapout(p) +#define cpu_wait(p) + +extern void delay __P((unsigned)); +#define DELAY(n) delay(n) + +extern volatile int want_resched; +extern volatile int astpending; + +#define need_resched() (want_resched = 1, astpending = 1) +#define need_proftick(p) ((p)->p_flag |= P_OWEUPC, astpending = 1) +#define signotify(p) (astpending = 1) + +#define CACHELINESIZE 32 /* For now XXX */ + +extern __inline void +syncicache(from, len) + void *from; + int len; +{ + int l = len; + char *p = from; + + do { + __asm__ __volatile__ ("dcbst 0,%0" :: "r"(p)); + p += CACHELINESIZE; + } while ((l -= CACHELINESIZE) > 0); + __asm__ __volatile__ ("sync"); + p = from; + l = len; + do { + __asm__ __volatile__ ("icbi 0,%0" :: "r"(p)); + p += CACHELINESIZE; + } while ((l -= CACHELINESIZE) > 0); + __asm__ __volatile__ ("isync"); +} + +extern __inline void +invdcache(from, len) + void *from; + int len; +{ + int l = len; + char *p = from; + + do { + __asm__ __volatile__ ("dcbi 0,%0" :: "r"(p)); + p += CACHELINESIZE; + } while ((l -= CACHELINESIZE) > 0); + __asm__ __volatile__ ("sync"); +} + +extern char *bootpath; + +#endif /* _MACHINE_CPU_H_ */ diff --git a/sys/arch/mvmeppc/include/db_machdep.h b/sys/arch/mvmeppc/include/db_machdep.h new file mode 100644 index 00000000000..447ef91ece6 --- /dev/null +++ b/sys/arch/mvmeppc/include/db_machdep.h @@ -0,0 +1,103 @@ +/* $OpenBSD: db_machdep.h,v 1.1 2001/06/26 21:57:44 smurph Exp $ */ +/* $NetBSD: db_machdep.h,v 1.13 1996/04/29 20:50:08 leo Exp $ */ + +/* + * 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. + */ + +/* + * Machine-dependent defines for new kernel debugger. + */ +#ifndef _PPC_DB_MACHDEP_H_ +#define _PPC_DB_MACHDEP_H_ + +#include <vm/vm_prot.h> +#include <vm/vm_param.h> +#include <vm/vm_inherit.h> +#include <machine/trap.h> + +/* ELF symbols in ddb */ +#define DB_ELF_SYMBOLS +#define DB_ELFSIZE 32 + +typedef vm_offset_t db_addr_t; /* address - unsigned */ +typedef int db_expr_t; /* expression - signed */ +struct powerpc_saved_state { + u_int32_t r[32]; /* data registers */ + u_int32_t iar; + u_int32_t msr; +}; + + +typedef struct powerpc_saved_state db_regs_t; +db_regs_t ddb_regs; /* register state */ +#define DDB_REGS (&ddb_regs) + +#define PC_REGS(regs) ((regs)->iar) + +#define BKPT_INST 0x7C810808 /* breakpoint instruction */ + +#define BKPT_SIZE (4) /* size of breakpoint inst */ +#define BKPT_SET(inst) (BKPT_INST) + +#define FIXUP_PC_AFTER_BREAK(regs) ((regs)->iar -= 4) + +#define SR_SINGLESTEP 0x8000 +#define db_clear_single_step(regs) ((regs)->msr &= ~SR_SINGLESTEP) +#define db_set_single_step(regs) ((regs)->msr |= SR_SINGLESTEP) + +#define T_BREAKPOINT 0xffff +#define IS_BREAKPOINT_TRAP(type, code) ((type) == T_BREAKPOINT) + +#ifdef T_WATCHPOINT +#define IS_WATCHPOINT_TRAP(type, code) ((type) == T_WATCHPOINT) +#else +#define IS_WATCHPOINT_TRAP(type, code) 0 +#endif + +#define M_RTS 0xfc0007fe +#define I_RTS 0x4c000020 +#define M_BC 0xfc000000 +#define I_BC 0x40000000 +#define M_B 0xfc000000 +#define I_B 0x50000000 +#define M_RFI 0xfc0007fe +#define I_RFI 0x4c000064 + +#define inst_trap_return(ins) (((ins)&M_RFI) == I_RFI) +#define inst_return(ins) (((ins)&M_RTS) == I_RTS) +#define inst_call(ins) (((ins)&M_BC ) == I_BC || \ + ((ins)&M_B ) == I_B ) +#define inst_load(ins) 0 +#define inst_store(ins) 0 + +#ifdef _KERNEL + +void kdb_kintr __P((void *)); +int kdb_trap __P((int, void *)); + +#endif /* _KERNEL */ + +#endif /* _PPC_DB_MACHDEP_H_ */ diff --git a/sys/arch/mvmeppc/include/disklabel.h b/sys/arch/mvmeppc/include/disklabel.h new file mode 100644 index 00000000000..61ccca25afe --- /dev/null +++ b/sys/arch/mvmeppc/include/disklabel.h @@ -0,0 +1,113 @@ +/* $OpenBSD: disklabel.h,v 1.1 2001/06/26 21:57:44 smurph 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_ + +#define LABELSECTOR 1 /* sector containing label */ +#define LABELOFFSET 0 /* offset of label in sector */ +#define MAXPARTITIONS 16 /* number of partitions */ +#define RAW_PART 2 /* raw partition: ie. rsd0c */ + +/* MBR partition table */ +#define DOSBBSECTOR 0 /* MBR sector number */ +#define DOSPARTOFF 446 /* Offset of MBR partition table */ +#define NDOSPART 4 /* # of partitions in MBR */ +#define DOSMAGICOFF 510 /* Offset of magic number */ +#define DOSMAGIC 0xaa55 /* Actual magic number */ +#define MBRMAGIC DOSMAGIC +#define DOSMBR_SIGNATURE MBRMAGIC +#define DOSMBR_SIGNATURE_OFF DOSMAGICOFF +#define DOSACTIVE 0x80 + +struct dos_partition { + unsigned char dp_flag; /* default boot flag */ + unsigned char dp_shd; /* start head, IsN't Always Meaningful */ + unsigned char dp_ssect; /* start sector, INAM */ + unsigned char dp_scyl; /* start cylinder, INAM */ + unsigned char dp_typ; /* partition type */ + unsigned char dp_ehd; /* end head, INAM */ + unsigned char dp_esect; /* end sector, INAM */ + unsigned char dp_ecyl; /* end cylinder, INAM */ + unsigned long dp_start; /* absolute start sector number */ + unsigned long 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_FAT16C 0x0e /* 16-bit FAT, CHS-mapped */ +#define DOSPTYP_EXTENDL 0x0f /* Extended, LBA-mapped; contains sub-partitions */ +#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 */ + +#include <sys/dkbad.h> +struct cpu_disklabel { + struct dos_partition dosparts[NDOSPART]; + struct dkbad bad; +}; + +#define DKBAD(x) ((x)->bad) + +/* Isolate the relevant bits to get sector and cylinder. */ +#define DPSECT(s) ((s) & 0x3f) +#define DPCYL(c, s) ((c) + (((s) & 0xc0) << 2)) + +static __inline u_int32_t get_le __P((void *p)); + +static __inline u_int32_t +#ifdef __cplusplus +get_le(void *p) +#else +get_le(p) + void *p; +#endif +{ + u_int32_t c; + u_int8_t *_p = (u_int8_t *)p; + int x; + x = _p[0]; + x |= _p[1] << 8; + x |= _p[2] << 16; + x |= _p[3] << 24; + return x; +} + +#endif /* _MACHINE_DISKLABEL_H_ */ diff --git a/sys/arch/mvmeppc/include/dlfcn.h b/sys/arch/mvmeppc/include/dlfcn.h new file mode 100644 index 00000000000..51d6520ba15 --- /dev/null +++ b/sys/arch/mvmeppc/include/dlfcn.h @@ -0,0 +1,63 @@ +/* $OpenBSD: dlfcn.h,v 1.1 2001/06/26 21:57:44 smurph Exp $ */ +/* $NetBSD: dlfcn.h,v 1.2 1995/06/05 19:38:00 pk Exp $ */ + +/* + * Copyright (c) 1995 Paul Kranenburg + * 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 Paul Kranenburg. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software withough 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 _DLFCN_H_ +#define _DLFCN_H_ + +#include <sys/cdefs.h> + +/* + * User interface to the run-time linker. + */ +__BEGIN_DECLS +extern void *dlopen __P((const char *, int)); +extern int dlclose __P((void *)); +extern void *dlsym __P((void *, const char *)); +extern int dlctl __P((void *, int, void *)); +extern const char *dlerror __P((void)); +__END_DECLS + +/* Values for dlopen `mode'. */ +#define DL_LAZY 1 +#define RTLD_LAZY DL_LAZY /* SunOS Compat */ + +/* + * dlctl() commands + */ +#define DL_GETERRNO 1 +#define DL_SETSRCHPATH x +#define DL_GETLIST x +#define DL_GETREFCNT x +#define DL_GETLOADADDR x + +#endif /* _DLFCN_H_ */ diff --git a/sys/arch/mvmeppc/include/elf_abi.h b/sys/arch/mvmeppc/include/elf_abi.h new file mode 100644 index 00000000000..8655664c0ec --- /dev/null +++ b/sys/arch/mvmeppc/include/elf_abi.h @@ -0,0 +1,48 @@ +/* $OpenBSD: elf_abi.h,v 1.1 2001/06/26 21:57:44 smurph Exp $ */ + +/* + * Copyright (c) 1996 Per Fogelstrom + * + * 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 under OpenBSD by + * Per Fogelstrom. + * 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 _POWERPC_ELF_ABI_H +#define _POWERPC_ELF_ABI_H + +/* From MIPS ABI supplemental */ + +/* Architecture dependent Segment types - p_type */ +/* ??NONE?? */ + +/* Architecture dependent d_tag field for Elf32_Dyn. */ +/* ??NONE?? */ + +#define DT_PROCNUM 0 + +#endif /* _POWERPC_ELF_ABI_H */ diff --git a/sys/arch/mvmeppc/include/endian.h b/sys/arch/mvmeppc/include/endian.h new file mode 100644 index 00000000000..92b7ec3163b --- /dev/null +++ b/sys/arch/mvmeppc/include/endian.h @@ -0,0 +1,40 @@ +/* $OpenBSD: endian.h,v 1.1 2001/06/26 21:57:44 smurph Exp $ */ + +/*- + * Copyright (c) 1997 Niklas Hallqvist. 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 Niklas Hallqvist. + * 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 _POWERPC_ENDIAN_H_ +#define _POWERPC_ENDIAN_H_ + +#define BYTE_ORDER BIG_ENDIAN +#include <sys/endian.h> + +#define __STRICT_ALIGNMENT + +#endif /* _POWERPC_ENDIAN_H_ */ diff --git a/sys/arch/mvmeppc/include/exec.h b/sys/arch/mvmeppc/include/exec.h new file mode 100644 index 00000000000..e4a723216e1 --- /dev/null +++ b/sys/arch/mvmeppc/include/exec.h @@ -0,0 +1,57 @@ +/* $OpenBSD: exec.h,v 1.1 2001/06/26 21:57:44 smurph Exp $ */ + +/* + * Copyright (c) 1997 Per Fogelstrom, Opsycon AB. + * + * 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 under OpenBSD for RTMX Inc, + * North Carolina, USA, by Per Fogelstrom, Opsycon AB, Sweden. + * 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. + * + * $Id: exec.h,v 1.1 2001/06/26 21:57:44 smurph Exp $ + */ + +#ifndef _MACHINE_EXEC_H_ +#define _MACHINE_EXEC_H_ + +#define __LDPGSZ 4096 /* linker page size */ + +/* + * Define what exec "formats" we should handle. + */ +#define NATIVE_EXEC_ELF +#define EXEC_SCRIPT + +#define ARCH_ELFSIZE 32 + +#define ELF_TARG_CLASS ELFCLASS32 +#define ELF_TARG_DATA ELFDATA2MSB +#define ELF_TARG_MACH EM_PPC + +#define _NLIST_DO_ELF + +#define _KERN_DO_ELF + +#endif /* _MACHINE_EXEC_H_ */ diff --git a/sys/arch/mvmeppc/include/float.h b/sys/arch/mvmeppc/include/float.h new file mode 100644 index 00000000000..6c68fce847c --- /dev/null +++ b/sys/arch/mvmeppc/include/float.h @@ -0,0 +1,80 @@ +/* $OpenBSD: float.h,v 1.1 2001/06/26 21:57:45 smurph 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. 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, Berkeley and its contributors. + * 4. 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 _MACHINE_FLOAT_H_ +#define _MACHINE_FLOAT_H_ + +#include <sys/cdefs.h> + +__BEGIN_DECLS +int __flt_rounds __P((void)); +__END_DECLS + +#define FLT_RADIX 2 /* b */ +#define FLT_ROUNDS __flt_rounds() + +#define FLT_MANT_DIG 24 /* p */ +#define FLT_EPSILON 1.19209290E-07F /* b**(1-p) */ +#define FLT_DIG 6 /* floor((p-1)*log10(b))+(b == 10) */ +#define FLT_MIN_EXP (-125) /* emin */ +#define FLT_MIN 1.17549435E-38F /* b**(emin-1) */ +#define FLT_MIN_10_EXP (-37) /* ceil(log10(b**(emin-1))) */ +#define FLT_MAX_EXP 128 /* emax */ +#define FLT_MAX 3.40282347E+38F /* (1-b**(-p))*b**emax */ +#define FLT_MAX_10_EXP 38 /* floor(log10((1-b**(-p))*b**emax)) */ + +#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 DBL_MANT_DIG +#define LDBL_EPSILON DBL_EPSILON +#define LDBL_DIG DBL_DIG +#define LDBL_MIN_EXP DBL_MIN_EXP +#define LDBL_MIN DBL_MIN +#define LDBL_MIN_10_EXP DBL_MIN_10_EXP +#define LDBL_MAX_EXP DBL_MAX_EXP +#define LDBL_MAX DBL_MAX +#define LDBL_MAX_10_EXP DBL_MAX_10_EXP + +#endif /* _MACHINE_FLOAT_H_ */ diff --git a/sys/arch/mvmeppc/include/fpu.h b/sys/arch/mvmeppc/include/fpu.h new file mode 100644 index 00000000000..34a4cda8070 --- /dev/null +++ b/sys/arch/mvmeppc/include/fpu.h @@ -0,0 +1,69 @@ +/* $OpenBSD: fpu.h,v 1.1 2001/06/26 21:57:45 smurph Exp $ */ + +/*- + * Copyright (C) 1996 Wolfgang Solfrank. + * Copyright (C) 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_FPU_H_ +#define _MACHINE_FPU_H_ + +#define FPCSR_FX 0x80000000 +#define FPCSR_FEX 0x40000000 +#define FPCSR_VX 0x20000000 +#define FPCSR_OX 0x10000000 +#define FPCSR_UX 0x08000000 +#define FPCSR_ZX 0x04000000 +#define FPCSR_XX 0x02000000 +#define FPCSR_VXSNAN 0x01000000 +#define FPCSR_VXISI 0x00800000 +#define FPCSR_VXIDI 0x00400000 +#define FPCSR_VXZDZ 0x00200000 +#define FPCSR_VXIMZ 0x00100000 +#define FPCSR_VXVC 0x00080000 +#define FPCSR_FR 0x00040000 +#define FPCSR_FI 0x00020000 +#define FPCSR_FPRF 0x0001f000 +#define FPCSR_C 0x00010000 +#define FPCSR_FPCC 0x0000f000 +#define FPCSR_FL 0x00008000 +#define FPCSR_FG 0x00004000 +#define FPCSR_FE 0x00002000 +#define FPCSR_FU 0x00001000 +#define FPCSR_VXSOFT 0x00000400 +#define FPCSR_VXSQRT 0x00000200 +#define FPCSR_VXCVI 0x00000100 +#define FPCSR_VE 0x00000080 +#define FPCSR_OE 0x00000040 +#define FPCSR_UE 0x00000020 +#define FPCSR_ZE 0x00000010 +#define FPCSR_XE 0x00000008 +#define FPCSR_NI 0x00000004 +#define FPCSR_RN 0x00000003 + +#endif /* _MACHINE_FPU_H_ */ diff --git a/sys/arch/mvmeppc/include/frame.h b/sys/arch/mvmeppc/include/frame.h new file mode 100644 index 00000000000..2a12f8dea7b --- /dev/null +++ b/sys/arch/mvmeppc/include/frame.h @@ -0,0 +1,76 @@ +/* $OpenBSD: frame.h,v 1.1 2001/06/26 21:57:45 smurph Exp $ */ + +/* + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_FRAME_H_ +#define _MACHINE_FRAME_H_ + +#include <machine/types.h> + +/* + * This is to ensure alignment of the stackpointer + */ +#define FRAMELEN roundup(sizeof(struct trapframe) + 8, 16) +#define trapframe(p) ((struct trapframe *)((void *)(p)->p_addr + USPACE - FRAMELEN + 8)) + +struct switchframe { + register_t sp; + int fill; + int user_sr; + int cr; + register_t fixreg2; + register_t fixreg[19]; /* R13-R31 */ +}; + +struct clockframe { + register_t srr1; + register_t srr0; + int pri; + int depth; +}; + +/* + * Call frame for PowerPC used during fork. + */ +struct callframe { + register_t sp; + register_t lr; + register_t r30; + register_t r31; +}; + +struct sigframe { + int sf_signum; + siginfo_t *sf_sip; + struct sigcontext sf_sc; + siginfo_t sf_si; +}; +#endif /* _MACHINE_FRAME_H_ */ diff --git a/sys/arch/mvmeppc/include/ieee.h b/sys/arch/mvmeppc/include/ieee.h new file mode 100644 index 00000000000..8552f21f957 --- /dev/null +++ b/sys/arch/mvmeppc/include/ieee.h @@ -0,0 +1,136 @@ +/* $OpenBSD: ieee.h,v 1.1 2001/06/26 21:57:45 smurph 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. 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, Berkeley and its contributors. + * 4. 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 + +#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/mvmeppc/include/ieeefp.h b/sys/arch/mvmeppc/include/ieeefp.h new file mode 100644 index 00000000000..71a4c0153c1 --- /dev/null +++ b/sys/arch/mvmeppc/include/ieeefp.h @@ -0,0 +1,23 @@ +/* + * Written by J.T. Conklin, Apr 6, 1995 + * Public domain. + */ + +#ifndef _MACHINE_IEEEFP_H_ +#define _MACHINE_IEEEFP_H_ + +typedef int fp_except; +#define FP_X_IMP 0x01 /* imprecise (loss of precision) */ +#define FP_X_DZ 0x02 /* divide-by-zero exception */ +#define FP_X_UFL 0x04 /* underflow exception */ +#define FP_X_OFL 0x08 /* overflow exception */ +#define FP_X_INV 0x10 /* invalid operation exception */ + +typedef enum { + FP_RN=0, /* round to nearest representable number */ + FP_RZ=1, /* round to zero (truncate) */ + FP_RM=2, /* round toward negative infinity */ + FP_RP=3 /* round toward positive infinity */ +} fp_rnd; + +#endif /* _MACHINE_IEEEFP_H_ */ diff --git a/sys/arch/mvmeppc/include/intr.h b/sys/arch/mvmeppc/include/intr.h new file mode 100644 index 00000000000..0093a81410a --- /dev/null +++ b/sys/arch/mvmeppc/include/intr.h @@ -0,0 +1,172 @@ +/* $OpenBSD: intr.h,v 1.1 2001/06/26 21:57:46 smurph Exp $ */ + +/* + * Copyright (c) 1997 Per Fogelstrom, Opsycon AB and RTMX Inc, USA. + * + * 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 under OpenBSD by + * Per Fogelstrom, Opsycon AB, Sweden for RTMX Inc, North Carolina USA. + * 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_INTR_H_ +#define _MACHINE_INTR_H_ + +#define IPL_BIO 0 +#define IPL_NET 1 +#define IPL_TTY 2 +#define IPL_IMP 3 +#define IPL_CLOCK 4 +#define IPL_NONE 5 +#define IPL_HIGH 6 + +#define IST_NONE 0 +#define IST_PULSE 1 +#define IST_EDGE 2 +#define IST_LEVEL 3 + +#ifndef _LOCORE + +#define PPC_NIRQ 65 +#define PPC_CLK_IRQ 64 +extern int intrcnt[PPC_NIRQ]; + +void setsoftclock __P((void)); +void clearsoftclock __P((void)); +int splsoftclock __P((void)); +void setsoftnet __P((void)); +void clearsoftnet __P((void)); +int splsoftnet __P((void)); + +void do_pending_int __P((void)); + + +volatile int cpl, ipending, astpending, tickspending; +int imask[7]; + +/* + * Reorder protection in the following inline functions is + * achived with the "eieio" instruction which the assembler + * seems to detect and then doen't move instructions past.... + */ +static __inline int +splraise(newcpl) + int newcpl; +{ + int oldcpl; + + __asm__ volatile("sync; eieio\n"); /* don't reorder.... */ + oldcpl = cpl; + cpl = oldcpl | newcpl; + __asm__ volatile("sync; eieio\n"); /* reorder protect */ + return(oldcpl); +} + +static __inline void +splx(newcpl) + int newcpl; +{ + __asm__ volatile("sync; eieio\n"); /* reorder protect */ + cpl = newcpl; + if(ipending & ~newcpl) + do_pending_int(); + __asm__ volatile("sync; eieio\n"); /* reorder protect */ +} + +static __inline int +spllower(newcpl) + int newcpl; +{ + int oldcpl; + + __asm__ volatile("sync; eieio\n"); /* reorder protect */ + oldcpl = cpl; + cpl = newcpl; + if(ipending & ~newcpl) + do_pending_int(); + __asm__ volatile("sync; eieio\n"); /* reorder protect */ + return(oldcpl); +} + +/* Following code should be implemented with lwarx/stwcx to avoid + * the disable/enable. i need to read the manual once more.... */ +static __inline void +set_sint(pending) + int pending; +{ + int msrsave; + + __asm__ ("mfmsr %0" : "=r"(msrsave)); + __asm__ volatile ("mtmsr %0" :: "r"(msrsave & ~PSL_EE)); + ipending |= pending; + __asm__ volatile ("mtmsr %0" :: "r"(msrsave)); +} + +#define SINT_CLOCK 0x10000000 +#define SINT_NET 0x20000000 +#define SINT_TTY 0x40000000 +#define SPL_CLOCK 0x80000000 +#define SINT_MASK (SINT_CLOCK|SINT_NET|SINT_TTY) + +#define splbio() splraise(imask[IPL_BIO]) +#define splnet() splraise(imask[IPL_NET]) +#define spltty() splraise(imask[IPL_TTY]) +#define splclock() splraise(SPL_CLOCK|SINT_MASK) +#define splimp() splraise(imask[IPL_IMP]) +#define splstatclock() splhigh() +#define spllowersoftclock() spllower(SINT_CLOCK) +#define splsoftclock() splraise(SINT_CLOCK) +#define splsoftnet() splraise(SINT_NET) +#define splsofttty() splraise(SINT_TTY) + +#define setsoftclock() set_sint(SINT_CLOCK); +#define setsoftnet() set_sint(SINT_NET); +#define setsofttty() set_sint(SINT_TTY); + +#define splhigh() splraise(0xffffffff) +#define spl0() spllower(0) + +/* + * Interrupt control struct used to control the ICU setup. + */ + +struct intrhand { + struct intrhand *ih_next; + int (*ih_fun) __P((void *)); + void *ih_arg; + u_long ih_count; + int ih_level; + int ih_irq; + char *ih_what; +}; +extern int ppc_configed_intr_cnt; +#define MAX_PRECONF_INTR 16 +extern struct intrhand ppc_configed_intr[MAX_PRECONF_INTR]; + +#endif /* _LOCORE */ + + +#endif /* _MACHINE_INTR_H_ */ diff --git a/sys/arch/mvmeppc/include/ipkdb.h b/sys/arch/mvmeppc/include/ipkdb.h new file mode 100644 index 00000000000..499d249a160 --- /dev/null +++ b/sys/arch/mvmeppc/include/ipkdb.h @@ -0,0 +1,80 @@ +/* $OpenBSD: ipkdb.h,v 1.1 2001/06/26 21:57:46 smurph Exp $ */ + +/* + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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. + */ +/* register array */ +#define FIX 0 +#define LR 32 +#define CR 33 +#define CTR 34 +#define XER 35 +#define PC 36 +#define MSR 37 +#define NREG 38 + +#ifndef _LOCORE +extern int ipkdbregs[NREG]; + +/* Doesn't handle overlapping regions */ +__inline extern void +ipkdbcopy(s,d,n) + void *s, *d; + int n; +{ + char *sp = s, *dp = d; + + while (--n >= 0) + *dp++ = *sp++; +} + +__inline extern void +ipkdbzero(d,n) + void *d; + int n; +{ + char *dp = d; + + while (--n >= 0) + *dp++ = 0; +} + +__inline extern int +ipkdbcmp(s,d,n) + void *s, *d; +{ + char *sp = s, *dp = d; + + while (--n >= 0) + if (*sp++ != *dp++) + return *--dp - *--sp; + return 0; +} +#endif /* _LOCORE */ diff --git a/sys/arch/mvmeppc/include/kbio.h b/sys/arch/mvmeppc/include/kbio.h new file mode 100644 index 00000000000..af8d95c6038 --- /dev/null +++ b/sys/arch/mvmeppc/include/kbio.h @@ -0,0 +1,118 @@ +/* $OpenBSD: kbio.h,v 1.1 2001/06/26 21:57:46 smurph Exp $ */ +/* $NetBSD: kbio.h,v 1.1 1996/04/12 01:45:45 cgd 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. 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, Berkeley and its contributors. + * 4. 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. + * + * @(#)kbio.h 8.1 (Berkeley) 6/11/93 + */ + +#if 0 /* XXX */ +/* + * The following is a minimal emulation of Sun's `kio' structures + * and related operations necessary to make X11 happy (i.e., make it + * compile, and make old X11 binaries run). + */ + +/* + * The kiockey structure apparently gets and/or sets keyboard mappings. + * It seems to be kind of useless, but X11 uses it (according to the + * comments) to figure out when a Sun 386i has a type-4 keyboard but + * claims to have a type-3 keyboard. We need just enough to cause the + * appropriate ioctl to return the appropriate magic value. + * + * KIOCGETKEY fills in kio_entry from kio_station. Not sure what tablemask + * is for; X sets it before the call, so it is not an output, but we do not + * care anyway. KIOCSDIRECT is supposed to tell the kernel whether to send + * keys to the console or to X; we just send them to X whenever the keyboard + * is open at all. (XXX may need to change this later) + * + * Keyboard commands and types are defined in kbd.h as they are actually + * real hardware commands and type numbers. + */ +struct okiockey { /* Out-dated key translation structure */ + int kio_tablemask; /* whatever */ + u_char kio_station; /* key number */ + u_char kio_entry; /* HOLE if not present */ + char kio_text[10]; /* the silly escape sequences (unsupported) */ +}; + +struct kiockey { + int kio_tablemask; /* whatever */ + u_char kio_station; /* key number */ + u_short kio_entry; /* HOLE if not present */ + char kio_text[10]; /* the silly escape sequences (unsupported) */ +}; + +/* + * Values for kio_tablemask. These determine which table to read/modify + * in KIOC[SG]KEY ioctls. Currently, we only have "non-shift" and "shift" + * tables. + */ +#define KIOC_NOMASK 0x0 +#define KIOC_CAPSMASK 0x1 +#define KIOC_SHIFTMASK 0xe +#define KIOC_CTRLMASK 0x30 +#define KIOC_ALTGMASK 0x200 +#define KIOC_NUMLMASK 0x800 + +#define HOLE 0x302 /* value for kio_entry to say `really type 3' */ + +#define KIOCTRANS _IOW('k', 0, int) /* set translation mode */ + /* (we only accept TR_UNTRANS_EVENT) */ +#define KIOCGETKEY _IOWR('k', 2, struct okiockey) /* fill in kio_entry */ +#define KIOCGTRANS _IOR('k', 5, int) /* get translation mode */ +#define KIOCCMD _IOW('k', 8, int) /* X uses this to ring bell */ +#define KIOCTYPE _IOR('k', 9, int) /* get keyboard type */ +#endif /* 0 XXX */ +#define KIOCSDIRECT _IOW('k', 10, int) /* keys to console? */ +#if 0 /* XXX */ +#define KIOCSKEY _IOW('k', 12, struct kiockey) /* set xlat mode */ +#define KIOCGKEY _IOWR('k', 13, struct kiockey) /* get xlat mode */ +#define KIOCLAYOUT _IOR('k', 20, int) /* get keyboard layout */ +#define KIOCSLED _IOW('k', 14, char) /* set LED state */ +#define KIOCGLED _IOR('k', 15, char) /* get LED state */ + +#define TR_NONE 0 /* X compat, unsupported */ +#define TR_ASCII 1 /* X compat, unsupported */ +#define TR_EVENT 2 /* X compat, unsupported */ +#define TR_UNTRANS_EVENT 3 +#endif /* 0 XXX */ diff --git a/sys/arch/mvmeppc/include/kcore.h b/sys/arch/mvmeppc/include/kcore.h new file mode 100644 index 00000000000..d8d2fce296d --- /dev/null +++ b/sys/arch/mvmeppc/include/kcore.h @@ -0,0 +1,46 @@ +/* $OpenBSD: kcore.h,v 1.1 2001/06/26 21:57:46 smurph Exp $ */ +/* $NetBSD: kcore.h,v 1.1 1996/09/30 16:34:26 ws Exp $ */ + +/*- + * Copyright (C) 1996 Wolfgang Solfrank. + * Copyright (C) 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_KCORE_H_ +#define _MACHINE_KCORE_H_ + +#define NPHYS_RAM_SEGS 4 + +typedef struct cpu_kcore_hdr { + vm_offset_t ptable; /* Phys address of page table */ + vm_offset_t potable; /* Phys address of page overflow table */ + phys_ram_seg_t ram_segs[NPHYS_RAM_SEGS]; +} cpu_kcore_hdr_t; + +#endif /* _MACHINE_KCORE_H_ */ diff --git a/sys/arch/mvmeppc/include/limits.h b/sys/arch/mvmeppc/include/limits.h new file mode 100644 index 00000000000..7f56856521c --- /dev/null +++ b/sys/arch/mvmeppc/include/limits.h @@ -0,0 +1,88 @@ +/* $OpenBSD: limits.h,v 1.1 2001/06/26 21:57:46 smurph Exp $ */ +/* $NetBSD: limits.h,v 1.1 1996/09/30 16:34:28 ws Exp $ */ + +/*- + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_LIMITS_H_ +#define _MACHINE_LIMITS_H_ + +#define CHAR_BIT 8 /* bits per char */ +#define MB_LEN_MAX 1 /* no multibyte characters */ +#define CHAR_MIN 0 /* min value in char */ +#define CHAR_MAX 0xff /* max value in char */ +#define UCHAR_MAX 0xff /* max value in unsigned char */ +#define SCHAR_MIN (-0x7f-1) /* min value for a signed char */ +#define SCHAR_MAX 0x7f /* max value for a signed char */ + +#define SHRT_MIN (-0x7fff-1) /* min value in short */ +#define SHRT_MAX 0x7fff /* max value in short */ +#define USHRT_MAX 0xffff /* max value in unsigned short */ + +#define INT_MIN (-0x7fffffff-1) /* min value in int */ +#define INT_MAX 0x7fffffff /* max value in int */ +#define UINT_MAX 0xffffffff /* max value in unsigned int */ + +#define LONG_MIN (-0x7fffffff-1) /* min value in long */ +#define LONG_MAX 0x7fffffff /* max value in long */ +#define ULONG_MAX 0xffffffff /* max value in unsigned long */ + +#if !defined(_ANSI_SOURCE) +#define SSIZE_MAX INT_MAX /* max value for a ssize_t */ + +#if !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE) +#define SIZE_T_MAX UINT_MAX /* max value for a size_t */ + +#define UID_MAX UINT_MAX /* max value for a uid_t */ +#define GID_MAX UINT_MAX /* max value for a gid_t */ + +#define UQUAD_MAX 0xffffffffffffffffULL /* max unsigned quad */ +#define QUAD_MAX 0x7fffffffffffffffLL /* max signed quad */ +#define QUAD_MIN (-0x7fffffffffffffffLL-1) /* min signed quad */ +#define ULLONG_MAX (UQUAD_MAX) /* max value for unsigned long long */ +#define LLONG_MAX (QUAD_MAX) /* max value for a signed long long */ +#define LLONG_MIN (QUAD_MIN) /* min value for a signed long long */ +#endif /* !_POSIX_SOURCE && !_XOPEN_SOURCE */ +#endif /* !_ANSI_SOURCE */ + +#if (!defined(_ANSI_SOURCE)&&!defined(_POSIX_SOURCE)) || defined(_XOPEN_SOURCE) +#define LONG_BIT 32 +#define WORD_BIT 32 + +#define DBL_DIG 15 +#define DBL_MAX 1.7976931348623157E+308 +#define DBL_MIN 2.2250738585072014E-308 + +#define FLT_DIG 6 +#define FLT_MAX 3.40282347E+38F +#define FLT_MIN 1.17549435E-38F +#endif +#endif /* _MACHINE_LIMITS_H_ */ diff --git a/sys/arch/mvmeppc/include/link.h b/sys/arch/mvmeppc/include/link.h new file mode 100644 index 00000000000..c8ede7dd33d --- /dev/null +++ b/sys/arch/mvmeppc/include/link.h @@ -0,0 +1,183 @@ +/* $OpenBSD: link.h,v 1.1 2001/06/26 21:57:47 smurph Exp $ */ + +/* + * Copyright (c) 1996 Per Fogelstrom + * + * 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 under OpenBSD by + * Per Fogelstrom. + * 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 _POWERPC_LINK_H +#define _POWERPC_LINK_H + +#include <elf_abi.h> +#include <machine/elf_abi.h> + +/* + * Debug rendezvous struct. Pointer to this is set up in the + * target code pointed by the DT_MIPS_RLD_MAP tag. If it is + * defined. + */ + +struct r_debug { + int r_version; /* Protocol version. */ + struct link_map *r_map; /* Head of list of loaded objects. */ + + /* This is the address of a function internal to the run-time linker, + that will always be called when the linker begins to map in a + library or unmap it, and again when the mapping change is complete. + The debugger can set a breakpoint at this address if it wants to + notice shared object mapping changes. */ + Elf32_Addr r_brk; + enum { + /* This state value describes the mapping change taking place when + the `r_brk' address is called. */ + RT_CONSISTENT, /* Mapping change is complete. */ + RT_ADD, /* Adding a new object. */ + RT_DELETE, /* Removing an object mapping. */ + } r_state; + + Elf32_Addr r_ldbase; /* Base address the linker is loaded at. */ + }; + +/* This symbol refers to the "dynamic structure" in the `.dynamic' section + of whatever module refers to `_DYNAMIC'. So, to find its own + `struct r_debug', a program could do: + for (dyn = _DYNAMIC; dyn->d_tag != DT_NULL) + if (dyn->d_tag == DT_MIPS_RLD_MAP) r_debug = (struct r_debug) dyn->d_un.d_ptr; + */ + +extern Elf32_Dyn _DYNAMIC[]; + + +/* Structure describing a loaded shared object. The `l_next' and `l_prev' + members form a chain of all the shared objects loaded at startup. + + These data structures exist in space used by the run-time dynamic linker; + modifying them may have disastrous results. */ + +struct link_map + { + /* These first few members are part of the protocol with the debugger. + This is the same format used in SVR4. */ + + Elf32_Addr l_addr; /* Base address shared object is loaded at. */ + Elf32_Addr l_offs; /* Offset */ + char *l_name; /* Absolute file name object was found in. */ + Elf32_Dyn *l_ld; /* Dynamic section of the shared object. */ + struct link_map *l_next, *l_prev; /* Chain of loaded objects. */ + + /* All following members are internal to the dynamic linker. + They may change without notice. */ + + const char *l_libname; /* Name requested (before search). */ + + /* Indexed pointers to dynamic section. */ + Elf32_Dyn *l_info[DT_NUM + DT_PROCNUM]; + + const Elf32_Phdr *l_phdr; /* Pointer to program header table in core. */ + Elf32_Word l_phnum; /* Number of program header entries. */ + Elf32_Addr l_entry; /* Entry point location. */ + + /* Symbol hash table. */ + Elf32_Word l_nbuckets; + const Elf32_Word *l_buckets, *l_chain; + + unsigned int l_opencount; /* Reference count for dlopen/dlclose. */ + enum /* Where this object came from. */ + { + lt_executable, /* The main executable program. */ + lt_interpreter, /* The interpreter: the dynamic linker. */ + lt_library, /* Library needed by main executable. */ + lt_loaded, /* Extra run-time loaded shared object. */ + } l_type:2; + unsigned int l_deps_loaded:1; /* Nonzero if DT_NEEDED items loaded. */ + unsigned int l_relocated:1; /* Nonzero if object's relocations done. */ + unsigned int l_init_called:1; /* Nonzero if DT_INIT function called. */ + unsigned int l_init_running:1; /* Nonzero while DT_INIT function runs. */ + }; + +/* SOD information used by ldconfig and ld.so */ +/* + * Maximum number of recognized shared object version numbers. + */ +#define MAXDEWEY 8 + +/* + * Header of the hints file. + */ +struct hints_header { + long hh_magic; +#define HH_MAGIC 011421044151 + long hh_version; /* Interface version number */ +#define LD_HINTS_VERSION_1 1 +#define LD_HINTS_VERSION_2 2 + long hh_hashtab; /* Location of hash table */ + long hh_nbucket; /* Number of buckets in hashtab */ + long hh_strtab; /* Location of strings */ + long hh_strtab_sz; /* Size of strings */ + long hh_ehints; /* End of hints (max offset in file) */ + long hh_dirlist; /* Colon-separated list of srch dirs */ +}; + +#define HH_BADMAG(hdr) ((hdr).hh_magic != HH_MAGIC) + +/* + * Hash table element in hints file. + */ +struct hints_bucket { + /* namex and pathx are indices into the string table */ + int hi_namex; /* Library name */ + int hi_pathx; /* Full path */ + int hi_dewey[MAXDEWEY]; /* The versions */ + int hi_ndewey; /* Number of version numbers */ +#define hi_major hi_dewey[0] +#define hi_minor hi_dewey[1] + int hi_next; /* Next in this bucket */ +}; + +#define _PATH_LD_HINTS "/var/run/ld.so.hints" + +/* + * A `Shared Object Descriptor' describes a shared object that is needed + * to complete the link edit process of the object containing it. + * A list of such objects (chained through `sod_next') is pointed at + * by `sdt_sods' in the section_dispatch_table structure. + */ + +struct sod { /* Shared Object Descriptor */ + long sod_name; /* name (relative to load address) */ + u_int sod_library : 1, /* Searched for by library rules */ + sod_reserved : 31; + short sod_major; /* major version number */ + short sod_minor; /* minor version number */ + long sod_next; /* next sod */ +}; + + +#endif /* !_POWERPC_LINK_H */ diff --git a/sys/arch/mvmeppc/include/param.h b/sys/arch/mvmeppc/include/param.h new file mode 100644 index 00000000000..54408b50ec1 --- /dev/null +++ b/sys/arch/mvmeppc/include/param.h @@ -0,0 +1,149 @@ +/* $OpenBSD: param.h,v 1.1 2001/06/26 21:57:47 smurph Exp $ */ +/* $NetBSD: param.h,v 1.1 1996/09/30 16:34:28 ws Exp $ */ + +/*- + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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. + */ + +#ifdef _KERNEL +#ifndef _LOCORE +#include <machine/cpu.h> +#endif /* _LOCORE */ +#endif + +/* + * Machine dependent constants for PowerPC (32-bit only currently) + */ +#define MACHINE "mvmeppc" +#define _MACHINE mvmeppc +#define MACHINE_ARCH "powerpc" +#define _MACHINE_ARCH powerpc + +#define MID_MACHINE 0 /* None but has to be defined */ + +#define ALIGNBYTES (sizeof(double) - 1) +#define ALIGN(p) (((u_int)(p) + ALIGNBYTES) & ~ALIGNBYTES) +#define ALIGNED_POINTER(p,t) ((((u_long)(p)) & (sizeof(t)-1)) == 0) + +#define PGSHIFT 12 +#define NBPG 4096 +#define PGOFSET (NBPG - 1) +#define PAGE_SIZE NBPG +#define PAGE_MASK PGOFSET +#define PAGE_SHIFT PGSHIFT + +#define DEV_BSHIFT 9 /* log2(DEV_BSIZE) */ +#define DEV_BSIZE (1 << DEV_BSHIFT) +#define BLKDEV_IOSIZE NBPG +#define MAXPHYS (64 * 1024) /* max raw I/O transfer size */ + +#define UPAGES 4 +#define USPACE (UPAGES * NBPG) + +#define KERNBASE 0x100000 + +/* + * 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 128 /* size of an mbuf */ +#define MCLSHIFT 11 /* convert bytes to m_buf clusters */ +#define MCLBYTES (1 << MCLSHIFT) /* size of a m_buf cluster */ +#define MCLOFSET (MCLBYTES - 1) + +#ifndef NMBCLUSTERS +#ifdef GATEWAY +#define NMBCLUSTERS 2048 /* map size, max cluster allocation */ +#else +#define NMBCLUSTERS 1024 /* map size, max cluster allocation */ +#endif +#endif + +#define MSGBUFSIZE (NBPG*2) + +/* + * Size of kernel malloc arena in logical pages. + */ +#ifndef NKMEMCLUSTERS +#define NKMEMCLUSTERS (16 * 1024 * 1024 / PAGE_SIZE) +#endif + +/* + * pages ("clicks") to disk blocks + */ +#define ctod(x) ((x) << (PGSHIFT - DEV_BSHIFT)) +#define dtoc(x) ((x) >> (PGSHIFT - DEV_BSHIFT)) +/* + * bytes to pages + */ +#define ctob(x) ((x) << PGSHIFT) +#define btoc(x) (((x) + PGOFSET) >> PGSHIFT) + +/* + * bytes to disk blocks + */ +#define dbtob(x) ((x) << DEV_BSHIFT) +#define btodb(x) ((x) >> DEV_BSHIFT) + +/* + * Mach derived conversion macros + */ +#define powerpc_btop(x) ((unsigned)(x) >> PGSHIFT) +#define powerpc_ptob(x) ((unsigned)(x) << PGSHIFT) + +/* + * Segment handling stuff + */ +#define SEGMENT_LENGTH 0x10000000 +#define SEGMENT_MASK 0xf0000000 + +/* + * Fixed segments + */ +#define USER_SR 13 +#define KERNEL_SR 14 +#define KERNEL_SEGMENT (0xfffff0 + KERNEL_SR) +#define EMPTY_SEGMENT 0xfffff0 +#define USER_ADDR ((void *)(USER_SR << ADDR_SR_SHFT)) + +/* + * Some system constants + */ +#ifndef NPMAPS +#define NPMAPS 32768 /* Number of pmaps in system */ +#endif + +/* + * Temporary kludge till we do (ov)bcopy in assembler + */ +#define ovbcopy bcopy diff --git a/sys/arch/mvmeppc/include/pcb.h b/sys/arch/mvmeppc/include/pcb.h new file mode 100644 index 00000000000..dab951bb04a --- /dev/null +++ b/sys/arch/mvmeppc/include/pcb.h @@ -0,0 +1,71 @@ +/* $OpenBSD: pcb.h,v 1.1 2001/06/26 21:57:47 smurph Exp $ */ +/* $NetBSD: pcb.h,v 1.1 1996/09/30 16:34:29 ws Exp $ */ + +/*- + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_PCB_H_ +#define _MACHINE_PCB_H_ + +#include <machine/reg.h> + + +typedef struct __faultbuf { + int pc; + int sr; + int sp; + int cr; + int regs[20]; +} faultbuf; + +struct pcb { + struct pmap *pcb_pm; /* pmap of our vmspace */ + struct pmap *pcb_pmreal; /* real address of above */ + register_t pcb_sp; /* saved SP */ + int pcb_spl; /* saved SPL */ + faultbuf *pcb_onfault; /* For use during copyin/copyout */ + int pcb_flags; +#define PCB_FPU 1 /* Process had FPU initialized */ + struct fpu { + double fpr[32]; + double fpcsr; /* FPCSR stored as double for easier access */ + } pcb_fpu; /* Floating point processor */ +}; + +struct md_coredump { + struct reg regs; +}; + +#ifdef _KERNEL +extern struct pcb *curpcb; +extern struct pmap *curpm; +extern struct proc *fpuproc; +#endif +#endif /* _MACHINE_PCB_H_ */ diff --git a/sys/arch/mvmeppc/include/pio.h b/sys/arch/mvmeppc/include/pio.h new file mode 100644 index 00000000000..5373eebcc84 --- /dev/null +++ b/sys/arch/mvmeppc/include/pio.h @@ -0,0 +1,195 @@ +/* $OpenBSD: pio.h,v 1.1 2001/06/26 21:57:47 smurph Exp $ */ + +/* + * Copyright (c) 1997 Per Fogelstrom, Opsycon AB and RTMX Inc, USA. + * + * 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 under OpenBSD by + * Per Fogelstrom Opsycon AB for RTMX Inc, North Carolina, USA. + * 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_PIO_H_ +#define _MACHINE_PIO_H_ +/* + * I/O macros. + */ +void *mapiodev(paddr_t pa, psize_t len); + +static __inline void +__outb(a,v) + volatile u_int8_t *a; + int v; +{ + *a = v; + __asm__ volatile("eieio"); +} + +static __inline void +__outw(a,v) + volatile u_int16_t *a; + u_int16_t v; +{ + *a = v; + __asm__ volatile("eieio"); +} + +static __inline void +__outl(a,v) + volatile u_int32_t *a; + int v; +{ + *a = v; + __asm__ volatile("eieio"); +} + +static __inline void +__outwrb(a,v) + volatile u_int16_t *a; + u_int16_t v; +{ + u_int32_t _p_ = (u_int32_t)a; + + __asm__ volatile("sthbrx %0, 0, %1" :: "r"(v), "r"(_p_)); + __asm__ volatile("eieio"); +} + +static __inline void +__outlrb(a,v) + volatile u_int32_t *a; + u_int32_t v; +{ + u_int32_t _p_ = (u_int32_t)a; + + __asm__ volatile("stwbrx %0, 0, %1" :: "r"(v), "r"(_p_)); + __asm__ volatile("eieio"); +} + +static __inline u_int8_t +__inb(a) + volatile u_int8_t *a; +{ + u_int8_t _v_; + + __asm__ volatile("eieio"); + _v_ = *a; + return _v_; +} + +static __inline u_int16_t +__inw(a) + volatile u_int16_t *a; +{ + u_int16_t _v_; + + __asm__ volatile("eieio"); + _v_ = *a; + return _v_; +} + +static __inline u_int32_t +__inl(a) + volatile u_int32_t *a; +{ + u_int32_t _v_; + + __asm__ volatile("eieio"); + _v_ = *a; + return _v_; +} + +static __inline u_int16_t +__inwrb(a) + volatile u_int16_t *a; +{ + u_int16_t _v_; + u_int32_t _p_ = (u_int32_t)a; + + __asm__ volatile("eieio"); + __asm__ volatile("lhbrx %0, 0, %1" : "=r"(_v_) : "r"(_p_)); + return _v_; +} + +static __inline u_int32_t +__inlrb(a) + volatile u_int32_t *a; +{ + u_int32_t _v_; + u_int32_t _p_ = (u_int32_t)a; + + __asm__ volatile("eieio"); + __asm__ volatile("lwbrx %0, 0, %1" : "=r"(_v_) : "r"(_p_)); + return _v_; +} + + +#define outb(a,v) (__outb((volatile u_int8_t *)(a), v)) +#define out8(a,v) outb(a,v) +#define outw(a,v) (__outw((volatile u_int16_t *)(a), v)) +#define out16(a,v) outw(a,v) +#define outl(a,v) (__outl((volatile u_int32_t *)(a), v)) +#define out32(a,v) outl(a,v) +#define inb(a) (__inb((volatile u_int8_t *)(a))) +#define in8(a) inb(a) +#define inw(a) (__inw((volatile u_int16_t *)(a))) +#define in16(a) inw(a) +#define inl(a) (__inl((volatile u_int32_t *)(a))) +#define in32(a) inl(a) + +#define out8rb(a,v) outb(a,v) +#define outwrb(a,v) (__outwrb((volatile u_int16_t *)(a), v)) +#define out16rb(a,v) outwrb(a,v) +#define outlrb(a,v) (__outlrb((volatile u_int32_t *)(a), v)) +#define out32rb(a,v) outlrb(a,v) +#define in8rb(a) inb(a) +#define inwrb(a) (__inwrb((volatile u_int16_t *)(a))) +#define in16rb(a) inwrb(a) +#define inlrb(a) (__inlrb((volatile u_int32_t *)(a))) +#define in32rb(a) inlrb(a) + +#ifdef DEBUG_SPEC +static __inline void +__flash_led(bits, count) + int bits; +{ + int i, v = 0; + + if(bits == 0) { + v = 1; bits = 3; + } + bits &= 3; + count += count; + v |= (*(volatile u_int8_t *)(MPC106_V_ISA_IO_SPACE + 0x01f4)) & ~3; + while(count--) { + v ^= bits; + for(i = 100000; i > 0; i--) + *(volatile u_int8_t *)(MPC106_V_ISA_IO_SPACE + 0x01f4) = v; + } + *(u_int8_t *)(MPC106_V_ISA_IO_SPACE + 0x01f4) &= ~3; +} +#endif /* DEBUG */ + +#endif /*_MACHINE_PIO_H_*/ diff --git a/sys/arch/mvmeppc/include/pmap.h b/sys/arch/mvmeppc/include/pmap.h new file mode 100644 index 00000000000..9491d97aadd --- /dev/null +++ b/sys/arch/mvmeppc/include/pmap.h @@ -0,0 +1,96 @@ +/* $OpenBSD: pmap.h,v 1.1 2001/06/26 21:57:47 smurph Exp $ */ +/* $NetBSD: pmap.h,v 1.1 1996/09/30 16:34:29 ws Exp $ */ + +/*- + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_PMAP_H_ +#define _MACHINE_PMAP_H_ + +#include <machine/pte.h> + +/* + * Segment registers + */ +#ifndef _LOCORE +typedef u_int sr_t; +#endif /* _LOCORE */ +#define SR_TYPE 0x80000000 +#define SR_SUKEY 0x40000000 +#define SR_PRKEY 0x20000000 +#define SR_VSID 0x00ffffff + +#ifndef _LOCORE +/* V->P mapping data */ +typedef int pmapv_t; +#define VP_SR_SIZE 32 +#define VP_SR_MASK VP_SR_SIZE-1 +#define VP_SR_POS 27 +#define VP_IDX1_SIZE 1024 +#define VP_IDX1_MASK VP_IDX1_SIZE-1 +#define VP_IDX1_POS 17 +#define VP_IDX2_SIZE 32 +#define VP_IDX2_MASK VP_IDX2_SIZE-1 +#define VP_IDX2_POS 12 + +/* + * Pmap stuff + */ +struct pmap { + sr_t pm_sr[16]; /* segments used in this pmap */ + int pm_refs; /* ref count */ + pmapv_t *vps[VP_SR_SIZE]; /* virtual to physical table */ + struct pmap_statistics pm_stats; /* pmap statistics */ +}; + +typedef struct pmap *pmap_t; + +#ifdef _KERNEL +extern struct pmap kernel_pmap_; +#define pmap_kernel() (&kernel_pmap_) + +#define pmap_clear_modify(pa) (ptemodify((pa), PTE_CHG, 0)) +#define pmap_clear_reference(pa) (ptemodify((pa), PTE_REF, 0)) +#define pmap_is_modified(pa) (ptebits((pa), PTE_CHG)) +#define pmap_is_referenced(pa) (ptebits((pa), PTE_REF)) +#define pmap_change_wiring(pm, va, wired) + +#define pmap_unwire(pm, va) + +#define pmap_phys_address(x) (x) + +#define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count) + +void pmap_bootstrap __P((u_int kernelstart, u_int kernelend)); + +#endif /* _KERNEL */ +#endif /* _LOCORE */ +#endif /* _MACHINE_PMAP_H_ */ diff --git a/sys/arch/mvmeppc/include/powerpc.h b/sys/arch/mvmeppc/include/powerpc.h new file mode 100644 index 00000000000..b79ed38d610 --- /dev/null +++ b/sys/arch/mvmeppc/include/powerpc.h @@ -0,0 +1,132 @@ +/* $OpenBSD: powerpc.h,v 1.1 2001/06/26 21:57:47 smurph Exp $ */ +/* $NetBSD: powerpc.h,v 1.1 1996/09/30 16:34:30 ws Exp $ */ + +/* + * Copyright (C) 1996 Wolfgang Solfrank. + * Copyright (C) 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_POWERPC_H_ +#define _MACHINE_POWERPC_H_ + +struct mem_region { + vm_offset_t start; + vm_size_t size; +}; + +void mem_regions __P((struct mem_region **, struct mem_region **)); + +/* + * These two functions get used solely in boot() in machdep.c. + * + * Not sure whether boot itself should be implementation dependent instead. XXX + */ +typedef void (exit_f) __P((void)) /*__attribute__((__noreturn__))*/ ; +typedef void (boot_f) __P((char *bootspec)) /* __attribute__((__noreturn__))*/ ; +typedef void (vmon_f) __P((void)); +typedef unsigned char (nvram_rd_f) __P((unsigned long offset)); +typedef void (nvram_wr_f) __P((unsigned long offset, unsigned char val)); +typedef unsigned long (tps_f) __P((void)); + + +typedef void (mem_regions_f) __P((struct mem_region **memp, + struct mem_region **availp)); + +typedef int (clock_read_f) __P((int *sec, int *min, int *hour, int *day, + int *mon, int *yr)); +typedef int (clock_write_f) __P((int sec, int min, int hour, int day, + int mon, int yr)); +typedef int (time_read_f) __P((u_long *sec)); +typedef int (time_write_f) __P((u_long sec)); + +/* firmware interface. + * regardless of type of firmware used several items + * are need from firmware to boot up. + * these include: + * memory information + * vmsetup for firmware calls. + * default character print mechanism ??? + * firmware exit (return) + * firmware boot (reset) + * vmon - tell firmware the bsd vm is active. + */ + +struct firmware { + mem_regions_f *mem_regions; + exit_f *exit; + boot_f *boot; + vmon_f *vmon; + nvram_rd_f *nvram_rd; + nvram_wr_f *nvram_wr; + tps_f *tps; + clock_read_f *clock_read; + clock_write_f *clock_write; + time_read_f *time_read; + time_write_f *time_write; +#ifdef FW_HAS_PUTC + boot_f *putc; +#endif +}; +extern struct firmware *fw; + +#define ppc_exit() if (fw->exit != NULL) (fw->exit)() +#define ppc_boot(x) if (fw->boot != NULL) (fw->boot)(x) +#define ppc_vmon() if (fw->vmon != NULL) (fw->vmon)() +#define ppc_nvram_rd(a) ({unsigned char val; \ + if (fw->nvram_rd !=NULL) \ + val = (fw->nvram_rd)(a); \ + else \ + val = 0; \ + val;}) + +#define ppc_nvram_wr(a, v) if (fw->nvram_wr !=NULL) (fw->nvram_wr)(a, v) + +#define ppc_tps() ({unsigned long val; \ + if (fw->tps != NULL) \ + val = (fw->tps)(); \ + else \ + val = 0; \ + val;}) + +#define SPR_XER "1" +#define SPR_LR "8" +#define SPR_CTR "9" +#define SPR_DSISR "18" +#define SPR_DAR "19" +#define SPR_DEC "22" +#define SPR_SDR1 "25" +#define SPR_SRR0 "26" +#define SPR_SRR1 "27" + +#define ppc_get_spr(reg) ({u_int32_t val; \ + __asm__ volatile("mfspr %0," reg : "=r"(val)); \ + val;}) +#define ppc_set_spr(reg, val) ({ \ + __asm__ volatile("mtspr " reg ",%0" :: "r"(val));}) + +#endif /* _MACHINE_POWERPC_H_ */ diff --git a/sys/arch/mvmeppc/include/proc.h b/sys/arch/mvmeppc/include/proc.h new file mode 100644 index 00000000000..a5700e76289 --- /dev/null +++ b/sys/arch/mvmeppc/include/proc.h @@ -0,0 +1,40 @@ +/* $OpenBSD: proc.h,v 1.1 2001/06/26 21:57:48 smurph Exp $ */ +/* $NetBSD: proc.h,v 1.1 1996/09/30 16:34:31 ws Exp $ */ + +/*- + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Machine-dependent part of the proc structure + */ +struct mdproc { + int dummy; +}; diff --git a/sys/arch/mvmeppc/include/profile.h b/sys/arch/mvmeppc/include/profile.h new file mode 100644 index 00000000000..f961bdbc427 --- /dev/null +++ b/sys/arch/mvmeppc/include/profile.h @@ -0,0 +1,73 @@ +/* $OpenBSD: profile.h,v 1.1 2001/06/26 21:57:48 smurph Exp $ */ + +/* + * Copyright (c) 1998 Dale Rahn. 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 Dale Rahn. + * 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. + */ +#define MCOUNT \ + __asm__(" \ + .section \".text\" \n\ + .align 2 \n\ + .globl _mcount \n\ + .type _mcount,@function \n\ + _mcount: \n\ + lwz 11, 4(1) \n\ + mflr 0 \n\ + stw 0, 4(1) \n\ + stwu 1, -48(1) \n\ + stw 3, 8(1) \n\ + stw 4, 12(1) \n\ + stw 5, 16(1) \n\ + stw 6, 20(1) \n\ + stw 7, 24(1) \n\ + stw 8, 28(1) \n\ + stw 9, 32(1) \n\ + stw 10,36(1) \n\ + stw 11,40(1) \n\ + mr 4, 0 \n\ + mr 3, 11 \n\ + bl __mcount \n\ + lwz 3, 8(1) \n\ + lwz 4, 12(1) \n\ + lwz 5, 16(1) \n\ + lwz 6, 20(1) \n\ + lwz 7, 24(1) \n\ + lwz 8, 28(1) \n\ + lwz 9, 32(1) \n\ + lwz 10,36(1) \n\ + lwz 11,40(1) \n\ + addi 1, 1, 48 \n\ + lwz 0, 4(1) \n\ + mtlr 11 \n\ + stw 11, 4(1) \n\ + mtctr 0 \n\ + bctr \n\ + .Lfe2: \n\ + .size _mcount, .Lfe2-_mcount \n\ + "); +#define _MCOUNT_DECL static __mcount diff --git a/sys/arch/mvmeppc/include/prom.h b/sys/arch/mvmeppc/include/prom.h new file mode 100644 index 00000000000..21f76b68d6d --- /dev/null +++ b/sys/arch/mvmeppc/include/prom.h @@ -0,0 +1,376 @@ +/* $OpenBSD: prom.h,v 1.1 2001/06/26 21:57:48 smurph Exp $ */ +/* + * Copyright (c) 2001 Steve Murphree, Jr. + * 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 Theo de Raadt + * 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_PROM_H__ +#define __MACHINE_PROM_H__ + +#define MVMEPROM_INCHR 0x0000 +#define MVMEPROM_INSTAT 0x0001 +#define MVMEPROM_INLN 0x0002 +#define MVMEPROM_READSTR 0x0003 +#define MVMEPROM_READLN 0x0004 +#define MVMEPROM_CHKBRK 0x0005 +#define MVMEPROM_DSKRD 0x0010 +#define MVMEPROM_DSKWR 0x0011 +#define MVMEPROM_DSKCFIG 0x0012 +#define MVMEPROM_DSKFMT 0x0014 +#define MVMEPROM_DSKCTRL 0x0015 +#define MVMEPROM_NETRD 0x0018 +#define MVMEPROM_NETWR 0x0019 +#define MVMEPROM_NETCFIG 0x001a +#define MVMEPROM_NETFOPEN 0x001b +#define MVMEPROM_NETFREAD 0x001c +#define MVMEPROM_NETCTRL 0x001d +#define MVMEPROM_OUTCHR 0x0020 +#define MVMEPROM_OUTSTR 0x0021 +#define MVMEPROM_OUTLN 0x0022 +#define MVMEPROM_WRITE 0x0023 +#define MVMEPROM_WRITELN 0x0024 +#define MVMEPROM_WRITDLN 0x0025 +#define MVMEPROM_PCRLF 0x0026 +#define MVMEPROM_ERASLN 0x0027 +#define MVMEPROM_WRITD 0x0028 +#define MVMEPROM_SNDBRK 0x0029 +#define MVMEPROM_DELAY 0x0043 +#define MVMEPROM_RTC_TM 0x0050 +#define MVMEPROM_RTC_DT 0x0051 +#define MVMEPROM_RTC_DSP 0x0052 +#define MVMEPROM_RTC_RD 0x0053 +#define MVMEPROM_REDIR 0x0060 +#define MVMEPROM_REDIR_I 0x0061 +#define MVMEPROM_REDIR_O 0x0062 +#define MVMEPROM_EXIT 0x0063 +#define MVMEPROM_RETURN MVMEPROM_EXIT +#define MVMEPROM_BINDEC 0x0064 +#define MVMEPROM_CHANGEV 0x0067 +#define MVMEPROM_STRCMP 0x0068 +#define MVMEPROM_MUL32 0x0069 +#define MVMEPROM_DIV32 0x006a +#define MVMEPROM_CHKSUM 0x006b +#define MVMEPROM_BRD_ID 0x0070 +#define MVMEPROM_ENVIRON 0x0071 +#define MVMEPROM_PFLASH 0x0073 +#define MVMEPROM_DIAGFCN 0x0074 +#define MVMEPROM_SIOPEPS 0x0090 +#define MVMEPROM_FORKMPU 0x0100 +#define MVMEPROM_FORKMPUR 0x0101 +#define MVMEPROM_IDELMPU 0x0110 +#define MVMEPROM_IOINQ 0x0120 +#define MVMEPROM_IOINFORM 0x0124 +#define MVMEPROM_IOCONFIG 0x0128 +#define MVMEPROM_IODELETE 0x012c +#define MVMEPROM_SYMBOLTA 0x0130 +#define MVMEPROM_SYMBOLTD 0x0131 + +#define NETCTRLCMD_GETETHER 1 +#define ENVIRONCMD_WRITE 1 +#define ENVIRONCMD_READ 2 +#define ENVIRONTYPE_EOL 0 +#define ENVIRONTYPE_START 1 +#define ENVIRONTYPE_DISKBOOT 2 +#define ENVIRONTYPE_ROMBOOT 3 +#define ENVIRONTYPE_NETBOOT 4 +#define ENVIRONTYPE_MEMSIZE 5 + +#define NETSTATUS_SUCCESS 0x00 +#define NETSTATUS_MISALNG 0x01 +#define NETSTATUS_BUFFLMT 0x02 +#define NETSTATUS_BADLEN 0x03 +#define NETSTATUS_INITABRT 0x04 +#define NETSTATUS_TXABRT 0x05 +#define NETSTATUS_PCIADDRERR 0x06 +#define NETSTATUS_NOPORT 0x07 +#define NETSTATUS_ILLIPL 0x08 +#define NETSTATUS_USERABRT 0x09 +#define NETSTATUS_TIMEOUT 0x0A +#define NETSTATUS_SYSERR 0x10 +#define NETSTATUS_TXBABBLE 0x11 +#define NETSTATUS_TXCOL 0x12 +#define NETSTATUS_TXSTOPPED 0x13 +#define NETSTATUS_TXUNDERFL 0x14 +#define NETSTATUS_TXLATECOL 0x15 +#define NETSTATUS_TXLOSTCARR 0x16 +#define NETSTATUS_TXLINKFAIL 0x17 +#define NETSTATUS_TXNOCARR 0x18 +#define NETSTATUS_TXTOPHY 0x19 +#define NETSTATUS_RXCRCERR 0x20 +#define NETSTATUS_RXOVERFL 0x21 +#define NETSTATUS_RXFRAMEERR 0x22 +#define NETSTATUS_RXLDFNS 0x23 +#define NETSTATUS_RXFDCOL 0x24 +#define NETSTATUS_RXRUNTFRAME 0x25 +#define NETSTATUS_TXTONORM 0x28 +#define NETSTATUS_TXTOSETUP 0x29 +#define NETSTATUS_SROMERR 0x30 + +#define NETCTRLCMD_INIT 0 +#define NETCTRLCMD_GETETHER 1 +#define NETCTRLCMD_TX 2 +#define NETCTRLCMD_RX 3 +#define NETCTRLCMD_FLUSH 4 +#define NETCTRLCMD_RESET 5 + +#define NETCFG_FLAG_RD 0 +#define NETCFG_FLAG_WR 1 +#define NETCFG_FLAG_WRNV 2 + +#ifndef LOCORE +extern struct bugenviron bugenviron; +extern int bugenv_init; + +#define BUG_ENV_END 0 +#define BUG_STARTUP_PARAM 1 +struct bug_startup { + char s_mode; + char s_menu; + char s_remotestart; + char s_probe; + char s_negsysfail; + char s_resetscsi; + char s_nocfblk; + char s_scsisync; +}; + +#define BUG_AUTOBOOT_INFO 2 +struct bug_autoboot { + char b_enable; + char b_poweruponly; + char b_clun; + char b_dlun; + char b_delay; + char b_string[22]; /* 0x15 + 0x1 */ +}; + +#define BUG_ROMBOOT_INFO 3 +struct bug_romboot { + char r_enable; + char r_poweruponly; + char r_bootvme; + char r_delay; + unsigned r_start; + unsigned r_end; +}; + +#define BUG_NETBOOT_INFO 4 +struct bug_netboot { + char n_enable; + char n_poweruponly; + char n_clun; + char n_dlun; + char n_delay; + char *n_param; +}; + +#define BUG_MEMORY_INFO 5 +struct bug_memory { + char m_sizeenable; + unsigned m_start; + unsigned m_end; +}; + +struct bugenviron { + struct bug_startup s; + struct bug_autoboot b; + struct bug_romboot r; + struct bug_netboot n; + struct bug_memory m; +}; + +#define bug_localmemsize() (bugenviron.m.m_end - bugenviron.m.m_start) +#define bug_localmemstart() (bugenviron.m.m_start) +#define bug_localmemend() (bugenviron.m.m_end) + +struct mvmeprom_netio { + u_char clun; + u_char dlun; + u_short status; + void *addr; + u_long tlen; + u_long offset; + u_long ttime; + u_long tbytes; + char filename[64]; +}; + +struct mvmeprom_netfopen { + u_char clun; + u_char dlun; + u_short status; + char filename[64]; +}; + +struct mvmeprom_netfread { + u_char clun; + u_char dlun; + u_short status; + void *addr; + u_short bytes; + u_short blk; + u_long timeout; +}; + +struct mvmeprom_netctrl { + u_char clun; + u_char dlun; + u_short status; + u_long cmd; + void *addr; + u_long len; + u_long flags; +}; + +struct mvmeprom_netparam { + u_long ver; + void * nodeaddr; + void * loadaddr; + void * execaddr; + u_long delay; + u_long length; + u_long offset; + void * traceaddr; + u_long client_ip; + u_long server_ip; + u_long subnet; + u_long bcast; + u_long gateway_ip; + u_char rarp_retry; + u_char tftp_retry; + u_char rarp_cntl; + u_char update_cntl; + char filename[64]; + char args[64]; +}; + +struct mvmeprom_netcfg { + u_char clun; + u_char dlun; + u_short status; + struct mvmeprom_netparam *netparam; + u_long flag; +}; + +struct prom_environ_hdr { + u_char type; + u_char len; +}; + +struct mvmeprom_brdid { + u_long eye_catcher; /* "BDID" */ + u_char rev; + u_char month; + u_char day; + u_char year; + u_short size; /* BID packet length */ + u_short rsv1; + u_short model; /* e.g. 1603, 1604 */ + u_short suffix; /* e.g. AT */ + u_long options; /* Board options */ + u_short ctrlun; /* boot clun */ + u_short devlun; /* boot dlun */ + u_short devtype; /* boot device type */ + u_short devnum; /* boot device number */ + u_long opt2; /* reserved */ + u_char version[4]; + /* the folowing are CNFG values */ + u_char board_serial[12]; /* SBC serial number */ + u_char board_id[16]; /* SBC id */ + u_char pwa_id[16]; /* printed wiring assembly id */ + u_char old_speed[4]; /* old cpu speed field */ + u_char etheraddr[6]; /* mac address, all zero if no ether */ + u_char fill[2]; + u_char scsi_id[2]; /* local SCSI id */ + u_char speed[3]; /* cpu speed */ + u_char bus_speed[3]; /* pci bus speed */ + u_char sys_serial[16]; /* system serial (user)*/ + u_char sys_id[31]; /* system id (user)*/ + u_char license_id[9]; /* license ID (for AIX)*/ +}; + +struct mvmeprom_time { + u_char year_BCD; + u_char month_BCD; + u_char day_BCD; + u_char wday_BCD; + u_char hour_BCD; + u_char min_BCD; + u_char sec_BCD; + u_char cal_BCD; +}; + +struct mvmeprom_dskio { + u_char ctrl_lun; + u_char dev_lun; + u_short status; + void *pbuffer; + u_long blk_num; + u_short blk_cnt; + u_char flag; +#define BUG_FILE_MARK 0x80 +#define IGNORE_FILENUM 0x02 +#define END_OF_FILE 0x01 + u_char addr_mod; +}; +#define MVMEPROM_BLOCK_SIZE 256 + +struct mvmeprom_args { + u_int dev_lun; + u_int ctrl_lun; + u_int flags; + u_int ctrl_addr; + u_int entry; + u_int conf_blk; + char *arg_start; + char *arg_end; + char *nbarg_start; + char *nbarg_end; + u_int cputyp; +}; + +#endif + +#define MVMEPROM_CALL(x) \ + __asm__ __volatile__ ( __CONCAT("addi 10,0,",__STRING(x)) ); \ + __asm__ __volatile__ ("sc"); + +#define MVMEPROM_REG_CTRLLUN "3" +#define MVMEPROM_REG_DEVLUN "4" +#define MVMEPROM_REG_SCSUPP "5" +#define MVMEPROM_REG_CTRLADDR "6" +#define MVMEPROM_REG_ENTRY "7" +#define MVMEPROM_REG_IPA "8" +#define MVMEPROM_REG_ARGSTART "9" +#define MVMEPROM_REG_ARGEND "10" +#define MVMEPROM_REG_NBARGSTART "11" +#define MVMEPROM_REG_NBARGEND "12" + +#ifndef RB_NOSYM +#define RB_NOSYM 0x400 +#endif +#endif __MACHINE_PROM_H__ diff --git a/sys/arch/mvmeppc/include/psl.h b/sys/arch/mvmeppc/include/psl.h new file mode 100644 index 00000000000..ff197f9c4aa --- /dev/null +++ b/sys/arch/mvmeppc/include/psl.h @@ -0,0 +1,77 @@ +/* $OpenBSD: psl.h,v 1.1 2001/06/26 21:57:48 smurph Exp $ */ +/* $NetBSD: psl.h,v 1.1 1996/09/30 16:34:32 ws Exp $ */ + +/* + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_PSL_H_ +#define _MACHINE_PSL_H_ + +/* + * Flags in MSR: + */ +#define PSL_POW 0x00040000 +#define PSL_ILE 0x00010000 +#define PSL_EE 0x00008000 +#define PSL_PR 0x00004000 +#define PSL_FP 0x00002000 +#define PSL_ME 0x00001000 +#define PSL_FE0 0x00000800 +#define PSL_SE 0x00000400 +#define PSL_BE 0x00000200 +#define PSL_FE1 0x00000100 +#define PSL_IP 0x00000040 +#define PSL_IR 0x00000020 +#define PSL_DR 0x00000010 +#define PSL_RI 0x00000002 +#define PSL_LE 0x00000001 + +/* + * Floating-point exception modes: + */ +#define PSL_FE_DIS 0 +#define PSL_FE_NONREC PSL_FE1 +#define PSL_FE_REC PSL_FE0 +#define PSL_FE_PREC (PSL_FE0 | PSL_FE1) +#define PSL_FE_DFLT PSL_FE_DIS + +/* + * Note that PSL_POW and PSL_ILE are not in the saved copy of the MSR + */ +#define PSL_MBO 0 +#define PSL_MBZ 0 + +#define PSL_USERSET (PSL_EE | PSL_PR | PSL_ME | PSL_IR | PSL_DR | PSL_RI) + +#define PSL_USERSTATIC (PSL_USERSET | PSL_IP | 0x87c0008c) + +#include <machine/intr.h> + +#endif /* _MACHINE_PSL_H_ */ diff --git a/sys/arch/mvmeppc/include/pte.h b/sys/arch/mvmeppc/include/pte.h new file mode 100644 index 00000000000..43becb6d73d --- /dev/null +++ b/sys/arch/mvmeppc/include/pte.h @@ -0,0 +1,113 @@ +/* $OpenBSD: pte.h,v 1.1 2001/06/26 21:57:48 smurph Exp $ */ +/* $NetBSD: pte.h,v 1.1 1996/09/30 16:34:32 ws Exp $ */ + +/*- + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_PTE_H_ +#define _MACHINE_PTE_H_ + +#include <sys/queue.h> + +/* + * Page Table Entries + */ +#ifndef _LOCORE +struct pte { + u_int pte_hi; + u_int pte_lo; +}; +#endif /* _LOCORE */ +/* High word: */ +#define PTE_VALID 0x80000000 +#define PTE_VSID_SHFT 7 +#define PTE_HID 0x00000040 +#define PTE_API 0x0000003f +/* Low word: */ +#define PTE_RPGN 0xfffff000 +#define PTE_REF 0x00000100 +#define PTE_CHG 0x00000080 +#define PTE_WIMG 0x00000078 +#define PTE_W 0x00000040 +#define PTE_I 0x00000020 +#define PTE_M 0x00000010 +#define PTE_G 0x00000008 +#define PTE_PP 0x00000003 +#define PTE_RO 0x00000003 +#define PTE_RW 0x00000002 + +#ifndef _LOCORE +typedef struct pte pte_t; +#endif /* _LOCORE */ + +/* + * Extract bits from address + */ +#define ADDR_SR_SHFT 28 +#define ADDR_PIDX 0x0ffff000 +#define ADDR_PIDX_SHFT 12 +#define ADDR_API_SHFT 22 +#define ADDR_POFF 0x00000fff + +#ifndef _LOCORE +#ifdef _KERNEL +extern pte_t *ptable; +extern int ptab_cnt; +#endif /* _KERNEL */ +#endif /* _LOCORE */ + +/* + * Bits in DSISR: + */ +#define DSISR_DIRECT 0x80000000 +#define DSISR_NOTFOUND 0x40000000 +#define DSISR_PROTECT 0x08000000 +#define DSISR_INVRX 0x04000000 +#define DSISR_STORE 0x02000000 +#define DSISR_DABR 0x00400000 +#define DSISR_SEGMENT 0x00200000 +#define DSISR_EAR 0x00100000 + +/* + * Bits in SRR1 on ISI: + */ +#define ISSRR1_NOTFOUND 0x40000000 +#define ISSRR1_DIRECT 0x10000000 +#define ISSRR1_PROTECT 0x08000000 +#define ISSRR1_SEGMENT 0x00200000 + +#ifdef _KERNEL +#ifndef _LOCORE +extern u_int dsisr __P((void)); +extern vm_offset_t dar __P((void)); +#endif /* _KERNEL */ +#endif /* _LOCORE */ +#endif /* _MACHINE_PTE_H_ */ diff --git a/sys/arch/mvmeppc/include/ptrace.h b/sys/arch/mvmeppc/include/ptrace.h new file mode 100644 index 00000000000..311a8ddcff3 --- /dev/null +++ b/sys/arch/mvmeppc/include/ptrace.h @@ -0,0 +1,48 @@ +/* $OpenBSD: ptrace.h,v 1.1 2001/06/26 21:57:48 smurph Exp $ */ +/* $NetBSD: ptrace.h,v 1.7 1995/01/26 19:47:10 mycroft Exp $ */ + +/* + * Copyright (c) 1993 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 _POWERPC_PTRACE_H_ +#define _POWERPC_PTRACE_H_ + +/* + * powerpc-dependent ptrace definitions + */ +#define PT_STEP (PT_FIRSTMACH + 0) +#define PT_GETREGS (PT_FIRSTMACH + 1) +#define PT_SETREGS (PT_FIRSTMACH + 2) + +#if NOT_SUPPORTED +#define PT_GETFPREGS (PT_FIRSTMACH + 3) +#define PT_SETFPREGS (PT_FIRSTMACH + 4) +#endif + +#endif /* !_POWERPC_PTRACE_H_ */ diff --git a/sys/arch/mvmeppc/include/reg.h b/sys/arch/mvmeppc/include/reg.h new file mode 100644 index 00000000000..e65145f27e6 --- /dev/null +++ b/sys/arch/mvmeppc/include/reg.h @@ -0,0 +1,62 @@ +/* $OpenBSD: reg.h,v 1.1 2001/06/26 21:57:48 smurph Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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 University of + * California, Berkeley and its contributors. + * 4. 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. + * + * @(#)reg.h 5.5 (Berkeley) 1/18/91 + */ + +#ifndef _POWERPC_REG_H_ +#define _POWERPC_REG_H_ + +/* + * Struct reg, used for procfs and in signal contexts + * Note that in signal contexts, it's represented as an array. + * That array has to look exactly like 'struct reg' though. + */ + +/* this table is set up to match what gdb expects */ +struct reg { + u_int32_t gpr[32]; + u_int64_t fpr[32]; + u_int32_t pc; + u_int32_t ps; + u_int32_t cnd; + u_int32_t lr; + u_int32_t cnt; + u_int32_t xer; + u_int32_t mq; +}; +#endif /* !_POWERPC_REG_H_ */ diff --git a/sys/arch/mvmeppc/include/reloc.h b/sys/arch/mvmeppc/include/reloc.h new file mode 100644 index 00000000000..210c56c2025 --- /dev/null +++ b/sys/arch/mvmeppc/include/reloc.h @@ -0,0 +1,77 @@ +/* $NetBSD: reloc.h,v 1.1 1996/09/30 16:34:33 ws Exp $ */ + +/*- + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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 _MACH_RELOC_H_ +#define _MACH_RELOC_H_ + +/* + * Quite a number of relocation types + */ +enum reloc_type { + RELOC_NONE, + RELOC_32, + RELOC_24, + RELOC_16, + RELOC_16_LO, + RELOC_16_HI, /* RELOC_ADDIS = 5 */ + RELOC_16_HA, + RELOC_14, + RELOC_14_TAKEN, + RELOC_14_NTAKEN, + RELOC_REL24, /* RELOC_BRANCH = 10 */ + RELOC_REL14, + RELOC_REL14_TAKEN, + RELOC_REL14_NTAKEN, + RELOC_GOT16, + RELOC_GOT16_LO, + RELOC_GOT16_HI, + RELOC_GOT16_HA, + RELOC_PLT24, + RELOC_COPY, + RELOC_GLOB_DAT, + RELOC_JMP_SLOT, + RELOC_RELATIVE, + RELOC_LOCAL24PC, + RELOC_U32, + RELOC_U16, + RELOC_REL32, + RELOC_PLT32, + RELOC_PLTREL32, + RELOC_PLT16_LO, + RELOC_PLT16_HI, + RELOC_PLT16_HA, + /* ABI defines this as 32nd entry, but we ignore this, at least for now */ + RELOC_SDAREL, + RELOC_MAX +}; + +#endif /* _MACH_RELOC_H_ */ diff --git a/sys/arch/mvmeppc/include/setjmp.h b/sys/arch/mvmeppc/include/setjmp.h new file mode 100644 index 00000000000..39a1f62c9b5 --- /dev/null +++ b/sys/arch/mvmeppc/include/setjmp.h @@ -0,0 +1,3 @@ +/* $NetBSD: setjmp.h,v 1.1 1996/09/30 16:34:34 ws Exp $ */ + +#define _JBLEN 100 diff --git a/sys/arch/mvmeppc/include/signal.h b/sys/arch/mvmeppc/include/signal.h new file mode 100644 index 00000000000..15e93672485 --- /dev/null +++ b/sys/arch/mvmeppc/include/signal.h @@ -0,0 +1,68 @@ +/* $OpenBSD: signal.h,v 1.1 2001/06/26 21:57:48 smurph Exp $ */ +/* $NetBSD: signal.h,v 1.1 1996/09/30 16:34:34 ws Exp $ */ + +/* + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_SIGNAL_H_ +#define _MACHINE_SIGNAL_H_ + +typedef int sig_atomic_t; + +#include <machine/types.h> + +/* + * We have to save all registers on every trap, because + * 1. user could attach this process every time + * 2. we must be able to restore all user registers in case of fork + * Actually, we do not save the fp registers on trap, since + * these are not used by the kernel. They are saved only when switching + * between processes using the FPU. + * + */ +struct trapframe { + u_int32_t fixreg[32]; + u_int32_t lr; + u_int32_t cr; + u_int32_t xer; + u_int32_t ctr; + int srr0; + int srr1; + int dar; /* dar & dsisr are only filled on a DSI trap */ + int dsisr; + u_int32_t exc; +}; + +struct sigcontext { + int sc_onstack; /* saved onstack flag */ + int sc_mask; /* saved signal mask */ + struct trapframe sc_frame; /* saved registers */ +}; +#endif /* _MACHINE_SIGNAL_H_ */ diff --git a/sys/arch/mvmeppc/include/spinlock.h b/sys/arch/mvmeppc/include/spinlock.h new file mode 100644 index 00000000000..eded853cce9 --- /dev/null +++ b/sys/arch/mvmeppc/include/spinlock.h @@ -0,0 +1,10 @@ +/* $OpenBSD: spinlock.h,v 1.1 2001/06/26 21:57:49 smurph Exp $ */ + +#ifndef _MACHINE_SPINLOCK_H_ +#define _MACHINE_SPINLOCK_H_ + +#define _SPINLOCK_UNLOCKED (0) +#define _SPINLOCK_LOCKED (1) +typedef int _spinlock_lock_t; + +#endif diff --git a/sys/arch/mvmeppc/include/stdarg.h b/sys/arch/mvmeppc/include/stdarg.h new file mode 100644 index 00000000000..15e7d1deec5 --- /dev/null +++ b/sys/arch/mvmeppc/include/stdarg.h @@ -0,0 +1,50 @@ +/* $NetBSD: stdarg.h,v 1.1 1996/09/30 16:34:35 ws 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. 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, Berkeley and its contributors. + * 4. 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_ + +#include <machine/ansi.h> + +#ifndef _STDARG_H +#define _STDARG_H +#endif +#include <machine/va-ppc.h> + +typedef _BSD_VA_LIST_ va_list; + +#endif /* !_MACHINE_STDARG_H_ */ diff --git a/sys/arch/mvmeppc/include/trap.h b/sys/arch/mvmeppc/include/trap.h new file mode 100644 index 00000000000..f8460494e16 --- /dev/null +++ b/sys/arch/mvmeppc/include/trap.h @@ -0,0 +1,84 @@ +/* $NetBSD: trap.h,v 1.1 1996/09/30 16:34:35 ws Exp $ */ + +/* + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_TRAP_H_ +#define _MACHINE_TRAP_H_ + +#define EXC_RSVD 0x0000 /* Reserved */ +#define EXC_RST 0x0100 /* Reset */ +#define EXC_MCHK 0x0200 /* Machine Check */ +#define EXC_DSI 0x0300 /* Data Storage Interrupt */ +#define EXC_ISI 0x0400 /* Instruction Storage Interrupt */ +#define EXC_EXI 0x0500 /* External Interrupt */ +#define EXC_ALI 0x0600 /* Alignment Interrupt */ +#define EXC_PGM 0x0700 /* Program Interrupt */ +#define EXC_FPU 0x0800 /* Floating-point Unavailable */ +#define EXC_DECR 0x0900 /* Decrementer Interrupt */ +#define EXC_SC 0x0c00 /* System Call */ +#define EXC_TRC 0x0d00 /* Trace */ +#define EXC_FPA 0x0e00 /* Floating-point Assist */ + +/* The following are only available on 604: */ +#define EXC_PERF 0x0f00 /* Performance Monitoring */ +#define EXC_BPT 0x1300 /* Instruction Breakpoint */ +#define EXC_SMI 0x1400 /* System Managment Interrupt */ + +/* And these are only on the 603: */ +#define EXC_IMISS 0x1000 /* Instruction translation miss */ +#define EXC_DLMISS 0x1100 /* Data load translation miss */ +#define EXC_DSMISS 0x1200 /* Data store translation miss */ + +#define EXC_LAST 0x2f00 /* Last possible exception vector */ + +#define EXC_AST 0x3000 /* Fake AST vector */ + +/* Trap was in user mode */ +#define EXC_USER 0x10000 + +/* + * EXC_ALI sets bits in the DSISR and DAR to provide enough + * information to recover from the unaligned access without needing to + * parse the offending instruction. This includes certain bits of the + * opcode, and information about what registers are used. The opcode + * indicator values below come from Appendix F of Book III of "The + * PowerPC Architecture". + */ + +#define EXC_ALI_OPCODE_INDICATOR(dsisr) ((dsisr >> 10) & 0x7f) +#define EXC_ALI_LFD 0x09 +#define EXC_ALI_STFD 0x0b + +/* Macros to extract register information */ +#define EXC_ALI_RST(dsisr) ((dsisr >> 5) & 0x1f) /* source or target */ +#define EXC_ALI_RA(dsisr) (dsisr & 0x1f) + +#endif /* _MACHINE_TRAP_H_ */ diff --git a/sys/arch/mvmeppc/include/types.h b/sys/arch/mvmeppc/include/types.h new file mode 100644 index 00000000000..87af1f45243 --- /dev/null +++ b/sys/arch/mvmeppc/include/types.h @@ -0,0 +1,70 @@ +/* $NetBSD: types.h,v 1.1 1996/09/30 16:34:36 ws Exp $ */ +/* $OpenBSD: types.h,v 1.1 2001/06/26 21:57:49 smurph Exp $ */ + +/*- + * Copyright (C) 1995 Wolfgang Solfrank. + * Copyright (C) 1995 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_TYPES_H_ +#define _MACHINE_TYPES_H_ + +#include <sys/cdefs.h> + +#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 long int64_t; +typedef unsigned long long u_int64_t; +typedef unsigned long long uint64_t; + +typedef u_int32_t register_t; + +typedef unsigned long vm_size_t; +typedef unsigned long vm_offset_t; + +typedef unsigned long vaddr_t; +typedef unsigned long paddr_t; +typedef unsigned long vsize_t; +typedef unsigned long psize_t; + +typedef struct label_t { + int val[40]; /* double check this XXX */ +} label_t; + +#define __BROKEN_INDIRECT_CONFIG + +#endif /* _MACHINE_TYPES_H_ */ diff --git a/sys/arch/mvmeppc/include/va-ppc.h b/sys/arch/mvmeppc/include/va-ppc.h new file mode 100644 index 00000000000..54486c16a94 --- /dev/null +++ b/sys/arch/mvmeppc/include/va-ppc.h @@ -0,0 +1,304 @@ +/* GNU C varargs support for the PowerPC with either the V.4 or Windows NT calling sequences */ + +#ifndef _WIN32 +/* System V.4 support */ +/* Define __gnuc_va_list. */ + +#ifndef __GNUC_VA_LIST +#define __GNUC_VA_LIST + +#ifndef _SYS_VA_LIST_H +#define _SYS_VA_LIST_H /* Solaris sys/va_list.h */ + +/* Solaris decided to rename overflow_arg_area to input_arg_area, + so handle it via a macro. */ +#define __va_overflow(AP) (AP)->overflow_arg_area + +/* Note that the names in this structure are in the user's namespace, but + that the V.4 abi explicitly states that these names should be used. */ +typedef struct __va_list_tag { + char gpr; /* index into the array of 8 GPRs stored in the + register save area gpr=0 corresponds to r3, + gpr=1 to r4, etc. */ + char fpr; /* index into the array of 8 FPRs stored in the + register save area fpr=0 corresponds to f1, + fpr=1 to f2, etc. */ + char *overflow_arg_area; /* location on stack that holds the next + overflow argument */ + char *reg_save_area; /* where r3:r10 and f1:f8, if saved are stored */ +} __va_list[1], __gnuc_va_list[1]; + +#else /* _SYS_VA_LIST */ + +typedef __va_list __gnuc_va_list; +#define __va_overflow(AP) (AP)->input_arg_area + +#endif /* not _SYS_VA_LIST */ +#endif /* not __GNUC_VA_LIST */ + +/* If this is for internal libc use, don't define anything but + __gnuc_va_list. */ +#if defined (_STDARG_H) || defined (_VARARGS_H) + +/* Register save area located below the frame pointer */ +#ifndef __VA_PPC_H__ +#define __VA_PPC_H__ +typedef struct { + long __gp_save[8]; /* save area for GP registers */ + double __fp_save[8]; /* save area for FP registers */ +} __va_regsave_t; + +/* Macros to access the register save area */ +/* We cast to void * and then to TYPE * because this avoids + a warning about increasing the alignment requirement. */ +#define __VA_FP_REGSAVE(AP,TYPE) \ + ((TYPE *) (void *) (&(((__va_regsave_t *) \ + (AP)->reg_save_area)->__fp_save[(int)(AP)->fpr]))) + +#define __VA_GP_REGSAVE(AP,TYPE) \ + ((TYPE *) (void *) (&(((__va_regsave_t *) \ + (AP)->reg_save_area)->__gp_save[(int)(AP)->gpr]))) +#if __GNUC_MINOR__ > 8 +#define GCC29 +#endif + +#ifndef GCC29 +/* Common code for va_start for both varargs and stdarg. This depends + on the format of rs6000_args in rs6000.h. The fields used are: + + #0 WORDS # words used for GP regs/stack values + #1 FREGNO next available FP register + #2 NARGS_PROTOTYPE # args left in the current prototype + #3 ORIG_NARGS original value of NARGS_PROTOTYPE + #4 VARARGS_OFFSET offset from frame pointer of varargs area */ +#else /* GCC29 */ +/* Common code for va_start for both varargs and stdarg. We allow all + the work to be done by __builtin_saveregs. It returns a pointer to + a va_list that was constructed on the stack; we must simply copy it + to the user's variable. */ +#endif /* GCC29 */ + +#ifndef GCC29 +#define __va_words __builtin_args_info (0) +#define __va_fregno __builtin_args_info (1) +#define __va_nargs __builtin_args_info (2) +#define __va_orig_nargs __builtin_args_info (3) +#define __va_varargs_offset __builtin_args_info (4) + +#define __va_start_common(AP, FAKE) \ +__extension__ ({ \ + register int __words = __va_words - FAKE; \ + \ + (AP) = (struct __va_list_tag *)__builtin_alloca(sizeof(struct __va_list_tag)); \ + (AP)->gpr = (__words < 8) ? __words : 8; \ + (AP)->fpr = __va_fregno - 33; \ + (AP)->reg_save_area = (((char *) __builtin_frame_address (0)) \ + + __va_varargs_offset); \ + __va_overflow(AP) = ((char *)__builtin_saveregs () \ + + (((__words >= 8) ? __words - 8 : 0) \ + * sizeof (long))); \ + (void)0; \ +}) +#else /* GCC29 */ +#define __va_start_common(AP, FAKE) \ +__extension__ ({ \ + (AP) = (struct __va_list_tag *)__builtin_alloca(sizeof(__gnuc_va_list)); \ + __builtin_memcpy ((AP), __builtin_saveregs (), sizeof(__gnuc_va_list)); \ + }) +#endif /* GCC29 */ + +#ifdef _STDARG_H /* stdarg.h support */ + +/* Calling __builtin_next_arg gives the proper error message if LASTARG is + not indeed the last argument. */ +#define va_start(AP,LASTARG) \ + (__builtin_next_arg (LASTARG), __va_start_common (AP, 0)) + +#else /* varargs.h support */ + +#define va_start(AP) __va_start_common (AP, 1) +#define va_alist __va_1st_arg +#define va_dcl register int va_alist; ... + +#endif /* _STDARG_H */ + +#ifdef _SOFT_FLOAT +#define __va_float_p(TYPE) 0 +#else +#define __va_float_p(TYPE) (__builtin_classify_type(*(TYPE *)0) == 8) +#endif + +#define __va_longlong_p(TYPE) \ + ((__builtin_classify_type(*(TYPE *)0) == 1) && (sizeof(TYPE) == 8)) + +#define __va_aggregate_p(TYPE) (__builtin_classify_type(*(TYPE *)0) >= 12) +#define __va_size(TYPE) ((sizeof(TYPE) + sizeof (long) - 1) / sizeof (long)) + +#ifndef GCC29 +#define va_arg(AP,TYPE) \ +__extension__ (*({ \ + register TYPE *__ptr; \ + \ + if (__va_float_p (TYPE) && (AP)->fpr < 8) \ + { \ + __ptr = __VA_FP_REGSAVE (AP, TYPE); \ + (AP)->fpr++; \ + } \ + \ + else if (__va_aggregate_p (TYPE) && (AP)->gpr < 8) \ + { \ + __ptr = * __VA_GP_REGSAVE (AP, TYPE *); \ + (AP)->gpr++; \ + } \ + \ + else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE) \ + && (AP)->gpr + __va_size(TYPE) <= 8 \ + && (!__va_longlong_p(TYPE) \ + || (AP)->gpr + __va_size(TYPE) <= 7)) \ + { \ + if (__va_longlong_p(TYPE) && ((AP)->gpr & 1) != 0) \ + (AP)->gpr++; \ + \ + __ptr = __VA_GP_REGSAVE (AP, TYPE); \ + (AP)->gpr += __va_size (TYPE); \ + } \ + \ + else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE) \ + && (AP)->gpr < 8) \ + { \ + (AP)->gpr = 8; \ + __ptr = (TYPE *) (void *) (__va_overflow(AP)); \ + __va_overflow(AP) += __va_size (TYPE) * sizeof (long); \ + } \ + \ + else if (__va_aggregate_p (TYPE)) \ + { \ + __ptr = * (TYPE **) (void *) (__va_overflow(AP)); \ + __va_overflow(AP) += sizeof (TYPE *); \ + } \ + else \ + { \ + if (__va_longlong_p(TYPE) && ((long)__va_overflow(AP) & 4) != 0) \ + __va_overflow(AP) += 4; \ + \ + __ptr = (TYPE *) (void *) (__va_overflow(AP)); \ + __va_overflow(AP) += __va_size (TYPE) * sizeof (long); \ + } \ + \ + __ptr; \ +})) +#else /* GCC29 */ +#define va_arg(AP,TYPE) \ +__extension__ (*({ \ + register TYPE *__ptr; \ + \ + if (__va_float_p (TYPE) && (AP)->fpr < 8) \ + { \ + __ptr = __VA_FP_REGSAVE (AP, TYPE); \ + (AP)->fpr++; \ + } \ + \ + else if (__va_aggregate_p (TYPE) && (AP)->gpr < 8) \ + { \ + __ptr = * __VA_GP_REGSAVE (AP, TYPE *); \ + (AP)->gpr++; \ + } \ + \ + else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE) \ + && (AP)->gpr + __va_size(TYPE) <= 8 \ + && (!__va_longlong_p(TYPE) \ + || (AP)->gpr + __va_size(TYPE) <= 8)) \ + { \ + if (__va_longlong_p(TYPE) && ((AP)->gpr & 1) != 0) \ + (AP)->gpr++; \ + \ + __ptr = __VA_GP_REGSAVE (AP, TYPE); \ + (AP)->gpr += __va_size (TYPE); \ + } \ + \ + else if (!__va_float_p (TYPE) && !__va_aggregate_p (TYPE) \ + && (AP)->gpr < 8) \ + { \ + (AP)->gpr = 8; \ + __ptr = (TYPE *) (void *) (__va_overflow(AP)); \ + __va_overflow(AP) += __va_size (TYPE) * sizeof (long); \ + } \ + \ + else if (__va_aggregate_p (TYPE)) \ + { \ + __ptr = * (TYPE **) (void *) (__va_overflow(AP)); \ + __va_overflow(AP) += sizeof (TYPE *); \ + } \ + else \ + { \ + __ptr = (TYPE *) (void *) (__va_overflow(AP)); \ + __va_overflow(AP) += __va_size (TYPE) * sizeof (long); \ + } \ + \ + __ptr; \ +})) +#endif /* not GCC29 */ + +#define va_end(AP) ((void)0) + +/* Copy __gnuc_va_list into another variable of this type. */ +#define __va_copy(dest, src) *(dest) = *(src) + +#endif /* __VA_PPC_H__ */ +#endif /* defined (_STDARG_H) || defined (_VARARGS_H) */ + + +#else +/* Windows NT */ +/* Define __gnuc_va_list. */ + +#ifndef __GNUC_VA_LIST +#define __GNUC_VA_LIST +typedef char *__gnuc_va_list; +#endif /* not __GNUC_VA_LIST */ + +/* If this is for internal libc use, don't define anything but + __gnuc_va_list. */ +#if defined (_STDARG_H) || defined (_VARARGS_H) + +#define __va_start_common(AP, LASTARG, FAKE) \ + ((__builtin_saveregs ()), ((AP) = ((char *) &LASTARG) + __va_rounded_size (AP)), 0) + +#ifdef _STDARG_H /* stdarg.h support */ + +/* Calling __builtin_next_arg gives the proper error message if LASTARG is + not indeed the last argument. */ +#define va_start(AP,LASTARG) \ + (__builtin_saveregs (), \ + (AP) = __builtin_next_arg (LASTARG), \ + 0) + +#else /* varargs.h support */ + +#define va_start(AP) \ + (__builtin_saveregs (), \ + (AP) = __builtin_next_arg (__va_1st_arg) - sizeof (int), \ + 0) + +#define va_alist __va_1st_arg +#define va_dcl register int __va_1st_arg; ... + +#endif /* _STDARG_H */ + +#define __va_rounded_size(TYPE) ((sizeof (TYPE) + 3) & ~3) +#define __va_align(AP, TYPE) \ + ((((unsigned long)(AP)) + ((sizeof (TYPE) >= 8) ? 7 : 3)) \ + & ~((sizeof (TYPE) >= 8) ? 7 : 3)) + +#define va_arg(AP,TYPE) \ +( *(TYPE *)((AP = (char *) (__va_align(AP, TYPE) \ + + __va_rounded_size(TYPE))) \ + - __va_rounded_size(TYPE))) + +#define va_end(AP) ((void)0) + +/* Copy __gnuc_va_list into another variable of this type. */ +#define __va_copy(dest, src) (dest) = (src) + +#endif /* defined (_STDARG_H) || defined (_VARARGS_H) */ +#endif /* Windows NT */ diff --git a/sys/arch/mvmeppc/include/varargs.h b/sys/arch/mvmeppc/include/varargs.h new file mode 100644 index 00000000000..ee015e0500b --- /dev/null +++ b/sys/arch/mvmeppc/include/varargs.h @@ -0,0 +1,53 @@ +/* $NetBSD: varargs.h,v 1.1 1996/09/30 16:34:37 ws Exp $ */ + +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. 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. + * + * @(#)varargs.h 8.2 (Berkeley) 3/22/94 + */ + +#ifndef _PPC_VARARGS_H_ +#define _PPC_VARARGS_H_ + +#define _VARARGS_H + +#include <machine/ansi.h> +#include <machine/va-ppc.h> + +typedef _BSD_VA_LIST_ va_list; + +#endif /* !_PPC_VARARGS_H_ */ diff --git a/sys/arch/mvmeppc/include/vmparam.h b/sys/arch/mvmeppc/include/vmparam.h new file mode 100644 index 00000000000..4a7a8d4ee8d --- /dev/null +++ b/sys/arch/mvmeppc/include/vmparam.h @@ -0,0 +1,125 @@ +/* $NetBSD: vmparam.h,v 1.1 1996/09/30 16:34:38 ws Exp $ */ + +/*- + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_VMPARAM_H +#define MACHINE_VMPARAM_H + +#define USRTEXT PAGE_SIZE +#define USRSTACK VM_MAXUSER_ADDRESS + +#ifndef MAXTSIZ +#define MAXTSIZ (16*1024*1024) /* max text size */ +#endif + +#ifndef DFLDSIZ +#define DFLDSIZ (32*1024*1024) /* default data size */ +#endif + +#ifndef MAXDSIZ +#define MAXDSIZ (512*1024*1024) /* max data size */ +#endif + +#ifndef DFLSSIZ +#define DFLSSIZ (1*1024*1024) /* default stack size */ +#endif + +#ifndef MAXSSIZ +#define MAXSSIZ (32*1024*1024) /* max stack size */ +#endif + +/* + * Min & Max swap space allocation chunks + */ +#define DMMIN 32 +#define DMMAX 4096 + +/* + * Size of shared memory map + */ +#ifndef SHMMAXPGS +#define SHMMAXPGS 1024 +#endif + +/* + * Size of User Raw I/O map + */ +#define USRIOSIZE 1024 + +/* + * The time for a process to be blocked before being very swappable. + * This is a number of seconds which the system takes as being a non-trivial + * amount of real time. You probably shouldn't change this; + * it is used in subtle ways (fractions and multiples of it are, that is, like + * half of a ``long time'', almost a long time, etc.) + * It is related to human patience and other factors which don't really + * change over time. + */ +#define MAXSLP 20 + +/* + * Would like to have MAX addresses = 0, but this doesn't (currently) work + */ +#define VM_MIN_ADDRESS ((vm_offset_t)0) +#define VM_MAXUSER_ADDRESS ((vm_offset_t)0xfffff000) +#define VM_MAX_ADDRESS VM_MAXUSER_ADDRESS +#define VM_MIN_KERNEL_ADDRESS ((vm_offset_t)(KERNEL_SR << ADDR_SR_SHFT)) + +/* ppc_kvm_size is so that vm space can be stolen before vm is fully + * initialized. + */ +#define VM_KERN_ADDR_SIZE_DEF SEGMENT_LENGTH +extern vm_offset_t ppc_kvm_size; +#define VM_KERN_ADDRESS_SIZE (ppc_kvm_size) +#define VM_MAX_KERNEL_ADDRESS ((vm_offset_t)((KERNEL_SR << ADDR_SR_SHFT) \ + + VM_KERN_ADDRESS_SIZE)) + +#define MACHINE_NEW_NONCONTIG /* VM <=> pmap interface modifier */ + +#define VM_KMEM_SIZE (NKMEMCLUSTERS * PAGE_SIZE) +#define VM_MBUF_SIZE (NMBCLUSTERS * PAGE_SIZE) +#define VM_PHYS_SIZE (USRIOSIZE * PAGE_SIZE) + +struct pmap_physseg { + struct pv_entry *pvent; + char *attrs; + /* NULL ??? */ +}; + +#define VM_PHYSSEG_MAX 32 /* actually we could have this many segments */ +#define VM_PHYSSEG_STRAT VM_PSTRAT_BSEARCH +#define VM_PHYSSEG_NOADD /* can't add RAM after vm_mem_init */ + +#define VM_NFREELIST 1 +#define VM_FREELIST_DEFAULT 0 + +#endif diff --git a/sys/arch/mvmeppc/include/vuid_event.h b/sys/arch/mvmeppc/include/vuid_event.h new file mode 100644 index 00000000000..3ecbdcb7a3a --- /dev/null +++ b/sys/arch/mvmeppc/include/vuid_event.h @@ -0,0 +1,88 @@ +/* $OpenBSD: vuid_event.h,v 1.1 2001/06/26 21:57:50 smurph Exp $ */ +/* $NetBSD: vuid_event.h,v 1.1 1996/04/12 01:45:47 cgd 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. 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, Berkeley and its contributors. + * 4. 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. + * + * @(#)vuid_event.h 8.1 (Berkeley) 6/11/93 + */ + +/* + * The following is a minimal emulation of Sun's `Firm_event' structures + * and related operations necessary to make X11 happy (i.e., make it + * compile, and make old X11 binaries run). + */ +typedef struct firm_event { + u_short id; /* key or MS_* or LOC_[XY]_DELTA */ + u_short pad; /* unused, at least by X11 */ + int value; /* VKEY_{UP,DOWN} or locator delta */ + struct timeval time; +} Firm_event; + +/* + * Special `id' fields. These weird numbers simply match the old binaries. + * Others are in 0..0x7f and are keyboard key numbers (keyboard dependent!). + */ +#define MS_LEFT 0x7f20 /* left mouse button */ +#define MS_MIDDLE 0x7f21 /* middle mouse button */ +#define MS_RIGHT 0x7f22 /* right mouse button */ +#define LOC_X_DELTA 0x7f80 /* mouse delta-X */ +#define LOC_Y_DELTA 0x7f81 /* mouse delta-Y */ +#define LOC_X_ABSOLUTE 0x7f82 /* X compat, unsupported */ +#define LOC_Y_ABSOLUTE 0x7f83 /* X compat, unsupported */ + +/* + * Special `value' fields. These apply to keys and mouse buttons. The + * value of a mouse delta is the delta. Note that positive deltas are + * left and up (not left and down as you might expect). + */ +#define VKEY_UP 0 /* key or button went up */ +#define VKEY_DOWN 1 /* key or button went down */ + +/* + * The following ioctls are clearly intended to take things in and out + * of `firm event' mode. Since we always run in this mode (as far as + * /dev/kbd and /dev/mouse are concerned, anyway), we always claim to + * be in this mode and reject anything else. + */ +#define VUIDSFORMAT _IOW('v', 1, int) +#define VUIDGFORMAT _IOR('v', 2, int) +#define VUID_FIRM_EVENT 1 /* the only format we support */ diff --git a/sys/arch/mvmeppc/include/wsconsio.h b/sys/arch/mvmeppc/include/wsconsio.h new file mode 100644 index 00000000000..37ae8d06b5c --- /dev/null +++ b/sys/arch/mvmeppc/include/wsconsio.h @@ -0,0 +1,62 @@ +/* $OpenBSD: wsconsio.h,v 1.1 2001/06/26 21:57:50 smurph Exp $ */ +/* $NetBSD: wsconsio.h,v 1.1 1996/04/12 01:43:06 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. + */ + +/* + * Get keyboard type. Keyboard type definitions are below. + */ +#define WSCONSIO_KBD_GTYPE _IOR('W',100,int) +#define KBD_TYPE_LK201 0 /* lk-201 */ +#define KBD_TYPE_LK401 1 /* lk-401 */ +#define KBD_TYPE_PC 2 /* pc-like */ + +/* + * If arg is one, don't process scancodes into characters + */ +#define WSCONSIO_KBD_SCANCODES _IO('W',101,int) + +/* + * Bell ioctls. + */ + +struct wsconsio_bell_data { + int wbd_flags; + int wbd_pitch; /* pitch, in Hz. */ + int wbd_period; /* period, in milliseconds. */ + int wbd_volume; /* percentage of maximum volume. */ +}; + +#define WSCONSIO_BELLDATA_PITCH 0x01 /* pitch data present */ +#define WSCONSIO_BELLDATA_PERIOD 0x02 /* period data present */ +#define WSCONSIO_BELLDATA_VOLUME 0x04 /* volume data present */ + +#define WSCONSIO_BELL _IO('W',102) +#define WSCONSIO_COMPLEXBELL _IOW('W',103,struct wsconsio_bell_data) +#define WSCONSIO_SETBELL _IOW('W',104,struct wsconsio_bell_data) +#define WSCONSIO_GETBELL _IOR('W',105,struct wsconsio_bell_data) diff --git a/sys/arch/mvmeppc/isa/isa_machdep.c b/sys/arch/mvmeppc/isa/isa_machdep.c new file mode 100644 index 00000000000..15aa605bfc3 --- /dev/null +++ b/sys/arch/mvmeppc/isa/isa_machdep.c @@ -0,0 +1,185 @@ +/* $OpenBSD: isa_machdep.c,v 1.1 2001/06/26 21:57:51 smurph Exp $ */ +/* $NetBSD: isa_machdep.c,v 1.22 1997/06/12 23:57:32 thorpej Exp $ */ + +#define ISA_DMA_STATS + +/*- + * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center. + * + * 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. + */ + +/*- + * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center. + * + * 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. + */ + +/*- + * Copyright (c) 1993, 1994, 1996, 1997 + * Charles M. Hannum. All rights reserved. + * Copyright (c) 1991 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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 University of + * California, Berkeley and its contributors. + * 4. 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. + * + * @(#)isa.c 7.2 (Berkeley) 5/13/91 + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/syslog.h> +#include <sys/device.h> +#include <sys/malloc.h> +#include <sys/proc.h> + +#include <vm/vm.h> + +#include <machine/bus.h> + +#include <machine/pio.h> + +#include <dev/isa/isareg.h> +#include <dev/isa/isavar.h> +#include <dev/isa/isadmavar.h> +#include <powerpc/isa/isa_machdep.h> + +void *i8259_intr_establish( void * lcv, int irq, int type, int level, + int (*ih_fun) __P((void *)), void *ih_arg, char *name); + +int isa_has_been_seen = 0; + +/* + * Set up an interrupt handler to start being called. + * XXX PRONE TO RACE CONDITIONS, UGLY, 'INTERESTING' INSERTION ALGORITHM. + */ +void * +isa_intr_establish(ic, irq, type, level, ih_fun, ih_arg, ih_what) + isa_chipset_tag_t ic; + int irq; + int type; + int level; + int (*ih_fun) __P((void *)); + void *ih_arg; + char *ih_what; +{ + return(i8259_intr_establish(ic, irq, type, level, ih_fun, ih_arg, ih_what)); +} + +/* + * Deregister an interrupt handler. + */ +void +isa_intr_disestablish(ic, arg) + isa_chipset_tag_t ic; + void *arg; +{ + openpic_intr_disestablish(ic, arg); +} + +void +isa_attach_hook(parent, self, iba) + struct device *parent, *self; + struct isabus_attach_args *iba; +{ + + /* + * Notify others that might need to know that the ISA bus + * has now been attached. + */ + if (isa_has_been_seen) + panic("isaattach: ISA bus already seen!"); + isa_has_been_seen = 1; +} + diff --git a/sys/arch/mvmeppc/isa/isa_machdep.h b/sys/arch/mvmeppc/isa/isa_machdep.h new file mode 100644 index 00000000000..a8174c14808 --- /dev/null +++ b/sys/arch/mvmeppc/isa/isa_machdep.h @@ -0,0 +1,69 @@ +/* $OpenBSD: isa_machdep.h,v 1.1 2001/06/26 21:57:51 smurph Exp $ */ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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 University of + * California, Berkeley and its contributors. + * 4. 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. + * + * @(#)isa.h 5.7 (Berkeley) 5/9/91 + */ +#ifndef _MVMEPPC_ISA_MACHDEP_H_ /* XXX */ +#define _MVMEPPC_ISA_MACHDEP_H_ /* XXX */ + +#include <machine/bus.h> + +/* + * Types provided to machine-independent ISA code. + */ +typedef void *isa_chipset_tag_t; + +struct device; /* XXX */ +struct isabus_attach_args; /* XXX */ + +/* + * Functions provided to machine-independent ISA code. + */ +void isa_attach_hook __P((struct device *, struct device *, + struct isabus_attach_args *)); +void *isa_intr_establish __P((isa_chipset_tag_t ic, int irq, int type, + int level, int (*ih_fun)(void *), void *ih_arg, char *ih_what)); +void isa_intr_disestablish __P((isa_chipset_tag_t ic, void *handler)); + +#define __NO_ISA_INTR_CHECK +/* + * ALL OF THE FOLLOWING ARE MACHINE-DEPENDENT, AND SHOULD NOT BE USED + * BY PORTABLE CODE. + */ + +extern struct powerpc_bus_dma_tag isa_bus_dma_tag; + +#endif /* _MVMEPPC_ISA_MACHDEP_H_ XXX */ diff --git a/sys/arch/mvmeppc/mvmeppc/Locore.c b/sys/arch/mvmeppc/mvmeppc/Locore.c new file mode 100644 index 00000000000..9b77cd4d198 --- /dev/null +++ b/sys/arch/mvmeppc/mvmeppc/Locore.c @@ -0,0 +1,89 @@ +/* $OpenBSD: Locore.c,v 1.1 2001/06/26 21:57:52 smurph Exp $ */ + +/* + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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. + */ + +/* + * Some additional routines that happened to be in locore.S traditionally, + * but have no need to be coded in assembly. + */ + +#include <sys/param.h> +#include <sys/proc.h> + +int whichqs; + +/* + * Put process p on the run queue, given by its priority. + * Calls should be made at splstatclock(), and p->p_stat should be SRUN. + */ +void +setrunqueue(p) + struct proc *p; +{ + struct prochd *q; + struct proc *oldlast; + int which = p->p_priority >> 2; + +#ifdef DIAGNOSTIC + if (p->p_back) + panic("setrunqueue"); +#endif + q = &qs[which]; + whichqs |= 0x80000000 >> which; + p->p_forw = (struct proc *)q; + p->p_back = oldlast = q->ph_rlink; + q->ph_rlink = p; + oldlast->p_forw = p; +} + +/* + * Remove process p from its run queue, given by its priority. + * Calls should be made at splstatclock(). + */ +void +remrunqueue(p) + struct proc *p; +{ + int which = p->p_priority >> 2; + struct prochd *q; + +#ifdef DIAGNOSTIC + if (!(whichqs & (0x80000000 >> which))) + panic("remrunqueue"); +#endif + p->p_forw->p_back = p->p_back; + p->p_back->p_forw = p->p_forw; + p->p_back = NULL; + q = &qs[which]; + if (q->ph_link == (struct proc *)q) + whichqs &= ~(0x80000000 >> which); +} diff --git a/sys/arch/mvmeppc/mvmeppc/autoconf.c b/sys/arch/mvmeppc/mvmeppc/autoconf.c new file mode 100644 index 00000000000..9da26166a8d --- /dev/null +++ b/sys/arch/mvmeppc/mvmeppc/autoconf.c @@ -0,0 +1,613 @@ +/* $OpenBSD: autoconf.c,v 1.1 2001/06/26 21:57:52 smurph Exp $ */ +/* + * Copyright (c) 1996, 1997 Per Fogelstrom + * Copyright (c) 1995 Theo de Raadt + * Copyright (c) 1988 University of Utah. + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * the Systems Programming Group of the University of Utah Computer + * Science Department and Ralph Campbell. + * + * 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 University of + * California, Berkeley and its contributors. + * 4. 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. + * + * from: Utah Hdr: autoconf.c 1.31 91/01/21 + * + * from: @(#)autoconf.c 8.1 (Berkeley) 6/10/93 + * $Id: autoconf.c,v 1.1 2001/06/26 21:57:52 smurph Exp $ + */ + +/* + * Setup the system to run on the current machine. + * + * Configure() is called at boot time. Available + * devices are determined (from possibilities mentioned in ioconf.c), + * and the drivers are initialized. + */ + +#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 <machine/autoconf.h> + +struct device *parsedisk __P((char *, int, int, dev_t *)); +void setroot __P((void)); +void swapconf __P((void)); +extern void dumpconf __P((void)); +static int findblkmajor __P((struct device *)); +static struct device * getdisk __P((char *, int, int, dev_t *)); +struct device * getdevunit __P((char *, int)); +static struct devmap * findtype __P((char **)); +void makebootdev __P((char *cp)); +int getpno __P((char **)); +void diskconf(); + +/* + * The following several variables are related to + * the configuration process, and are used in initializing + * the machine. + */ +int cold = 1; /* if 1, still working on cold-start */ +char bootdev[16]; /* to hold boot dev name */ +struct device *bootdv = NULL; + +/* + * Configure all devices found that we know about. + * This is done at boot time. + */ +void +cpu_configure() +{ + (void)splhigh(); /* To be really sure.. */ + calc_delayconst(); + + /* + if(system_type == OFWMACH) { + ofrootfound(); + } + */ + if(config_rootfound("mainbus", "mainbus") == 0) + panic("no mainbus found"); + (void)spl0(); + + /* + * We can not know which is our root disk, defer + * until we can checksum blocks to figure it out. + */ + md_diskconf = diskconf; + cold = 0; +} +/* + * Now that we are fully operational, we can checksum the + * disks, and using some heuristics, hopefully are able to + * always determine the correct root disk. + */ +void +diskconf() +{ + /* + * Configure root, swap, and dump area. This is + * currently done by running the same checksum + * algorithm over all known disks, as was done in + * /boot. Then we basically fixup the *dev vars + * from the info we gleaned from this. + dkcsumattach(); + * - XXX + */ + +#if 0 + rootconf(); +#endif + setroot(); + swapconf(); +#if 0 + dumpconf(); +#endif +} + +/* + * Configure swap space and related parameters. + */ +void +swapconf() +{ + register struct swdevt *swp; + register int nblks; + + for (swp = swdevt; swp->sw_dev != NODEV; swp++) { + if (bdevsw[major(swp->sw_dev)].d_psize) { + nblks = + (*bdevsw[major(swp->sw_dev)].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)); + } + } +#if 0 + dumpconf(); +#endif +} + +/* + * Crash dump handling. + */ +u_long dumpmag = 0x8fca0101; /* magic number */ +int dumpsize = 0; /* size of dump in pages */ +long dumplo = -1; /* blocks */ + +/* + * 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. + */ +#if 0 +void +dumpconf() +{ + int nblks; /* size of dump area */ + int maj; + + if (dumpdev == NODEV) + return; + maj = major(dumpdev); + if (maj < 0 || maj >= nblkdev) + panic("dumpconf: bad dumpdev=0x%x", dumpdev); + if (bdevsw[maj].d_psize == NULL) + return; + nblks = (*bdevsw[maj].d_psize)(dumpdev); + if (nblks <= ctod(1)) + return; + + dumpsize = btoc(IOM_END + ctob(dumpmem_high)); + + /* Always skip the first CLBYTES, in case there is a label there. */ + if (dumplo < ctod(1)) + dumplo = ctod(1); + + /* Put dump at end of partition, and make it fit. */ + if (dumpsize > dtoc(nblks - dumplo)) + dumpsize = dtoc(nblks - dumplo); + if (dumplo < nblks - ctod(dumpsize)) + dumplo = nblks - ctod(dumpsize); +} +#endif + +static struct nam2blk { + char *name; + int maj; +} nam2blk[] = { + { "wd", 0 }, /* 0 = wd */ + { "sd", 2 }, /* 2 = sd */ + { "ofdisk", 4 }, /* 4 = ofdisk */ +}; + +static int +findblkmajor(dv) + struct device *dv; +{ + char *name = dv->dv_xname; + register int i; + + for (i = 0; i < sizeof(nam2blk)/sizeof(nam2blk[0]); ++i) + if (strncmp(name, nam2blk[i].name, strlen(nam2blk[0].name)) == 0) + return (nam2blk[i].maj); + return (-1); +} + +static struct device * +getdisk(str, len, defpart, devp) + char *str; + int len, defpart; + dev_t *devp; +{ + register struct device *dv; + + if ((dv = parsedisk(str, len, defpart, devp)) == NULL) { + printf("use one of:"); + for (dv = alldevs.tqh_first; dv != NULL; + dv = dv->dv_list.tqe_next) { + if (dv->dv_class == DV_DISK) + printf(" %s[a-h]", dv->dv_xname); +#ifdef NFSCLIENT + if (dv->dv_class == DV_IFNET) + printf(" %s", dv->dv_xname); +#endif + } + printf("\n"); + } + return (dv); +} + +struct device * +parsedisk(str, len, defpart, devp) + char *str; + int len, defpart; + dev_t *devp; +{ + register struct device *dv; + register char *cp, c; + int majdev, part; + + if (len == 0) + return (NULL); + cp = str + len - 1; + c = *cp; + if (c >= 'a' && (c - 'a') < MAXPARTITIONS) { + part = c - 'a'; + *cp = '\0'; + } else + part = defpart; + + 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) { + 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); +} + +/* + * 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. + */ +void +setroot() +{ + int majdev, mindev, unit, part, len; + dev_t temp; + struct swdevt *swp; + struct device *dv; + dev_t nrootdev, nswapdev = NODEV; + char buf[128]; + +#if defined(NFSCLIENT) + extern char *nfsbootdevname; +#endif + + printf("bootpath: '%s'\n", bootpath); + makebootdev(bootpath); + if(boothowto & RB_DFLTROOT) + return; /* Boot compiled in */ + + /* Lookup boot device from boot if not set by configuration */ + if(bootdv == NULL) { + bootdv = parsedisk(bootdev, strlen(bootdev), 0, &temp); + } + if(bootdv == NULL) { + printf("boot device: lookup '%s' failed.\n", bootdev); + boothowto |= RB_ASKNAME; /* Don't Panic :-) */ + /* boothowto |= RB_SINGLE; */ + } + else { + printf("boot device: %s.\n", bootdv->dv_xname); + } + + if (boothowto & RB_ASKNAME) { + for (;;) { + printf("root device "); + if (bootdv != NULL) + printf("(default %s%c)", + bootdv->dv_xname, + bootdv->dv_class == DV_DISK + ? 'a' : ' '); + printf(": "); + len = getsn(buf, sizeof(buf)); + if (len == 0 && bootdv != NULL) { + strcpy(buf, bootdv->dv_xname); + len = strlen(buf); + } + if (len > 0 && buf[len - 1] == '*') { + buf[--len] = '\0'; + dv = getdisk(buf, len, 1, &nrootdev); + if (dv != NULL) { + bootdv = dv; + nswapdev = nrootdev; + goto gotswap; + } + } + dv = getdisk(buf, len, 0, &nrootdev); + if (dv != NULL) { + bootdv = dv; + break; + } + } + /* + * because swap must be on same device as root, for + * network devices this is easy. + */ + if (bootdv->dv_class == DV_IFNET) { + goto gotswap; + } + for (;;) { + printf("swap device "); + if (bootdv != NULL) + printf("(default %s%c)", + bootdv->dv_xname, + bootdv->dv_class == DV_DISK?'b':' '); + printf(": "); + len = getsn(buf, sizeof(buf)); + if (len == 0 && bootdv != NULL) { + switch (bootdv->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; + } + break; + } + dv = getdisk(buf, len, 1, &nswapdev); + if (dv) { + if (dv->dv_class == DV_IFNET) + nswapdev = NODEV; + break; + } + } + +gotswap: + 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. + */ + if (bootdv == NULL) + panic("boot device not known"); + + majdev = findblkmajor(bootdv); + + if (majdev >= 0) { + /* + * Root and Swap are on disk. + * Boot is always from partition 0. + */ + rootdev = MAKEDISKDEV(majdev, bootdv->dv_unit, 0); + nswapdev = MAKEDISKDEV(majdev, bootdv->dv_unit, 1); + dumpdev = nswapdev; + } + else { + /* + * Root and Swap are on net. + */ + 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. + */ + return; + } + + switch (bootdv->dv_class) { +#if defined(NFSCLIENT) + case DV_IFNET: + mountroot = nfs_mountroot; + nfsbootdevname = bootdv->dv_xname; + return; +#endif + case DV_DISK: + mountroot = dk_mountroot; + majdev = major(rootdev); + mindev = minor(rootdev); + unit = DISKUNIT(rootdev); + part = DISKPART(rootdev); + printf("root on %s%c\n", bootdv->dv_xname, part + 'a'); + break; + default: + printf("can't figure root, hope your kernel is right\n"); + return; + } + + /* + * XXX: What is this doing? + */ + temp = NODEV; + for (swp = swdevt; swp->sw_dev != NODEV; swp++) { + if (majdev == major(swp->sw_dev) && + unit == 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; +} + +/* + * find a device matching "name" and unit number + */ +struct device * +getdevunit(name, unit) + char *name; + int unit; +{ + struct device *dev = alldevs.tqh_first; + char num[10], fullname[16]; + int lunit; + + /* compute length of name and decimal expansion of unit number */ + sprintf(num, "%d", unit); + lunit = strlen(num); + if (strlen(name) + lunit >= sizeof(fullname) - 1) + panic("config_attach: device name too long"); + + strcpy(fullname, name); + strcat(fullname, num); + + while (strcmp(dev->dv_xname, fullname) != 0) { + if ((dev = dev->dv_list.tqe_next) == NULL) + return NULL; + } + return dev; +} + +struct devmap { + char *att; + char *dev; + int type; +}; +#define T_IFACE 0x10 + +#define T_BUS 0x00 +#define T_SCSI 0x11 +#define T_IDE 0x12 +#define T_DISK 0x21 + +static struct devmap * +findtype(s) + char **s; +{ + static struct devmap devmap[] = { + { "/pci@", NULL, T_BUS }, + { "/pci", NULL, T_BUS }, + { "/mac-io@", NULL, T_BUS }, + { "/mac-io", NULL, T_BUS }, + { "/@", NULL, T_BUS }, + { "/scsi@", "sd", T_SCSI }, + { "/ide", "wd", T_IDE }, + { "/ata", "wd", T_IDE }, + { "/disk@", "sd", T_DISK }, + { "/disk", "wd", T_DISK }, + { NULL, NULL } + }; + struct devmap *dp = &devmap[0]; + + while (dp->att) { + if (strncmp (*s, dp->att, strlen(dp->att)) == 0) { + *s += strlen(dp->att); + break; + } + dp++; + } + if (dp->att == NULL) { + printf("string [%s]not found\n", *s); + } + return(dp); +} + +/* + * Look at the string 'bp' and decode the boot device. + * Boot names look like: '/pci/scsi@c/disk@0,0/bsd' + * '/pci/mac-io/ide@20000/disk@0,0/bsd + * '/pci/mac-io/ide/disk/bsd + */ +void +makebootdev(bp) + char *bp; +{ + int unit; + char *dev, *cp; + struct devmap *dp; + + cp = bp; + do { + while(*cp && *cp != '/') { + cp++; + } + dp = findtype(&cp); + if (!dp->att) { + printf("Warning: boot device unrecognized: %s\n", bp); + return; + } + } while((dp->type & T_IFACE) == 0); + + dev = dp->dev; + while(*cp && *cp != '/') + cp++; + dp = findtype(&cp); + if (!dp->att || dp->type != T_DISK) { + printf("Warning: boot device unrecognized: %s\n", bp); + return; + } + unit = getpno(&cp); + sprintf(bootdev, "%s%d%c", dev, unit, 'a'); +} + +int +getpno(cp) + char **cp; +{ + int val = 0; + char *cx = *cp; + + while(*cx && *cx >= '0' && *cx <= '9') { + val = val * 10 + *cx - '0'; + cx++; + } + *cp = cx; + return val; +} diff --git a/sys/arch/mvmeppc/mvmeppc/bcopy.c b/sys/arch/mvmeppc/mvmeppc/bcopy.c new file mode 100644 index 00000000000..25835d24b59 --- /dev/null +++ b/sys/arch/mvmeppc/mvmeppc/bcopy.c @@ -0,0 +1,144 @@ +/* $OpenBSD: bcopy.c,v 1.1 2001/06/26 21:57:52 smurph Exp $ */ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * 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 University of + * California, Berkeley and its contributors. + * 4. 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)bcopy.c 5.11 (Berkeley) 6/21/91";*/ +static char *rcsid = "$Id: bcopy.c,v 1.1 2001/06/26 21:57:52 smurph Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include <sys/cdefs.h> +/* +#include <string.h> +*/ +#include <sys/types.h> + +/* + * sizeof(word) MUST BE A POWER OF TWO + * SO THAT wmask BELOW IS ALL ONES + */ +typedef int word; /* "word" used for optimal copy speed */ + +#define wsize sizeof(word) +#define wmask (wsize - 1) + +/* + * Copy a block of memory, handling overlap. + * This is the routine that actually implements + * (the portable versions of) bcopy, memcpy, and memmove. + */ +#ifdef MEMCOPY +void * +memcpy(dst0, src0, length) +#else +#ifdef MEMMOVE +void * +memmove(dst0, src0, length) +#else +void +bcopy(src0, dst0, length) +#endif +#endif + void *dst0; + const void *src0; + register size_t length; +{ + register char *dst = dst0; + register const char *src = src0; + register size_t t; + + if (length == 0 || dst == src) /* nothing to do */ + goto done; + + /* + * Macros: loop-t-times; and loop-t-times, t>0 + */ +#define TLOOP(s) if (t) TLOOP1(s) +#define TLOOP1(s) do { s; } while (--t) + + if ((unsigned long)dst < (unsigned long)src) { + /* + * Copy forward. + */ + t = (int)src; /* only need low bits */ + if ((t | (int)dst) & wmask) { + /* + * Try to align operands. This cannot be done + * unless the low bits match. + */ + if ((t ^ (int)dst) & wmask || length < wsize) + t = length; + else + t = wsize - (t & wmask); + length -= t; + TLOOP1(*dst++ = *src++); + } + /* + * Copy whole words, then mop up any trailing bytes. + */ + t = length / wsize; + TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize); + t = length & wmask; + TLOOP(*dst++ = *src++); + } else { + /* + * Copy backwards. Otherwise essentially the same. + * Alignment works as before, except that it takes + * (t&wmask) bytes to align, not wsize-(t&wmask). + */ + src += length; + dst += length; + t = (int)src; + if ((t | (int)dst) & wmask) { + if ((t ^ (int)dst) & wmask || length <= wsize) + t = length; + else + t &= wmask; + length -= t; + TLOOP1(*--dst = *--src); + } + t = length / wsize; + TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src); + t = length & wmask; + TLOOP(*--dst = *--src); + } +done: +#if defined(MEMCOPY) || defined(MEMMOVE) + return (dst0); +#else + return; +#endif +} diff --git a/sys/arch/mvmeppc/mvmeppc/bus_dma.c b/sys/arch/mvmeppc/mvmeppc/bus_dma.c new file mode 100644 index 00000000000..2cc91cf07be --- /dev/null +++ b/sys/arch/mvmeppc/mvmeppc/bus_dma.c @@ -0,0 +1,654 @@ +/* $NetBSD: bus_dma.c,v 1.2 2001/06/10 02:31:25 briggs Exp $ */ + +/*- + * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center. + * + * 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. + */ + +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/user.h> +#include <sys/extent.h> +#include <sys/buf.h> +#include <sys/device.h> +#include <sys/systm.h> +#include <sys/conf.h> +#include <sys/file.h> +#include <sys/malloc.h> +#include <sys/mbuf.h> +#include <sys/mount.h> + +#include <vm/vm.h> +#include <vm/vm_kern.h> +#ifdef UVM +#include <uvm/uvm.h> +#include <uvm/uvm_page.h> +#else +#endif + +#define _POWERPC_BUS_DMA_PRIVATE +#include <machine/bus.h> +#include <machine/intr.h> + +int _bus_dmamap_load_buffer (bus_dma_tag_t, bus_dmamap_t, void *, + bus_size_t, struct proc *, int, paddr_t *, int *, int); + +/* + * Common function for DMA map creation. May be called by bus-specific + * DMA map creation functions. + */ +int +_bus_dmamap_create(t, size, nsegments, maxsegsz, boundary, flags, dmamp) + bus_dma_tag_t t; + bus_size_t size; + int nsegments; + bus_size_t maxsegsz; + bus_size_t boundary; + int flags; + bus_dmamap_t *dmamp; +{ + struct powerpc_bus_dmamap *map; + void *mapstore; + size_t mapsize; + + /* + * Allocate and initialize the DMA map. The end of the map + * is a variable-sized array of segments, so we allocate enough + * room for them in one shot. + * + * Note we don't preserve the WAITOK or NOWAIT flags. Preservation + * of ALLOCNOW notifies others that we've reserved these resources, + * and they are not to be freed. + * + * The bus_dmamap_t includes one bus_dma_segment_t, hence + * the (nsegments - 1). + */ + mapsize = sizeof(struct powerpc_bus_dmamap) + + (sizeof(bus_dma_segment_t) * (nsegments - 1)); + if ((mapstore = malloc(mapsize, M_DEVBUF, + (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK)) == NULL) + return (ENOMEM); + + memset(mapstore, 0, mapsize); + map = (struct powerpc_bus_dmamap *)mapstore; + map->_dm_size = size; + map->_dm_segcnt = nsegments; + map->_dm_maxsegsz = maxsegsz; + map->_dm_boundary = boundary; + map->_dm_bounce_thresh = t->_bounce_thresh; + map->_dm_flags = flags & ~(BUS_DMA_WAITOK|BUS_DMA_NOWAIT); + map->dm_mapsize = 0; /* no valid mappings */ + map->dm_nsegs = 0; + + *dmamp = map; + return (0); +} + +/* + * Common function for DMA map destruction. May be called by bus-specific + * DMA map destruction functions. + */ +void +_bus_dmamap_destroy(t, map) + bus_dma_tag_t t; + bus_dmamap_t 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 entrance, and the ending segment on exit. + * first indicates if this is the first invocation of this function. + */ +int +_bus_dmamap_load_buffer(t, map, buf, buflen, p, flags, lastaddrp, segp, first) + 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; + + lastaddr = *lastaddrp; + bmask = ~(map->_dm_boundary - 1); + + for (seg = *segp; buflen > 0 ; ) { + /* + * Get the physical address for this segment. + */ + if (p != NULL) + (void) pmap_extract(p->p_vmspace->vm_map.pmap, + vaddr, (paddr_t *)&curaddr); + else + curaddr = vtophys(vaddr); + + /* + * If we're beyond the bounce threshold, notify + * the caller. + */ + if (map->_dm_bounce_thresh != 0 && + curaddr >= map->_dm_bounce_thresh) + return (EINVAL); + + /* + * Compute the segment size, and adjust counts. + */ + sgsize = NBPG - ((u_long)vaddr & PGOFSET); + 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 + * the previous segment if possible. + */ + if (first) { + map->dm_segs[seg].ds_addr = PHYS_TO_PCI_MEM(curaddr); + map->dm_segs[seg].ds_len = sgsize; + 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 = + PHYS_TO_PCI_MEM(curaddr); + map->dm_segs[seg].ds_len = sgsize; + } + } + + 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); +} + +/* + * Common function for loading a DMA map with a linear buffer. May + * be called by bus-specific DMA map load functions. + */ +int +_bus_dmamap_load(t, map, buf, buflen, p, flags) + bus_dma_tag_t t; + bus_dmamap_t map; + void *buf; + bus_size_t buflen; + struct proc *p; + int flags; +{ + paddr_t lastaddr; + int seg, error; + + /* + * Make sure that on error condition we return "no valid mappings". + */ + map->dm_mapsize = 0; + map->dm_nsegs = 0; + + if (buflen > map->_dm_size) + return (EINVAL); + + seg = 0; + error = _bus_dmamap_load_buffer(t, map, buf, buflen, p, flags, + &lastaddr, &seg, 1); + if (error == 0) { + map->dm_mapsize = buflen; + map->dm_nsegs = seg + 1; + } + return (error); +} + +/* + * Like _bus_dmamap_load(), but for mbufs. + */ +int +_bus_dmamap_load_mbuf(t, map, m0, flags) + bus_dma_tag_t t; + bus_dmamap_t map; + struct mbuf *m0; + int flags; +{ + paddr_t lastaddr; + int seg, error, first; + struct mbuf *m; + + /* + * Make sure that on error condition we return "no valid mappings." + */ + 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; + for (m = m0; m != NULL && error == 0; m = m->m_next) { + error = _bus_dmamap_load_buffer(t, 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); +} + +/* + * Like _bus_dmamap_load(), but for uios. + */ +int +_bus_dmamap_load_uio(t, map, uio, flags) + bus_dma_tag_t t; + 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 (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; + 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(t, 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); +} + +/* + * Like _bus_dmamap_load(), but for raw memory allocated with + * bus_dmamem_alloc(). + */ +int +_bus_dmamap_load_raw(t, map, segs, nsegs, size, flags) + bus_dma_tag_t t; + bus_dmamap_t map; + bus_dma_segment_t *segs; + int nsegs; + bus_size_t size; + int flags; +{ + + panic("_bus_dmamap_load_raw: not implemented"); +} + +/* + * Common function for unloading a DMA map. May be called by + * chipset-specific DMA map unload functions. + */ +void +_bus_dmamap_unload(t, map) + bus_dma_tag_t t; + bus_dmamap_t map; +{ + + /* + * No resources to free; just mark the mappings as + * invalid. + */ + map->dm_mapsize = 0; + map->dm_nsegs = 0; +} + +/* + * Common function for DMA map synchronization. May be called + * by chipset-specific DMA map synchronization functions. + */ + +void +_bus_dmamap_sync(t, map, op) + bus_dma_tag_t t; + bus_dmamap_t map; + bus_dmasync_op_t op; +{ + int i; + switch (op) { + case BUS_DMASYNC_POSTREAD: + case BUS_DMASYNC_POSTWRITE: + case BUS_DMASYNC_PREWRITE: + case BUS_DMASYNC_PREREAD: + for (i = map->dm_nsegs; i--; ) + invdcache(map->dm_segs[i].ds_addr, + map->dm_segs[i].ds_len); + break; + } +} + +/* + * Common function for DMA-safe memory allocation. May be called + * by bus-specific DMA memory allocation functions. + */ +int +_bus_dmamem_alloc(t, size, alignment, boundary, segs, nsegs, rsegs, flags) + bus_dma_tag_t t; + bus_size_t size, alignment, boundary; + bus_dma_segment_t *segs; + int nsegs; + int *rsegs; + int flags; +{ + paddr_t avail_start = 0xffffffff, avail_end = 0; + int bank; + + for (bank = 0; bank < vm_nphysseg; bank++) { + if (avail_start > vm_physmem[bank].avail_start << PGSHIFT) + avail_start = vm_physmem[bank].avail_start << PGSHIFT; + if (avail_end < vm_physmem[bank].avail_end << PGSHIFT) + avail_end = vm_physmem[bank].avail_end << PGSHIFT; + } + + return _bus_dmamem_alloc_range(t, size, alignment, boundary, segs, + nsegs, rsegs, flags, avail_start, avail_end - PAGE_SIZE); +} + +/* + * Common function for freeing DMA-safe memory. May be called by + * bus-specific DMA memory free functions. + */ +void +_bus_dmamem_free(t, segs, nsegs) + bus_dma_tag_t t; + bus_dma_segment_t *segs; + int nsegs; +{ + struct vm_page *m; + bus_addr_t addr; + struct pglist mlist; + int curseg; + + /* + * Build a list of pages to free back to the VM system. + */ + TAILQ_INIT(&mlist); + for (curseg = 0; curseg < nsegs; curseg++) { + for (addr = PCI_MEM_TO_PHYS(segs[curseg].ds_addr); + addr < (PCI_MEM_TO_PHYS(segs[curseg].ds_addr) + + segs[curseg].ds_len); + addr += PAGE_SIZE) { + m = PHYS_TO_VM_PAGE(addr); + TAILQ_INSERT_TAIL(&mlist, m, pageq); + } + } + + uvm_pglistfree(&mlist); +} + +/* + * Common function for mapping DMA-safe memory. May be called by + * bus-specific DMA memory map functions. + */ +int +_bus_dmamem_map(t, segs, nsegs, size, kvap, flags) + bus_dma_tag_t t; + bus_dma_segment_t *segs; + int nsegs; + size_t size; + caddr_t *kvap; + int flags; +{ + vaddr_t va; + bus_addr_t addr; + int curseg; + + size = round_page(size); + + va = uvm_km_valloc(kernel_map, size); + + if (va == 0) + return (ENOMEM); + + *kvap = (caddr_t)va; + + for (curseg = 0; curseg < nsegs; curseg++) { + for (addr = PCI_MEM_TO_PHYS(segs[curseg].ds_addr); + addr < (PCI_MEM_TO_PHYS(segs[curseg].ds_addr) + + segs[curseg].ds_len); + addr += NBPG, va += NBPG, size -= NBPG) { + if (size == 0) + panic("_bus_dmamem_map: size botch"); + pmap_enter(pmap_kernel(), va, addr, + VM_PROT_READ | VM_PROT_WRITE, TRUE, + VM_PROT_READ | VM_PROT_WRITE); + } + } + + return (0); +} + +/* + * Common function for unmapping DMA-safe memory. May be called by + * bus-specific DMA memory unmapping functions. + */ +void +_bus_dmamem_unmap(t, kva, size) + bus_dma_tag_t t; + caddr_t kva; + size_t size; +{ + +#ifdef DIAGNOSTIC + if ((u_long)kva & PGOFSET) + panic("_bus_dmamem_unmap"); +#endif + + size = round_page(size); + + uvm_km_free(kernel_map, (vaddr_t)kva, size); +} + +/* + * Common functin for mmap(2)'ing DMA-safe memory. May be called by + * bus-specific DMA mmap(2)'ing functions. + */ +paddr_t +_bus_dmamem_mmap(t, segs, nsegs, off, prot, flags) + bus_dma_tag_t t; + bus_dma_segment_t *segs; + int nsegs; + off_t off; + int prot, flags; +{ + int i; + + for (i = 0; i < nsegs; i++) { +#ifdef DIAGNOSTIC + if (off & PGOFSET) + panic("_bus_dmamem_mmap: offset unaligned"); + if (PCI_MEM_TO_PHYS(segs[i].ds_addr) & PGOFSET) + panic("_bus_dmamem_mmap: segment unaligned"); + if (segs[i].ds_len & PGOFSET) + panic("_bus_dmamem_mmap: segment size not multiple" + " of page size"); +#endif + if (off >= segs[i].ds_len) { + off -= segs[i].ds_len; + continue; + } + + return (PCI_MEM_TO_PHYS(segs[i].ds_addr) + off); + } + + /* Page not found. */ + return (-1); +} + +/* + * Allocate physical memory from the given physical address range. + * Called by DMA-safe memory allocation methods. + */ +int +_bus_dmamem_alloc_range(t, size, alignment, boundary, segs, nsegs, rsegs, + flags, low, high) + bus_dma_tag_t t; + bus_size_t size, alignment, boundary; + bus_dma_segment_t *segs; + int nsegs; + int *rsegs; + int flags; + paddr_t low; + paddr_t high; +{ + paddr_t curaddr, lastaddr; + struct vm_page *m; + struct pglist mlist; + int curseg, error; + + /* Always round the size. */ + size = round_page(size); + + /* + * Allocate pages from the VM system. + */ + TAILQ_INIT(&mlist); + error = uvm_pglistalloc(size, low, high, alignment, boundary, + &mlist, nsegs, (flags & BUS_DMA_NOWAIT) == 0); + if (error) + return (error); + + /* + * Compute the location, size, and number of segments actually + * returned by the VM code. + */ + m = mlist.tqh_first; + curseg = 0; + lastaddr = VM_PAGE_TO_PHYS(m); + segs[curseg].ds_addr = PHYS_TO_PCI_MEM(lastaddr); + segs[curseg].ds_len = PAGE_SIZE; + m = m->pageq.tqe_next; + + for (; m != NULL; m = m->pageq.tqe_next) { + curaddr = VM_PAGE_TO_PHYS(m); +#ifdef DIAGNOSTIC + if (curaddr < low || curaddr >= high) { + printf("vm_page_alloc_memory returned non-sensical" + " address 0x%lx\n", curaddr); + panic("_bus_dmamem_alloc_range"); + } +#endif + if (curaddr == (lastaddr + PAGE_SIZE)) + segs[curseg].ds_len += PAGE_SIZE; + else { + curseg++; + segs[curseg].ds_addr = PHYS_TO_PCI_MEM(curaddr); + segs[curseg].ds_len = PAGE_SIZE; + } + lastaddr = curaddr; + } + + *rsegs = curseg + 1; + + return (0); +} + diff --git a/sys/arch/mvmeppc/mvmeppc/bus_space.c b/sys/arch/mvmeppc/mvmeppc/bus_space.c new file mode 100644 index 00000000000..26a939227f3 --- /dev/null +++ b/sys/arch/mvmeppc/mvmeppc/bus_space.c @@ -0,0 +1,224 @@ +/* $NetBSD: bus_space.c,v 1.4 2001/06/15 15:50:05 nonaka Exp $ */ + +/*- + * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace + * Simulation Facility, NASA Ames Research Center. + * + * 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. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/extent.h> +#include <sys/mbuf.h> + +#include <machine/bus.h> + +static int prep_memio_map(bus_space_tag_t, bus_addr_t, bus_size_t, int, + bus_space_handle_t *); +static void prep_memio_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t); +static int prep_memio_alloc(bus_space_tag_t, bus_addr_t, bus_addr_t, + bus_size_t, bus_size_t, bus_size_t, int, bus_addr_t *, + bus_space_handle_t *); +static void prep_memio_free(bus_space_tag_t, bus_space_handle_t, bus_size_t); + +const struct ppc_bus_space prep_io_space_tag = { + PREP_BUS_SPACE_IO, 0x80000000, 0x80000000, 0x3f800000, + prep_memio_map, prep_memio_unmap, prep_memio_alloc, prep_memio_free +}; +const struct ppc_bus_space prep_isa_io_space_tag = { + PREP_BUS_SPACE_IO, 0x80000000, 0x80000000, 0x00010000, + prep_memio_map, prep_memio_unmap, prep_memio_alloc, prep_memio_free +}; +const struct ppc_bus_space prep_mem_space_tag = { + PREP_BUS_SPACE_MEM, 0xC0000000, 0xC0000000, 0x3f000000, + prep_memio_map, prep_memio_unmap, prep_memio_alloc, prep_memio_free +}; +const struct ppc_bus_space prep_isa_mem_space_tag = { + PREP_BUS_SPACE_MEM, 0xC0000000, 0xC0000000, 0x01000000, + prep_memio_map, prep_memio_unmap, prep_memio_alloc, prep_memio_free +}; +static long ioport_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)]; +static long iomem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)]; + +struct extent *ioport_ex; +struct extent *iomem_ex; + +static int ioport_malloc_safe; + +void +prep_bus_space_init() +{ + int error; + + ioport_ex = extent_create("ioport", 0, 0x3f7fffff, M_DEVBUF, + (caddr_t)ioport_ex_storage, sizeof(ioport_ex_storage), + EX_NOCOALESCE|EX_NOWAIT); + error = extent_alloc_region(ioport_ex, 0x10000, 0x7F0000, EX_NOWAIT); + if (error) + panic("prep_bus_space_init: can't block out reserved I/O space 0x10000-0x7fffff: error=%d\n", error); + iomem_ex = extent_create("iomem", 0, 0x3effffff, M_DEVBUF, + (caddr_t)iomem_ex_storage, sizeof(iomem_ex_storage), + EX_NOCOALESCE|EX_NOWAIT); +} + +void +prep_bus_space_mallocok() +{ + + ioport_malloc_safe = 1; +} + +static int +prep_memio_map(t, bpa, size, flags, bshp) + bus_space_tag_t t; + bus_addr_t bpa; + bus_size_t size; + int flags; + bus_space_handle_t *bshp; +{ + int error; + struct extent *ex; + + if (bpa + size > t->pbs_limit) + return (EINVAL); + /* + * Pick the appropriate extent map. + */ + if (t->pbs_type == PREP_BUS_SPACE_IO) { + if (flags & BUS_SPACE_MAP_LINEAR) + return (EOPNOTSUPP); + ex = ioport_ex; + } else if (t->pbs_type == PREP_BUS_SPACE_MEM) { + ex = iomem_ex; + } else + panic("prep_memio_map: bad bus space tag"); + + /* + * Before we go any further, let's make sure that this + * region is available. + */ + error = extent_alloc_region(ex, bpa, size, + EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0)); + if (error) + return (error); + + *bshp = t->pbs_base + bpa; + + return (0); +} + +static void +prep_memio_unmap(t, bsh, size) + bus_space_tag_t t; + bus_space_handle_t bsh; + bus_size_t size; +{ + struct extent *ex; + bus_addr_t bpa; + + /* + * Find the correct extent and bus physical address. + */ + if (t->pbs_type == PREP_BUS_SPACE_IO) + ex = ioport_ex; + else if (t->pbs_type == PREP_BUS_SPACE_MEM) + ex = iomem_ex; + else + panic("prep_memio_unmap: bad bus space tag"); + + bpa = bsh - t->pbs_base; + + if (extent_free(ex, bpa, size, + EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0))) { + printf("prep_memio_unmap: %s 0x%lx, size 0x%lx\n", + (t->pbs_type == PREP_BUS_SPACE_IO) ? "port" : "mem", + (unsigned long)bpa, (unsigned long)size); + printf("prep_memio_unmap: can't free region\n"); + } +} + +static int +prep_memio_alloc(t, rstart, rend, size, alignment, boundary, flags, + bpap, bshp) + bus_space_tag_t t; + bus_addr_t rstart, rend; + bus_size_t size, alignment, boundary; + int flags; + bus_addr_t *bpap; + bus_space_handle_t *bshp; +{ + struct extent *ex; + u_long bpa; + int error; + + if (rstart + size > t->pbs_limit) + return (EINVAL); + + if (t->pbs_type == PREP_BUS_SPACE_IO) { + if (flags & BUS_SPACE_MAP_LINEAR) + return (EOPNOTSUPP); + ex = ioport_ex; + } else if (t->pbs_type == PREP_BUS_SPACE_MEM) { + ex = iomem_ex; + } else + panic("prep_memio_alloc: bad bus space tag"); + + if (rstart < ex->ex_start || rend > ex->ex_end) + panic("prep_memio_alloc: bad region start/end"); + + error = extent_alloc_subregion(ex, rstart, rend, size, alignment, + boundary, + EX_FAST | EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0), + &bpa); + + if (error) + return (error); + + *bpap = bpa; + *bshp = t->pbs_base + bpa; + + return (0); +} + +static void +prep_memio_free(t, bsh, size) + bus_space_tag_t t; + bus_space_handle_t bsh; + bus_size_t size; +{ + + /* prep_memio_unmap() does all that we need to do. */ + prep_memio_unmap(t, bsh, size); +} diff --git a/sys/arch/mvmeppc/mvmeppc/conf.c b/sys/arch/mvmeppc/mvmeppc/conf.c new file mode 100644 index 00000000000..42a9d977f7f --- /dev/null +++ b/sys/arch/mvmeppc/mvmeppc/conf.c @@ -0,0 +1,345 @@ +/* $OpenBSD: conf.c,v 1.1 2001/06/26 21:57:52 smurph Exp $ */ + +/* + * Copyright (c) 1997 Per Fogelstrom + * Copyright (c) 1997 RTMX Inc, North Carolina + * + * 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 under OpenBSD for RTMX Inc, + * North Carolina, USA, by Per Fogelstrom, Opsycon AB, Sweden. + * 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. + * + */ +#include <sys/param.h> +#include <sys/buf.h> +#include <sys/conf.h> +#include <sys/ioctl.h> +#include <sys/systm.h> +#include <sys/tty.h> +#include <sys/vnode.h> + +#include "wd.h" +bdev_decl(wd); +#include "sd.h" +bdev_decl(sd); +bdev_decl(sw); +#include "cd.h" +bdev_decl(cd); + +#include "rd.h" +bdev_decl(rd); + +#include "vnd.h" +bdev_decl(vnd); +#include "ccd.h" +bdev_decl(ccd); +#include "raid.h" +bdev_decl(raid); + +struct bdevsw bdevsw[] = { + bdev_disk_init(NWD,wd), /* 0: ST506/ESDI/IDE disk */ + bdev_swap_init(1,sw), /* 1 swap pseudo device */ + bdev_disk_init(NSD,sd), /* 2 SCSI Disk */ + bdev_disk_init(NCD,cd), /* 3 SCSI CD-ROM */ +#if 0 + bdev_disk_init(NOFDISK,ofd), /* 4 Openfirmware disk */ +#else + bdev_notdef(), /* 4 unknown*/ +#endif + bdev_notdef(), /* 5 unknown*/ + bdev_notdef(), /* 6 unknown*/ + bdev_notdef(), /* 7 unknown*/ + bdev_lkm_dummy(), /* 8 */ + bdev_lkm_dummy(), /* 9 */ + bdev_lkm_dummy(), /* 10 */ + bdev_lkm_dummy(), /* 11 */ + bdev_lkm_dummy(), /* 12 */ + bdev_lkm_dummy(), /* 13 */ + bdev_disk_init(NVND,vnd), /* 14 vnode disk driver*/ + bdev_notdef(), /* 15 unknown*/ + bdev_disk_init(NCCD,ccd), /* 16 concatenated disk driver*/ + bdev_disk_init(NRD,rd), /* 17 ram disk driver*/ + bdev_notdef(), /* 18 unknown*/ + bdev_disk_init(NRAID,raid), /* 19: RAIDframe disk driver */ +}; +int nblkdev = sizeof bdevsw / sizeof bdevsw[0]; + +cdev_decl(cn); +cdev_decl(ctty); +#define mmread mmrw +#define mmwrite mmrw +cdev_decl(mm); +#include "pty.h" +#define ptstty ptytty +#define ptsioctl ptyioctl +cdev_decl(pts); +#define ptctty ptytty +#define ptcioctl ptyioctl +cdev_decl(ptc); +cdev_decl(log); +cdev_decl(sw); + +#include "bugtty.h" +cdev_decl(bugtty); + +cdev_decl(kbd); +cdev_decl(ms); + +#include <sd.h> +#include <st.h> +#include <cd.h> +#include <uk.h> +#include <ss.h> +cdev_decl(st); +cdev_decl(sd); +cdev_decl(cd); +cdev_decl(vnd); +cdev_decl(ccd); +cdev_decl(rd); +#include "raid.h" +cdev_decl(raid); + +#include <wd.h> +cdev_decl(wd); + +dev_decl(filedesc,open); + +#include "bpfilter.h" +cdev_decl(bpf); + +#include "tun.h" +cdev_decl(tun); +cdev_decl(random); + +#ifdef XFS +#include <xfs/nxfs.h> +cdev_decl(xfs_dev); +#endif + +#ifdef LKM +#define NLKM 1 +#else +#define NLKM 0 +#endif + +cdev_decl(lkm); + +#ifdef IPFILTER +#define NIPF 1 +#else +#define NIPF 0 +#endif +#include "ksyms.h" +cdev_decl(ksyms); + +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 */ +#if 0 + cdev_tty_init(NCOM,com), /* 7: Serial ports */ +#else + cdev_notdef(), /* 7 */ +#endif + cdev_disk_init(NSD,sd), /* 8: SCSI disk */ + cdev_disk_init(NCD,cd), /* 9: SCSI CD-ROM */ + cdev_notdef(), /* 10: SCSI changer */ + cdev_disk_init(NWD,wd), /* 11: ST506/ESDI/IDE disk */ + cdev_notdef(), /* 12 */ + cdev_notdef(), /* 13 */ + cdev_tty_init(NBUGTTY,bugtty), /* 14: BUGtty (ttyB) */ + cdev_notdef(), /* 15 */ + cdev_notdef(), /* 16 */ + cdev_disk_init(NRD,rd), /* 17 ram disk driver*/ + cdev_disk_init(NCCD,ccd), /* 18 concatenated disk driver */ + cdev_disk_init(NVND,vnd), /* 19: vnode disk */ + cdev_tape_init(NST,st), /* 20: SCSI tape */ + cdev_fd_init(1,filedesc), /* 21: file descriptor pseudo-dev */ + cdev_bpftun_init(NBPFILTER,bpf),/* 22: berkeley packet filter */ + cdev_bpftun_init(NTUN,tun), /* 23: network tunnel */ + cdev_lkm_init(NLKM,lkm), /* 24: loadable module driver */ + cdev_notdef(), /* 25 */ + cdev_notdef(), /* 26 */ + cdev_notdef(), /* 27 */ + cdev_notdef(), /* 28 */ + cdev_notdef(), /* 29 */ + cdev_notdef(), /* 30 */ + cdev_notdef(), /* 31 */ + cdev_notdef(), /* 32 */ + cdev_lkm_dummy(), /* 33 */ + cdev_lkm_dummy(), /* 34 */ + cdev_lkm_dummy(), /* 35 */ + cdev_lkm_dummy(), /* 36 */ + cdev_lkm_dummy(), /* 37 */ + cdev_lkm_dummy(), /* 38 */ + cdev_gen_ipf(NIPF,ipl), /* 39: IP filter */ + cdev_random_init(1,random), /* 40: random data source */ + cdev_uk_init(NUK,uk), /* 41: unknown SCSI */ + cdev_ss_init(NSS,ss), /* 42: SCSI scanner */ + cdev_ksyms_init(NKSYMS,ksyms), /* 43: Kernel symbols device */ + cdev_notdef(), /* 44 */ + cdev_notdef(), /* 45 */ + cdev_notdef(), /* 46 */ + cdev_notdef(), /* 47 */ + cdev_notdef(), /* 48 */ + cdev_notdef(), /* 49 */ + cdev_notdef(), /* 50 */ +#ifdef XFS + cdev_xfs_init(NXFS,xfs_dev), /* 51: xfs communication device */ +#else + cdev_notdef(), /* 51 */ +#endif + cdev_notdef(), /* 52 */ + cdev_notdef(), /* 53 */ + cdev_disk_init(NRAID,raid), /* 54: RAIDframe disk driver */ + cdev_notdef(), /* 55 */ + /* The following slots are reserved for isdn4bsd. */ + cdev_notdef(), /* 56: i4b main device */ + cdev_notdef(), /* 57: i4b control device */ + cdev_notdef(), /* 58: i4b raw b-channel access */ + cdev_notdef(), /* 59: i4b trace device */ + cdev_notdef(), /* 60: i4b phone device */ + /* End of reserved slots for isdn4bsd. */ + cdev_notdef(), /* 60: i4b phone device */ + cdev_notdef(), /* 61: i4b phone device */ + cdev_notdef(), /* 62: i4b phone device */ + cdev_notdef(), /* 63: i4b phone device */ + cdev_notdef(), /* 64: i4b phone device */ + cdev_notdef(), /* 65: i4b phone device */ + cdev_notdef(), /* 66: i4b phone device */ + cdev_notdef(), /* 67: i4b phone device */ + cdev_notdef(), /* 68: i4b phone device */ + cdev_notdef(), /* 69: i4b phone device */ + cdev_notdef(), /* 70: i4b phone device */ +}; +int nchrdev = sizeof cdevsw / sizeof cdevsw[0]; + +int mem_no = 2; /* major number of /dev/mem */ + +/* + * Swapdev is a fake device implemented in sw.c. + * It is used only internally to get to swstrategy. + */ +dev_t swapdev = makedev(1, 0); + +/* + * Check whether dev is /dev/mem or /dev/kmem. + */ +int +iskmemdev(dev) + dev_t dev; +{ + return major(dev) == mem_no && minor(dev) < 2; +} + +/* + * Check whether 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); +} + +static int chrtoblktbl[] = { + /*VCHR*/ /*VBLK*/ + /* 0 */ NODEV, + /* 1 */ NODEV, + /* 2 */ NODEV, + /* 3 */ NODEV, + /* 4 */ NODEV, + /* 5 */ NODEV, + /* 6 */ NODEV, + /* 7 */ NODEV, + /* 8 */ 2, + /* 9 */ NODEV, + /* 10 */ NODEV, + /* 11 */ 0, + /* 12 */ NODEV, + /* 13 */ 4, + /* 14 */ NODEV, + /* 15 */ NODEV, + /* 16 */ NODEV, + /* 17 */ 17, +}; + +/* + * Return accompanying block dev for a char dev. + */ +int +chrtoblk(dev) + dev_t dev; +{ + int blkmaj; + + if (major(dev) >= nchrdev || + major(dev) > sizeof(chrtoblktbl)/sizeof(chrtoblktbl[0])) + return (NODEV); + blkmaj = chrtoblktbl[major(dev)]; + if (blkmaj == NODEV) + return (NODEV); + return (makedev(blkmaj, minor(dev))); +} + +/* + * Convert a character device number to a block device number. + */ +dev_t +blktochr(dev) + dev_t dev; +{ + int blkmaj = major(dev); + int i; + + if (blkmaj >= nblkdev) + return (NODEV); + for (i = 0; i < sizeof(chrtoblktbl)/sizeof(chrtoblktbl[0]); i++) + if (blkmaj == chrtoblktbl[i]) + return (makedev(i, minor(dev))); + return (NODEV); +} + +#include <dev/cons.h> + +#define bugttycnpollc nullcnpollc +cons_decl(bugtty); + +struct consdev constab[] = { +#if NBUGTTY > 0 + cons_init(bugtty), +#endif + { 0 }, +}; diff --git a/sys/arch/mvmeppc/mvmeppc/disksubr.c b/sys/arch/mvmeppc/mvmeppc/disksubr.c new file mode 100644 index 00000000000..12e899e43fd --- /dev/null +++ b/sys/arch/mvmeppc/mvmeppc/disksubr.c @@ -0,0 +1,543 @@ +/* $OpenBSD: disksubr.c,v 1.1 2001/06/26 21:57:53 smurph Exp $ */ +/* $NetBSD: disksubr.c,v 1.21 1996/05/03 19:42:03 christos Exp $ */ + +/* + * 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. 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, Berkeley and its contributors. + * 4. 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 + */ + +#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> + +#define b_cylin b_resid + +#define BOOT_MAGIC 0xAA55 +#define BOOT_MAGIC_OFF (DOSPARTOFF+NDOSPART*sizeof(struct dos_partition)) + +void +dk_establish(dk, dev) + struct disk *dk; + struct device *dev; +{ +} + +/* + * 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. + * + * 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. + * + * Returns null on success and an error string on failure. + */ +char * +readdisklabel(dev, strat, lp, osdep, spoofonly) + dev_t dev; + void (*strat) __P((struct buf *)); + register struct disklabel *lp; + struct cpu_disklabel *osdep; + int spoofonly; +{ + struct dos_partition *dp = osdep->dosparts, *dp2; + struct dkbad *bdp = &DKBAD(osdep); + struct buf *bp; + struct disklabel *dlp; + char *msg = NULL, *cp; + int dospartoff, cyl, i, ourpart = -1; + + /* minimal requirements for archtypal disk label */ + if (lp->d_secsize == 0) + lp->d_secsize = DEV_BSIZE; + if (lp->d_secperunit == 0) + lp->d_secperunit = 0x1fffffff; + 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; + + /* get a buffer and initialize it */ + bp = geteblk((int)lp->d_secsize); + bp->b_dev = dev; + + /* do dos partitions in the process of getting disklabel? */ + dospartoff = 0; + cyl = 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; + + /* 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"; + goto done; + } + 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 (get_le(&dp2->dp_size) && + dp2->dp_typ == DOSPTYP_OPENBSD) + ourpart = i; + for (dp2=dp, i=0; i < NDOSPART && ourpart == -1; + i++, dp2++) + if (get_le(&dp2->dp_size) && + dp2->dp_typ == DOSPTYP_FREEBSD) + ourpart = i; + for (dp2=dp, i=0; i < NDOSPART && ourpart == -1; + i++, dp2++) + if (get_le(&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 = get_le(&dp2->dp_start) + part_blkno; + cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect); + + /* XXX build a temporary disklabel */ + lp->d_partitions[0].p_size = get_le(&dp2->dp_size); + lp->d_partitions[0].p_offset = + get_le(&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 (get_le(&dp2->dp_size) > lp->d_secperunit) + continue; + if (get_le(&dp2->dp_size)) + pp->p_size = get_le(&dp2->dp_size); + if (get_le(&dp2->dp_start)) + pp->p_offset = + get_le(&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_FAT16C: + case DOSPTYP_FAT32: + pp->p_fstype = FS_MSDOS; + n++; + break; + case DOSPTYP_EXTEND: + case DOSPTYP_EXTENDL: + part_blkno = get_le(&dp2->dp_start) + extoff; + if (!extoff) + extoff = get_le(&dp2->dp_start); + wander = 1; + break; + default: + pp->p_fstype = FS_OTHER; + n++; + break; + } + } + } + lp->d_bbsize = 8192; + lp->d_sbsize = 64*1024; /* XXX ? */ + lp->d_npartitions = MAXPARTITIONS; + } + + /* don't read the on-disk label if we are in spoofed-only mode */ + if (spoofonly) + goto done; + + /* next, dig out disk label */ + bp->b_blkno = dospartoff + LABELSECTOR; + 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"; + goto done; + } + for (dlp = (struct disklabel *)bp->b_data; + dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof(*dlp)); + dlp = (struct disklabel *)((char *)dlp + sizeof(long))) { + if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) { + if (msg == NULL) + msg = "no disk label"; + } else if (dlp->d_npartitions > MAXPARTITIONS || + dkcksum(dlp) != 0) + msg = "disk label corrupted"; + else { + *lp = *dlp; + msg = NULL; + break; + } + } + + if (msg) { +#if defined(CD9660) + if (iso_disklabelspoof(dev, strat, lp) == 0) + msg = NULL; +#endif + goto done; + } + + /* obtain bad sector table if requested and present */ + if (bdp && (lp->d_flags & D_BADSECT)) { + struct dkbad *db; + + 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); + } + +done: + bp->b_flags |= B_INVAL; + brelse(bp); + return (msg); +} + +/* + * Check new disk label for sensibility + * before setting it. + */ +int +setdisklabel(olp, nlp, openmask, osdep) + register struct disklabel *olp, *nlp; + u_long openmask; + struct cpu_disklabel *osdep; +{ + register i; + register struct partition *opp, *npp; + + /* sanity clause */ + if (nlp->d_secpercyl == 0 || nlp->d_secsize == 0 || + (nlp->d_secsize % DEV_BSIZE) != 0) + return(EINVAL); + + /* 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(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. + * XXX cannot handle OpenBSD partitions in extended partitions! + */ +int +writedisklabel(dev, strat, lp, osdep) + dev_t dev; + void (*strat) __P((struct buf *)); + register struct disklabel *lp; + struct cpu_disklabel *osdep; +{ + struct dos_partition *dp = osdep->dosparts, *dp2; + struct buf *bp; + struct disklabel *dlp; + int error, dospartoff, cyl, i; + int ourpart = -1; + + /* get a buffer and initialize it */ + bp = geteblk((int)lp->d_secsize); + bp->b_dev = dev; + + /* do dos partitions in the process of getting disklabel? */ + dospartoff = 0; + cyl = LABELSECTOR / lp->d_secpercyl; + if (dp) { + /* read master boot record */ + bp->b_blkno = DOSBBSECTOR; + bp->b_bcount = lp->d_secsize; + bp->b_flags = B_BUSY | B_READ; + bp->b_cylin = DOSBBSECTOR / lp->d_secpercyl; + (*strat)(bp); + + if ((error = biowait(bp)) != 0) + goto done; + + /* XXX how do we check veracity/bounds of this? */ + bcopy(bp->b_data + DOSPARTOFF, dp, + NDOSPART * sizeof(*dp)); + + for (dp2=dp, i=0; i < NDOSPART && ourpart == -1; i++, dp2++) + if (get_le(&dp2->dp_size) && dp2->dp_typ == DOSPTYP_OPENBSD) + ourpart = i; + for (dp2=dp, i=0; i < NDOSPART && ourpart == -1; i++, dp2++) + if (get_le(&dp2->dp_size) && dp2->dp_typ == DOSPTYP_FREEBSD) + ourpart = i; + for (dp2=dp, i=0; i < NDOSPART && ourpart == -1; i++, dp2++) + if (get_le(&dp2->dp_size) && dp2->dp_typ == DOSPTYP_NETBSD) + ourpart = i; + + if (ourpart != -1) { + dp2 = &dp[ourpart]; + + /* + * need sector address for SCSI/IDE, + * cylinder for ESDI/ST506/RLL + */ + dospartoff = get_le(&dp2->dp_start); + cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect); + } + } + + /* next, dig out disk label */ + bp->b_blkno = dospartoff + LABELSECTOR; + 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 ((error = biowait(bp)) != 0) + goto done; + for (dlp = (struct disklabel *)bp->b_data; + dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof(*dlp)); + dlp = (struct disklabel *)((char *)dlp + sizeof(long))) { + if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC && + dkcksum(dlp) == 0) { + *dlp = *lp; + bp->b_flags = B_BUSY | B_WRITE; + (*strat)(bp); + error = biowait(bp); + goto done; + } + } + + /* Write it in the regular place. */ + *(struct disklabel *)bp->b_data = *lp; + bp->b_flags = B_BUSY | B_WRITE; + (*strat)(bp); + error = biowait(bp); + goto done; + +done: + 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) + + LABELSECTOR; + int sz = howmany(bp->b_bcount, DEV_BSIZE); + + /* avoid division by zero */ + if (lp->d_secpercyl == 0) { + bp->b_error = EINVAL; + goto bad; + } + + 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 && +#if LABELSECTOR != 0 + bp->b_blkno + blockpersec(p->p_offset, lp) + sz > labelsector && +#endif + (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/mvmeppc/mvmeppc/genassym.cf b/sys/arch/mvmeppc/mvmeppc/genassym.cf new file mode 100644 index 00000000000..a3d1db8e2ab --- /dev/null +++ b/sys/arch/mvmeppc/mvmeppc/genassym.cf @@ -0,0 +1,77 @@ +# $OpenBSD: genassym.cf,v 1.1 2001/06/26 21:57:53 smurph Exp $ +# +# Copyright (c) 1982, 1990 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. 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, Berkeley and its contributors. +# 4. 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 7.8 (Berkeley) 5/7/91 +# + +include <sys/param.h> +include <sys/time.h> +include <sys/proc.h> +include <vm/vm.h> +include <vm/vm_kern.h> + + +include <machine/pcb.h> +include <machine/pmap.h> + + + +define FRAMELEN FRAMELEN +define FRAME_0 offsetof(struct trapframe, fixreg[0]) +define FRAME_1 offsetof(struct trapframe, fixreg[1]) +define FRAME_2 offsetof(struct trapframe, fixreg[2]) +define FRAME_3 offsetof(struct trapframe, fixreg[3]) +define FRAME_LR offsetof(struct trapframe, lr) +define FRAME_CR offsetof(struct trapframe, cr) +define FRAME_CTR offsetof(struct trapframe, ctr) +define FRAME_XER offsetof(struct trapframe, xer) +define FRAME_SRR0 offsetof(struct trapframe, srr0) +define FRAME_SRR1 offsetof(struct trapframe, srr1) +define FRAME_DAR offsetof(struct trapframe, dar) +define FRAME_DSISR offsetof(struct trapframe, dsisr) +define FRAME_EXC offsetof(struct trapframe, exc) + +define SFRAMELEN roundup(sizeof(struct switchframe), 16) + +define PCB_PMR offsetof(struct pcb, pcb_pmreal) +define PCB_SP offsetof(struct pcb, pcb_sp) +define PCB_SPL offsetof(struct pcb, pcb_spl) +define PCB_FAULT offsetof(struct pcb, pcb_onfault) + +define PM_USRSR offsetof(struct pmap, pm_sr[USER_SR]) +define PM_KERNELSR offsetof(struct pmap, pm_sr[KERNEL_SR]) + +define P_FORW offsetof(struct proc, p_forw) +define P_BACK offsetof(struct proc, p_back) +define P_ADDR offsetof(struct proc, p_addr) + diff --git a/sys/arch/mvmeppc/mvmeppc/in_cksum.c b/sys/arch/mvmeppc/mvmeppc/in_cksum.c new file mode 100644 index 00000000000..2500b6b3a75 --- /dev/null +++ b/sys/arch/mvmeppc/mvmeppc/in_cksum.c @@ -0,0 +1,85 @@ +/* $OpenBSD: in_cksum.c,v 1.1 2001/06/26 21:57:53 smurph Exp $ */ +/* $NetBSD: in_cksum.c,v 1.1 1996/09/30 16:34:47 ws Exp $ */ + +/* + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/param.h> +#include <sys/mbuf.h> + +/* + * First cut for in_cksum. + * This code is in C and should be optimized for PPC later. + */ +#define REDUCE (sum = (sum & 0xffff) + (sum >> 16)) +#define ROL (sum = sum << 8) +#define ADDB (ROL, sum += *w, byte_swapped ^= 1) +#define ADDS (sum += *(u_short *)w) +#define SHIFT(n) (w += (n), mlen -= (n)) +#define ADDCARRY do { while (sum > 0xffff) REDUCE; } while (0) + +int +in_cksum(m, len) + struct mbuf *m; + int len; +{ + u_char *w; + u_int sum = 0; + int mlen; + int byte_swapped = 0; + + for (; m && len; m = m->m_next) { + if (m->m_len == 0) + continue; + w = mtod(m, u_char *); + mlen = m->m_len; + if (len < mlen) + mlen = len; + len -= mlen; + if ((long)w & 1) { + REDUCE; + ADDB; + SHIFT(1); + } + while (mlen >= 2) { + ADDS; + SHIFT(2); + } + REDUCE; + if (mlen == 1) + ADDB; + } + if (byte_swapped) { + REDUCE; + ROL; + } + ADDCARRY; + return sum ^ 0xffff; +} diff --git a/sys/arch/mvmeppc/mvmeppc/locore.S b/sys/arch/mvmeppc/mvmeppc/locore.S new file mode 100644 index 00000000000..967a4213b0a --- /dev/null +++ b/sys/arch/mvmeppc/mvmeppc/locore.S @@ -0,0 +1,1383 @@ +/* $OpenBSD: locore.S,v 1.1 2001/06/26 21:57:54 smurph Exp $ */ +/* $NetBSD: locore.S,v 1.2 1996/10/16 19:33:09 ws Exp $ */ + +/* + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "machine/ipkdb.h" + +#include "assym.h" + +#include <sys/syscall.h> + +#include <machine/asm.h> +#include <machine/param.h> +#include <machine/pmap.h> +#include <machine/psl.h> +#include <machine/trap.h> + +/* + * Globals + */ + .globl _C_LABEL(esym),_C_LABEL(proc0paddr) + .type _C_LABEL(esym),@object + .type _C_LABEL(proc0paddr),@object + .data +_C_LABEL(esym): .long 0 /* end of symbol table */ +_C_LABEL(proc0paddr): .long 0 /* proc0 p_addr */ +idle_u: .long 0 /* fake uarea during idle after exit */ + + .globl _C_LABEL(where) + .type _C_LABEL(where),@object +_C_LABEL(where): .long 0 + +/* + * Startup entry + */ +_ENTRY(_C_LABEL(kernel_text)) +_ENTRY(_ASM_LABEL(start)) +/* arguments to start + * r1 - stack provided by firmware/bootloader + * r3 - unused (controller address for PPC1bug) + * r4 - unused (bootdev for PPC1bug) + * r5 - firmware pointer (NULL for PPC1bug) + * r6 - arg list + * r7 - length + * r8 - end of symbol table + */ + .globl start + .type start,@function +start: + li 0,0 /*(PSL_FP)*/ + mtmsr 0 /* Disable FPU/MMU/exceptions */ + isync + +/* compute end of kernel memory */ +#if defined(DDB) || defined(KERNFS) + lis 9,_C_LABEL(esym)@ha + stw 8,_C_LABEL(esym)@l(9) /* save for symbol handling */ +#else + lis 8,_end@ha + addi 8,8,_end@l +#endif + li 9,PGOFSET + add 8,8,9 + andc 8,8,9 + lis 9,idle_u@ha + stw 8,idle_u@l(9) + addi 8,8,USPACE /* space for idle_u */ + lis 9,_C_LABEL(proc0paddr)@ha + stw 8,_C_LABEL(proc0paddr)@l(9) + addi 1,8,USPACE-FRAMELEN /* stackpointer for proc0 */ + mr 4,1 /* end of mem reserved for kernel */ + xor 0,0,0 + stwu 0,-16(1) /* end of stack chain */ + + li 0, 2 + lis 9,_C_LABEL(where)@ha + stw 0,_C_LABEL(where)@l(9) + + lis 3,start@ha + addi 3,3,start@l + mr 5,6 /* args string */ + bl _C_LABEL(initppc) + bl _C_LABEL(main) +#if 0 + b _C_LABEL(OF_exit) +#endif + +#define LED_ADDR 0x800008c0 +_ENTRY(_C_LABEL(led_dbg)) + stwu 1,-32(1) + mflr 0 + stw 0,36(1) + + stw 4,8(1) + stw 5,12(1) + stw 6,16(1) + stw 7,20(1) + mfmsr 5 + + mr 6,5 + ori 6,6,(PSL_IR|PSL_DR)@l /* turn on MMU */ + mtmsr 6 + sync + isync + + lis 4,LED_ADDR@ha + addi 4,4,LED_ADDR@l + li 7,0 + ori 3,3,0x2000 + sthbrx 3,7,4 + + sync + mtmsr 5 + isync + lwz 4,8(1) + lwz 5,12(1) + lwz 6,16(1) + lwz 7,20(1) + + lwz 0,36(1) + mtlr 0 + addi 1,1,32 + blr + +/* + * No processes are runnable, so loop waiting for one. + * Separate label here for accounting purposes. + */ +_C_LABEL(idle): + mfmsr 3 + andi. 3,3,~PSL_EE@l /* disable interrupts while manipulating runque */ + mtmsr 3 + + lis 8,_C_LABEL(whichqs)@ha + lwz 9,_C_LABEL(whichqs)@l(8) + + or. 9,9,9 + bne- _C_LABEL(sw1) /* at least one queue non-empty */ + + ori 3,3,PSL_EE /* reenable ints again */ + mtmsr 3 + isync + sync + /* low power mode */ + mfmsr 3 + oris 3, 3, PSL_POW@h + mtmsr 3 + isync + +/* May do some power saving here? */ + + b _C_LABEL(idle) + +/* + * switchexit gets called from cpu_exit to free the user structure + * and kernel stack of the current process. + */ +_ENTRY(_C_LABEL(switchexit)) +/* First switch to the idle pcb/kernel stack */ + lis 6,idle_u@ha + lwz 6,idle_u@l(6) + lis 7,_C_LABEL(curpcb)@ha + stw 6,_C_LABEL(curpcb)@l(7) + addi 1,6,USPACE-16 /* 16 bytes are reserved at stack top */ + /* + * Schedule the vmspace and stack to be freed (the proc arg is + * already in r3). + */ + bl _C_LABEL(exit2) + + /* Fall through to cpu_switch to actually select another proc */ + li 3,0 /* indicate exited process */ + + +/* Fall through to cpu_switch to actually select another proc */ + +/* + * void cpu_switch(struct proc *p) + * Find a runnable process and switch to it. + */ +_ENTRY(_C_LABEL(cpu_switch)) + mflr 0 /* save lr */ + stw 0,4(1) + stwu 1,-16(1) + stw 31,12(1) + stw 30,8(1) + + mr 30,3 + lis 3,_C_LABEL(curproc)@ha + xor 31,31,31 + stw 31,_C_LABEL(curproc)@l(3) /* Zero to not accumulate cpu time */ + lis 3,_C_LABEL(curpcb)@ha + lwz 31,_C_LABEL(curpcb)@l(3) + + xor 3,3,3 + bl _C_LABEL(lcsplx) + stw 3,PCB_SPL(31) /* save spl */ + +/* Find a new process */ + mfmsr 3 + andi. 3,3,~PSL_EE@l /* disable interrupts while + manipulating runque */ + mtmsr 3 + isync + + lis 8,_C_LABEL(whichqs)@ha + lwz 9,_C_LABEL(whichqs)@l(8) + + or. 9,9,9 + beq- _C_LABEL(idle) /* all queues empty */ +_C_LABEL(sw1): + cntlzw 10,9 + lis 4,_C_LABEL(qs)@ha + addi 4,4,_C_LABEL(qs)@l + slwi 3,10,3 + add 3,3,4 /* select queue */ + + lwz 31,P_FORW(3) /* unlink first proc from queue */ + lwz 4,P_FORW(31) + stw 4,P_FORW(3) + stw 3,P_BACK(4) + + cmpl 0,3,4 /* queue empty? */ + bne 1f + + lis 3,0x80000000@ha + srw 3,3,10 + andc 9,9,3 + stw 9,_C_LABEL(whichqs)@l(8) /* mark it empty */ + +1: + xor 3,3,3 + lis 4,_C_LABEL(want_resched)@ha + stw 3,_C_LABEL(want_resched)@l(4) /* just did this resched thing */ + + stw 3,P_BACK(31) /* probably superfluous */ + + lis 4,_C_LABEL(curproc)@ha + stw 31,_C_LABEL(curproc)@l(4) /* record new process */ + + mfmsr 3 + ori 3,3,PSL_EE /* Now we can interrupt again */ + mtmsr 3 + + cmpl 0,31,30 /* is it the same process? */ + beq switch_return + + or. 30,30,30 /* old process was exiting? */ + beq switch_exited + + mfsr 10,USER_SR /* save USER_SR for copyin/copyout */ + mfcr 11 /* save cr */ + mr 12,2 /* save r2 */ + stwu 1,-SFRAMELEN(1) /* still running on old stack */ + stmw 10,8(1) + lwz 3,P_ADDR(30) + stw 1,PCB_SP(3) /* save SP */ + +switch_exited: + mfmsr 3 + andi. 3,3,~PSL_EE@l /* disable interrupts while actually switching */ + mtmsr 3 + + lwz 4,P_ADDR(31) + lis 5,_C_LABEL(curpcb)@ha + stw 4,_C_LABEL(curpcb)@l(5) /* indicate new pcb */ + + lwz 5,PCB_PMR(4) + lis 6,_C_LABEL(curpm)@ha + stwu 5,_C_LABEL(curpm)@l(6) /* save real pmap pointer for spill fill */ + stwcx. 5,0,6 /* clear possible reservation */ + + addic. 5,5,64 + li 6,0 + mfsr 8,KERNEL_SR /* save kernel SR */ +1: + addis 6,6,-0x10000000@ha /* set new procs segment registers */ + or. 6,6,6 /* This is done from the real address pmap */ + lwzu 7,-4(5) /* so we don't have to worry */ + mtsrin 7,6 /* about accessibility */ + bne 1b + mtsr KERNEL_SR,8 /* restore kernel SR */ + isync + + lwz 1,PCB_SP(4) /* get new procs SP */ + + ori 3,3,PSL_EE /* interrupts are okay again */ + mtmsr 3 + + lmw 10,8(1) /* get other regs */ + lwz 1,0(1) /* get saved SP */ + mr 2,12 /* get saved r2 */ + mtcr 11 /* get saved cr */ + isync + mtsr USER_SR,10 /* get saved USER_SR */ + isync + +switch_return: + mr 30,7 /* save proc pointer */ + lwz 3,PCB_SPL(4) + bl _C_LABEL(lcsplx) + + mr 3,30 /* get curproc for special fork returns */ + + lwz 31,12(1) + lwz 30,8(1) + addi 1,1,16 + lwz 0,4(1) + mtlr 0 + blr + + +/* + * Data used during primary/secondary traps/interrupts + */ +#define tempsave 0x2e0 /* primary save area for trap handling */ +#define disisave 0x3e0 /* primary save area for dsi/isi traps */ +#define INTSTK (8*1024) /* 8K interrupt stack */ + .data +intstk: .space INTSTK /* interrupt stack */ + .global _C_LABEL(intr_depth) + .type _C_LABEL(intr_depth),@object +_C_LABEL(intr_depth): + .long -1 /* in-use marker */ +#define SPILLSTK 1024 /* 1K spill stack */ +.lcomm spillstk,SPILLSTK,8 + +/* + * This code gets copied to all the trap vectors + * (except ISI/DSI, ALI, the interrupts, and possibly the debugging traps + * when using IPKDB). + */ + .text + .globl _C_LABEL(trapcode),_C_LABEL(trapsize) + .type _C_LABEL(trapcode),@function + .type _C_LABEL(trapsize),@object +_C_LABEL(trapcode): + mtsprg 1,1 /* save SP */ + stmw 28,tempsave(0) /* free r28-r31 */ + mflr 28 /* save LR */ + mfcr 29 /* save CR */ +/* Test whether we already had PR set */ + mfsrr1 31 + mtcr 31 + bc 4,17,1f /* branch if PSL_PR is clear */ + lis 1,_C_LABEL(curpcb)@ha + lwz 1,_C_LABEL(curpcb)@l(1) + addi 1,1,USPACE /* stack is top of user struct */ +1: + bla s_trap +_C_LABEL(trapsize) = .-_C_LABEL(trapcode) + +/* + * For ALI: has to save DSISR and DAR + */ + .globl _C_LABEL(alitrap),_C_LABEL(alisize) +_C_LABEL(alitrap): + mtsprg 1,1 /* save SP */ + stmw 28,tempsave(0) /* free r28-r31 */ + mfdar 30 + mfdsisr 31 + stmw 30,tempsave+16(0) + mflr 28 /* save LR */ + mfcr 29 /* save CR */ +/* Test whether we already had PR set */ + mfsrr1 31 + mtcr 31 + bc 4,17,1f /* branch if PSL_PR is clear */ + lis 1,_C_LABEL(curpcb)@ha + lwz 1,_C_LABEL(curpcb)@l(1) + addi 1,1,USPACE /* stack is top of user struct */ +1: + bla s_trap +_C_LABEL(alisize) = .-_C_LABEL(alitrap) + +/* + * Similar to the above for DSI + * Has to handle BAT spills + * and standard pagetable spills + */ + .globl _C_LABEL(dsitrap),_C_LABEL(dsisize) + .type _C_LABEL(dsitrap),@function + .type _C_LABEL(dsisize),@object +_C_LABEL(dsitrap): + stmw 28,disisave(0) /* free r28-r31 */ + mfcr 29 /* save CR */ + mfxer 30 /* save XER */ + mtsprg 2,30 /* in SPRG2 */ + mfsrr1 31 /* test kernel mode */ + mtcr 31 + bc 12,17,1f /* branch if PSL_PR is set */ + mfdar 31 /* get fault address */ + rlwinm 31,31,7,25,28 /* get segment * 8 */ + addis 31,31,_C_LABEL(battable)@ha + lwz 30,_C_LABEL(battable)@l(31) /* get batu */ + mtcr 30 + bc 4,30,1f /* branch if supervisor valid is false */ + lwz 31,_C_LABEL(battable)+4@l(31) /* get batl */ +/* We randomly use the highest two bat registers here */ + mftb 28 + andi. 28,28,1 + bne 2f + mtdbatu 2,30 + mtdbatl 2,31 + b 3f +2: + mtdbatu 3,30 + mtdbatl 3,31 +3: + mfsprg 30,2 /* restore XER */ + mtxer 30 + mtcr 29 /* restore CR */ + lmw 28,disisave(0) /* restore r28-r31 */ + rfi /* return to trapped code */ +1: + mflr 28 /* save LR */ + bla s_dsitrap +_C_LABEL(dsisize) = .-_C_LABEL(dsitrap) + +/* + * Similar to the above for ISI + */ + .globl _C_LABEL(isitrap),_C_LABEL(isisize) + .type _C_LABEL(isitrap),@function + .type _C_LABEL(isisize),@object +_C_LABEL(isitrap): + stmw 28,disisave(0) /* free r28-r31 */ + mflr 28 /* save LR */ + mfcr 29 /* save CR */ + mfsrr1 31 /* test kernel mode */ + mtcr 31 + bc 12,17,1f /* branch if PSL_PR is set */ + mfsrr0 31 /* get fault address */ + rlwinm 31,31,7,25,28 /* get segment * 8 */ + addis 31,31,_C_LABEL(battable)@ha + lwz 30,_C_LABEL(battable)@l(31) /* get batu */ + mtcr 30 + bc 4,30,1f /* branch if supervisor valid is false */ + mtibatu 3,30 + lwz 30,_C_LABEL(battable)+4@l(31) /* get batl */ + mtibatl 3,30 + mtcr 29 /* restore CR */ + lmw 28,disisave(0) /* restore r28-r31 */ + rfi /* return to trapped code */ +1: + bla s_isitrap +_C_LABEL(isisize) = .-_C_LABEL(isitrap) + +/* + * This one for the external interrupt handler. + */ + .globl _C_LABEL(extint),_C_LABEL(extsize) + .type _C_LABEL(extint),@function + .type _C_LABEL(extsize),@object +_C_LABEL(extint): + mtsprg 1,1 /* save SP */ + stmw 28,tempsave(0) /* free r28-r31 */ + mflr 28 /* save LR */ + mfcr 29 /* save CR */ + mfxer 30 /* save XER */ + lis 1,intstk+INTSTK@ha /* get interrupt stack */ + addi 1,1,intstk+INTSTK@l + lwz 31,0(1) /* were we already running on intstk? */ + addic. 31,31,1 + stw 31,0(1) + beq 1f + mfsprg 1,1 /* yes, get old SP */ +1: + ba extintr +_C_LABEL(extsize) = .-_C_LABEL(extint) + +/* + * And this one for the decrementer interrupt handler. + */ + .globl _C_LABEL(decrint),_C_LABEL(decrsize) + .type _C_LABEL(decrint),@function + .type _C_LABEL(decrsize),@object +_C_LABEL(decrint): + mtsprg 1,1 /* save SP */ + stmw 28,tempsave(0) /* free r28-r31 */ + mflr 28 /* save LR */ + mfcr 29 /* save CR */ + mfxer 30 /* save XER */ + lis 1,intstk+INTSTK@ha /* get interrupt stack */ + addi 1,1,intstk+INTSTK@l + lwz 31,0(1) /* were we already running on intstk? */ + addic. 31,31,1 + stw 31,0(1) + beq 1f + mfsprg 1,1 /* yes, get old SP */ +1: + ba decrintr +_C_LABEL(decrsize) = .-_C_LABEL(decrint) + +/* + * Now the tlb software load for 603 processors: + * (Code essentially from the 603e User Manual, Chapter 5) + */ +#define DMISS 976 +#define DCMP 977 +#define HASH1 978 +#define HASH2 979 +#define IMISS 980 +#define ICMP 981 +#define RPA 982 + +#define bdneq bdnzf 2, +#define tlbli .long 0x7c0007e4+0x800* +#define tlbld .long 0x7c0007a4+0x800* + + .globl _C_LABEL(tlbimiss),_C_LABEL(tlbimsize) + .type _C_LABEL(tlbimiss),@function + .type _C_LABEL(tlbimsize),@object +_C_LABEL(tlbimiss): + mfspr 2,HASH1 /* get first pointer */ + li 1,8 + mfctr 0 /* save counter */ + mfspr 3,ICMP /* get first compare value */ + addi 2,2,-8 /* predec pointer */ +1: + mtctr 1 /* load counter */ +2: + lwzu 1,8(2) /* get next pte */ + cmpl 0,1,3 /* see if found pte */ + bdneq 2b /* loop if not eq */ + bne 3f /* not found */ + lwz 1,4(2) /* load tlb entry lower word */ + andi. 3,1,8 /* check G-bit */ + bne 4f /* if guarded, take ISI */ + mtctr 0 /* restore counter */ + mfspr 0,IMISS /* get the miss address for the tlbli */ + mfsrr1 3 /* get the saved cr0 bits */ + mtcrf 0x80,3 /* and restore */ + ori 1,1,0x100 /* set the reference bit */ + mtspr RPA,1 /* set the pte */ + srwi 1,1,8 /* get byte 7 of pte */ + tlbli 0 /* load the itlb */ + stb 1,6(2) /* update page table */ + rfi + +3: /* not found in pteg */ + andi. 1,3,0x40 /* have we already done second hash? */ + bne 5f + mfspr 2,HASH2 /* get the second pointer */ + ori 3,3,0x40 /* change the compare value */ + li 1,8 + addi 2,2,-8 /* predec pointer */ + b 1b +4: /* guarded */ + mfsrr1 3 + andi. 2,3,0xffff /* clean upper srr1 */ + addis 2,2,0x800 /* set srr<4> to flag prot violation */ + b 6f +5: /* not found anywhere */ + mfsrr1 3 + andi. 2,3,0xffff /* clean upper srr1 */ + addis 2,2,0x4000 /* set srr1<1> to flag pte not found */ +6: + mtctr 0 /* restore counter */ + mtsrr1 2 + mfmsr 0 + xoris 0,0,2 /* flip the msr<tgpr> bit */ + mtcrf 0x80,3 /* restore cr0 */ + mtmsr 0 /* now with native gprs */ + isync + ba EXC_ISI +_C_LABEL(tlbimsize) = .-_C_LABEL(tlbimiss) + + .globl _C_LABEL(tlbdlmiss),_C_LABEL(tlbdlmsize) + .type _C_LABEL(tlbdlmiss),@function + .type _C_LABEL(tlbdlmsize),@object +_C_LABEL(tlbdlmiss): + mfspr 2,HASH1 /* get first pointer */ + li 1,8 + mfctr 0 /* save counter */ + mfspr 3,DCMP /* get first compare value */ + addi 2,2,-8 /* predec pointer */ +1: + mtctr 1 /* load counter */ +2: + lwzu 1,8(2) /* get next pte */ + cmpl 0,1,3 /* see if found pte */ + bdneq 2b /* loop if not eq */ + bne 3f /* not found */ + lwz 1,4(2) /* load tlb entry lower word */ + mtctr 0 /* restore counter */ + mfspr 0,DMISS /* get the miss address for the tlbld */ + mfsrr1 3 /* get the saved cr0 bits */ + mtcrf 0x80,3 /* and restore */ + ori 1,1,0x100 /* set the reference bit */ + mtspr RPA,1 /* set the pte */ + srwi 1,1,8 /* get byte 7 of pte */ + tlbld 0 /* load the dtlb */ + stb 1,6(2) /* update page table */ + rfi + +3: /* not found in pteg */ + andi. 1,3,0x40 /* have we already done second hash? */ + bne 5f + mfspr 2,HASH2 /* get the second pointer */ + ori 3,3,0x40 /* change the compare value */ + li 1,8 + addi 2,2,-8 /* predec pointer */ + b 1b +5: /* not found anywhere */ + mfsrr1 3 + lis 1,0x4000 /* set dsisr<1> to flag pte not found */ + mtctr 0 /* restore counter */ + andi. 2,3,0xffff /* clean upper srr1 */ + mtsrr1 2 + mtdsisr 1 /* load the dsisr */ + mfspr 1,DMISS /* get the miss address */ + mtdar 1 /* put in dar */ + mfmsr 0 + xoris 0,0,2 /* flip the msr<tgpr> bit */ + mtcrf 0x80,3 /* restore cr0 */ + mtmsr 0 /* now with native gprs */ + isync + ba EXC_DSI +_C_LABEL(tlbdlmsize) = .-_C_LABEL(tlbdlmiss) + + .globl _C_LABEL(tlbdsmiss),_C_LABEL(tlbdsmsize) + .type _C_LABEL(tlbdsmiss),@function + .type _C_LABEL(tlbdsmsize),@object +_C_LABEL(tlbdsmiss): + mfspr 2,HASH1 /* get first pointer */ + li 1,8 + mfctr 0 /* save counter */ + mfspr 3,DCMP /* get first compare value */ + addi 2,2,-8 /* predec pointer */ +1: + mtctr 1 /* load counter */ +2: + lwzu 1,8(2) /* get next pte */ + cmpl 0,1,3 /* see if found pte */ + bdneq 2b /* loop if not eq */ + bne 3f /* not found */ + lwz 1,4(2) /* load tlb entry lower word */ + andi. 3,1,0x80 /* check the C-bit */ + beq 4f +5: + mtctr 0 /* restore counter */ + mfspr 0,DMISS /* get the miss address for the tlbld */ + mfsrr1 3 /* get the saved cr0 bits */ + mtcrf 0x80,3 /* and restore */ + mtspr RPA,1 /* set the pte */ + tlbld 0 /* load the dtlb */ + rfi + +3: /* not found in pteg */ + andi. 1,3,0x40 /* have we already done second hash? */ + bne 5f + mfspr 2,HASH2 /* get the second pointer */ + ori 3,3,0x40 /* change the compare value */ + li 1,8 + addi 2,2,-8 /* predec pointer */ + b 1b +4: /* found, but C-bit = 0 */ + rlwinm. 3,1,30,0,1 /* test PP */ + bge- 7f + andi. 3,1,1 + beq+ 8f +9: /* found, but protection violation (PP==00)*/ + mfsrr1 3 + lis 1,0xa00 /* indicate protection violation on store */ + b 1f +7: /* found, PP=1x */ + mfspr 3,DMISS /* get the miss address */ + mfsrin 1,3 /* get the segment register */ + mfsrr1 3 + rlwinm 3,3,18,31,31 /* get PR-bit */ + rlwnm. 2,2,3,1,1 /* get the key */ + bne- 9b /* protection violation */ +8: /* found, set reference/change bits */ + lwz 1,4(2) /* reload tlb entry */ + ori 1,1,0x180 + sth 1,6(2) + b 5b +5: /* not found anywhere */ + mfsrr1 3 + lis 1,0x4200 /* set dsisr<1> to flag pte not found */ + /* dsisr<6> to flag store */ +1: + mtctr 0 /* restore counter */ + andi. 2,3,0xffff /* clean upper srr1 */ + mtsrr1 2 + mtdsisr 1 /* load the dsisr */ + mfspr 1,DMISS /* get the miss address */ + mtdar 1 /* put in dar */ + mfmsr 0 + xoris 0,0,2 /* flip the msr<tgpr> bit */ + mtcrf 0x80,3 /* restore cr0 */ + mtmsr 0 /* now with native gprs */ + isync + ba EXC_DSI +_C_LABEL(tlbdsmsize) = .-_C_LABEL(tlbdsmiss) + +#ifdef DDB +#define ddbsave 0xde0 /* primary save area for DDB */ +/* + * In case of DDB we want a separate trap catcher for it + */ + .local ddbstk + .comm ddbstk,INTSTK,8 /* ddb stack */ + + .globl _C_LABEL(ddblow),_C_LABEL(ddbsize) +_C_LABEL(ddblow): + mtsprg 1,1 /* save SP */ + stmw 28,ddbsave(0) /* free r28-r31 */ + mflr 28 /* save LR */ + mfcr 29 /* save CR */ + lis 1,ddbstk+INTSTK@ha /* get new SP */ + addi 1,1,ddbstk+INTSTK@l + bla ddbtrap +_C_LABEL(ddbsize) = .-_C_LABEL(ddblow) +#endif /* DDB */ + +#if NIPKDB > 0 +#define ipkdbsave 0xde0 /* primary save area for IPKDB */ +/* + * In case of IPKDB we want a separate trap catcher for it + */ +.lcomm ipkdbstk,INTSTK /* ipkdb stack */ + + .globl _C_LABEL(ipkdblow),_C_LABEL(ipkdbsize) + .type _C_LABEL(ipkdblow),@function + .type _C_LABEL(ipkdbsize),@object +_C_LABEL(ipkdblow): + mtsprg 1,1 /* save SP */ + stmw 28,ipkdbsave(0) /* free r28-r31 */ + lis 1,ipkdbstk+INTSTK@ha /* get new SP */ + addi 1,1,ipkdbstk+INTSTK@l + mflr 28 + mfcr 29 + bla ipkdbtrap +_C_LABEL(ipkdbsize) = .-_C_LABEL(ipkdblow) +#endif /* NIPKDB > 0 */ + +/* + * FRAME_SETUP assumes: + * SPRG1 SP (1) + * savearea r28-r31,DAR,DSISR (DAR & DSISR only for DSI traps) + * 28 LR + * 29 CR + * 1 kernel stack + * LR trap type + * SRR0/1 as at start of trap + */ +#define FRAME_SETUP(savearea) \ +/* Have to enable translation to allow access of kernel stack: */ \ + mfsrr0 30; \ + mfsrr1 31; \ + stmw 30,savearea+24(0); \ + mfmsr 30; \ + ori 30,30,(PSL_DR|PSL_IR); \ + mtmsr 30; \ + isync; \ + mfsprg 31,1; \ + stwu 31,-FRAMELEN(1); \ + stw 0,FRAME_0+8(1); \ + stw 31,FRAME_1+8(1); \ + stw 28,FRAME_LR+8(1); \ + stw 29,FRAME_CR+8(1); \ + lmw 28,savearea(0); \ + stmw 2,FRAME_2+8(1); \ + lmw 28,savearea+16(0); \ + mfxer 3; \ + mfctr 4; \ + mflr 5; \ + andi. 5,5,0xff00; \ + stw 3,FRAME_XER+8(1); \ + stw 4,FRAME_CTR+8(1); \ + stw 5,FRAME_EXC+8(1); \ + stw 28,FRAME_DAR+8(1); \ + stw 29,FRAME_DSISR+8(1); \ + stw 30,FRAME_SRR0+8(1); \ + stw 31,FRAME_SRR1+8(1) + +#define FRAME_LEAVE(savearea) \ +/* Now restore regs: */ \ + lwz 2,FRAME_SRR0+8(1); \ + lwz 3,FRAME_SRR1+8(1); \ + lwz 4,FRAME_CTR+8(1); \ + lwz 5,FRAME_XER+8(1); \ + lwz 6,FRAME_LR+8(1); \ + lwz 7,FRAME_CR+8(1); \ + stw 2,savearea(0); \ + stw 3,savearea+4(0); \ + mtctr 4; \ + mtxer 5; \ + mtlr 6; \ + mtsprg 1,7; /* save cr */ \ + lmw 2,FRAME_2+8(1); \ + lwz 0,FRAME_0+8(1); \ + lwz 1,FRAME_1+8(1); \ + mtsprg 2,2; /* save r2 & r3 */ \ + mtsprg 3,3; \ +/* Disable translation, machine check and recoverability: */ \ + mfmsr 2; \ + lis 3,(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@ha; \ + addi 3,3,(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@l; \ + andc 2,2,3; \ + mtmsr 2; \ + isync; \ +/* Decide whether we return to user mode: */ \ + lwz 3,savearea+4(0); \ + mtcr 3; \ + bc 4,17,1f; /* branch if PSL_PR is false */ \ +/* Restore user & kernel access SR: */ \ + lis 2,_C_LABEL(curpm)@ha; /* get real address of pmap */ \ + lwz 2,_C_LABEL(curpm)@l(2); \ + lwz 3,PM_USRSR(2); \ + mtsr USER_SR,3; \ + lwz 3,PM_KERNELSR(2); \ + mtsr KERNEL_SR,3; \ +1: mfsprg 2,1; /* restore cr */ \ + mtcr 2; \ + lwz 2,savearea(0); \ + lwz 3,savearea+4(0); \ + mtsrr0 2; \ + mtsrr1 3; \ + mfsprg 2,2; /* restore r2 & r3 */ \ + mfsprg 3,3 + +/* + * Preamble code for DSI/ISI traps + */ +disitrap: + lmw 30,disisave(0) + stmw 30,tempsave(0) + lmw 30,disisave+8(0) + stmw 30,tempsave+8(0) + mfdar 30 + mfdsisr 31 + stmw 30,tempsave+16(0) +realtrap: +/* Test whether we already had PR set */ + mfsrr1 1 + mtcr 1 + mfsprg 1,1 /* restore SP (might have been overwritten) */ + bc 4,17,s_trap /* branch if PSL_PR is false */ + lis 1,_C_LABEL(curpcb)@ha + lwz 1,_C_LABEL(curpcb)@l(1) + addi 1,1,USPACE /* stack is top of user struct */ +/* + * Now the common trap catching code. + */ +s_trap: +/* First have to enable KERNEL mapping */ + lis 31,KERNEL_SEGMENT@ha + addi 31,31,KERNEL_SEGMENT@l + mtsr KERNEL_SR,31 + FRAME_SETUP(tempsave) +/* Now we can recover interrupts again: */ + mfmsr 7 + ori 7,7,(PSL_EE|PSL_ME|PSL_RI) + mtmsr 7 + isync +/* Call C trap code: */ +trapagain: + addi 3,1,8 + bl _C_LABEL(trap) +trapexit: +/* Disable interrupts: */ + mfmsr 3 + andi. 3,3,~PSL_EE@l + mtmsr 3 +/* Test AST pending: */ + lwz 5,FRAME_SRR1+8(1) + mtcr 5 + bc 4,17,1f /* branch if PSL_PR is false */ + lis 3,_C_LABEL(astpending)@ha + lwz 4,_C_LABEL(astpending)@l(3) + andi. 4,4,1 + beq 1f + li 6,EXC_AST + stw 6,FRAME_EXC+8(1) + b trapagain +1: + FRAME_LEAVE(tempsave) + rfi + +/* + * Child comes here at the end of a fork. + * Mostly similar to the above. + */ + .globl _C_LABEL(fork_trampoline) + .type _C_LABEL(fork_trampoline),@function +_C_LABEL(fork_trampoline): + xor 3,3,3 + bl _C_LABEL(lcsplx) + mtlr 31 + mr 3,30 + blrl /* jump indirect to r31 */ + b trapexit + +/* + * DSI second stage fault handler + */ +s_dsitrap: + mfdsisr 31 /* test whether this may be a spill fault */ + mtcr 31 + mtsprg 1,1 /* save SP */ + bc 4,1,disitrap /* branch if table miss is false */ + lis 1,spillstk+SPILLSTK@ha + addi 1,1,spillstk+SPILLSTK@l /* get spill stack */ + stwu 1,-52(1) + stw 0,48(1) /* save non-volatile registers */ + stw 3,44(1) + stw 4,40(1) + stw 5,36(1) + stw 6,32(1) + stw 7,28(1) + stw 8,24(1) + stw 9,20(1) + stw 10,16(1) + stw 11,12(1) + stw 12,8(1) + mflr 30 /* save trap type */ + mfctr 31 /* & CTR */ + mfdar 3 +s_pte_spill: + bl _C_LABEL(pte_spill) /* try a spill */ + or. 3,3,3 + mtctr 31 /* restore CTR */ + mtlr 30 /* and trap type */ + mfsprg 31,2 /* get saved XER */ + mtxer 31 /* restore XER */ + lwz 12,8(1) /* restore non-volatile registers */ + lwz 11,12(1) + lwz 10,16(1) + lwz 9,20(1) + lwz 8,24(1) + lwz 7,28(1) + lwz 6,32(1) + lwz 5,36(1) + lwz 4,40(1) + lwz 3,44(1) + lwz 0,48(1) + beq disitrap + mfsprg 1,1 /* restore SP */ + mtcr 29 /* restore CR */ + mtlr 28 /* restore LR */ + lmw 28,disisave(0) /* restore r28-r31 */ + rfi /* return to trapped code */ + +/* + * ISI second stage fault handler + */ +s_isitrap: + mfsrr1 31 /* test whether this may be a spill fault */ + mtcr 31 + mtsprg 1,1 /* save SP */ + bc 4,1,disitrap /* branch if table miss is false */ + lis 1,spillstk+SPILLSTK@ha + addi 1,1,spillstk+SPILLSTK@l /* get spill stack */ + stwu 1,-52(1) + stw 0,48(1) /* save non-volatile registers */ + stw 3,44(1) + stw 4,40(1) + stw 5,36(1) + stw 6,32(1) + stw 7,28(1) + stw 8,24(1) + stw 9,20(1) + stw 10,16(1) + stw 11,12(1) + stw 12,8(1) + mfxer 30 /* save XER */ + mtsprg 2,30 + mflr 30 /* save trap type */ + mfctr 31 /* & ctr */ + mfsrr0 3 + b s_pte_spill /* above */ + +/* + * External interrupt second level handler + */ +#define INTRENTER \ +/* Save non-volatile registers: */ \ + stwu 1,-88(1); /* temporarily */ \ + stw 0,84(1); \ + mfsprg 0,1; /* get original SP */ \ + stw 0,0(1); /* and store it */ \ + stw 3,80(1); \ + stw 4,76(1); \ + stw 5,72(1); \ + stw 6,68(1); \ + stw 7,64(1); \ + stw 8,60(1); \ + stw 9,56(1); \ + stw 10,52(1); \ + stw 11,48(1); \ + stw 12,44(1); \ + stw 28,40(1); /* saved LR */ \ + stw 29,36(1); /* saved CR */ \ + stw 30,32(1); /* saved XER */ \ + lmw 28,tempsave(0); /* restore r28-r31 */ \ + mfctr 6; \ + lis 5,_C_LABEL(intr_depth)@ha; \ + lwz 5,_C_LABEL(intr_depth)@l(5); \ + mfsrr0 4; \ + mfsrr1 3; \ + stw 6,28(1); \ + stw 5,20(1); \ + stw 4,12(1); \ + stw 3,8(1); \ +/* interrupts are recoverable here, and enable translation */ \ + lis 3,(KERNEL_SEGMENT|SR_SUKEY|SR_PRKEY)@ha; \ + addi 3,3,(KERNEL_SEGMENT|SR_SUKEY|SR_PRKEY)@l; \ + mtsr KERNEL_SR,3; \ + mfmsr 5; \ + ori 5,5,(PSL_IR|PSL_DR|PSL_RI); \ + mtmsr 5; \ + isync + + .globl _C_LABEL(extint_call) + .type _C_LABEL(extint_call),@function +extintr: + INTRENTER +_C_LABEL(extint_call): + bl _C_LABEL(extint_call) /* to be filled in later */ +intr_exit: +/* Disable interrupts (should already be disabled) and MMU here: */ + mfmsr 3 + andi. 3,3,~(PSL_EE|PSL_ME|PSL_RI|PSL_DR|PSL_IR)@l + mtmsr 3 + isync +/* restore possibly overwritten registers: */ + lwz 12,44(1) + lwz 11,48(1) + lwz 10,52(1) + lwz 9,56(1) + lwz 8,60(1) + lwz 7,64(1) + lwz 6,8(1) + lwz 5,12(1) + lwz 4,28(1) + lwz 3,32(1) + mtsrr1 6 + mtsrr0 5 + mtctr 4 + mtxer 3 +/* Returning to user mode? */ + mtcr 6 /* saved SRR1 */ + bc 4,17,1f /* branch if PSL_PR is false */ + lis 3,_C_LABEL(curpm)@ha /* get current pmap real address */ + lwz 3,_C_LABEL(curpm)@l(3) + lwz 3,PM_KERNELSR(3) + mtsr KERNEL_SR,3 /* Restore kernel SR */ + lis 3,_C_LABEL(astpending)@ha /* Test AST pending */ + lwz 4,_C_LABEL(astpending)@l(3) + andi. 4,4,1 + beq 1f +/* Setup for entry to realtrap: */ + lwz 3,0(1) /* get saved SP */ + mtsprg 1,3 + li 6,EXC_AST + stmw 28,tempsave(0) /* establish tempsave again */ + mtlr 6 + lwz 28,40(1) /* saved LR */ + lwz 29,36(1) /* saved CR */ + lwz 6,68(1) + lwz 5,72(1) + lwz 4,76(1) + lwz 3,80(1) + lwz 0,84(1) + lis 30,_C_LABEL(intr_depth)@ha /* adjust reentrancy count */ + lwz 31,_C_LABEL(intr_depth)@l(30) + addi 31,31,-1 + stw 31,_C_LABEL(intr_depth)@l(30) + b realtrap +1: +/* Here is the normal exit of extintr: */ + lwz 5,36(1) + lwz 6,40(1) + mtcr 5 + mtlr 6 + lwz 6,68(1) + lwz 5,72(1) + lis 3,_C_LABEL(intr_depth)@ha /* adjust reentrancy count */ + lwz 4,_C_LABEL(intr_depth)@l(3) + addi 4,4,-1 + stw 4,_C_LABEL(intr_depth)@l(3) + lwz 4,76(1) + lwz 3,80(1) + lwz 0,84(1) + lwz 1,0(1) + rfi + +/* + * Decrementer interrupt second level handler + */ +decrintr: + INTRENTER + addi 3,1,8 /* intr frame */ + bl _C_LABEL(decr_intr) + b intr_exit + +#ifdef DDB +/* + * Deliberate entry to ddbtrap + */ + .globl _C_LABEL(ddb_trap) +_C_LABEL(ddb_trap): + mtsprg 1,1 + mfmsr 3 + mtsrr1 3 + andi. 3,3,~(PSL_EE|PSL_ME)@l + mtmsr 3 /* disable interrupts */ + isync + stmw 28,ddbsave(0) + mflr 28 + li 29,EXC_BPT + mtlr 29 + mfcr 29 + mtsrr0 28 + +/* + * Now the ddb trap catching code. + */ +ddbtrap: + FRAME_SETUP(ddbsave) +/* Call C trap code: */ + addi 3,1,8 + bl _C_LABEL(ddb_trap_glue) + or. 3,3,3 + bne ddbleave +/* This wasn't for DDB, so switch to real trap: */ + lwz 3,FRAME_EXC+8(1) /* save exception */ + stw 3,ddbsave+8(0) + FRAME_LEAVE(ddbsave) + mtsprg 1,1 /* prepare for entrance to realtrap */ + stmw 28,tempsave(0) + mflr 28 + mfcr 29 + lwz 31,ddbsave+8(0) + mtlr 31 + b realtrap +ddbleave: + FRAME_LEAVE(ddbsave) + rfi +#endif /* DDB */ + +#if NIPKDB > 0 +/* + * Deliberate entry to ipkdbtrap + */ + .globl _C_LABEL(ipkdb_trap) + .type _C_LABEL(ipkdb_trap),@function +_C_LABEL(ipkdb_trap): + + mtsprg 2,2 + mfmsr 3 + mtsrr1 3 + andi. 3,3,~(PSL_EE|PSL_ME)@l + mtmsr 3 /* disable interrupts */ + isync + stmw 28,ipkdbsave(0) + mflr 28 + li 29,EXC_BPT + mtlr 29 + mfcr 29 + mtsrr0 28 + +/* + * Now the ipkdb trap catching code. + */ +ipkdbtrap: + FRAME_SETUP(ipkdbsave) +/* Call C trap code: */ + addi 3,1,8 + bl _C_LABEL(ipkdb_trap_glue) + or. 3,3,3 + bne ipkdbleave +/* This wasn't for IPKDB, so switch to real trap: */ + lwz 3,FRAME_EXC+8(1) /* save exception */ + stw 3,ipkdbsave+8(0) + FRAME_LEAVE(ipkdbsave) + mtsprg 1,1 /* prepare for entrance to realtrap */ + stmw 28,tempsave(0) + mflr 28 + mfcr 29 + lwz 31,ipkdbsave+8(0) + mtlr 31 + b realtrap +ipkdbleave: + FRAME_LEAVE(ipkdbsave) + rfi + +ipkdbfault: + ba _C_LABEL(ipkdbfault) +_C_LABEL(ipkdbfault): + mfsrr0 3 + addi 3,3,4 + mtsrr0 3 + li 3,-1 + rfi + +/* + * int ipkdbfbyte(unsigned char *p) + */ + .globl _C_LABEL(ipkdbfbyte) + .type _C_LABEL(ipkdbfbyte),@function +_C_LABEL(ipkdbfbyte): + li 9,EXC_DSI /* establish new fault routine */ + lwz 5,0(9) + lis 6,ipkdbfault@ha + lwz 6,ipkdbfault@l(6) + stw 6,0(9) +#ifdef IPKDBUSERHACK + lis 8,_C_LABEL(ipkdbsr)@ha + lwz 8,_C_LABEL(ipkdbsr)@l(8) + mtsr USER_SR,8 + isync +#endif + dcbst 0,9 /* flush data... */ + sync + icbi 0,9 /* and instruction caches */ + lbz 3,0(3) /* fetch data */ + stw 5,0(9) /* restore previous fault handler */ + dcbst 0,9 /* and flush data... */ + sync + icbi 0,9 /* and instruction caches */ + blr + +/* + * int ipkdbsbyte(unsigned char *p, int c) + */ + .globl _C_LABEL(ipkdbsbyte) + .type _C_LABEL(ipkdbsbyte),@function +_C_LABEL(ipkdbsbyte): + li 9,EXC_DSI /* establish new fault routine */ + lwz 5,0(9) + lis 6,ipkdbfault@ha + lwz 6,ipkdbfault@l(6) + stw 6,0(9) +#ifdef IPKDBUSERHACK + lis 8,_C_LABEL(ipkdbsr)@ha + lwz 8,_C_LABEL(ipkdbsr)@l(8) + mtsr USER_SR,8 + isync +#endif + dcbst 0,9 /* flush data... */ + sync + icbi 0,9 /* and instruction caches */ + mr 6,3 + xor 3,3,3 + stb 4,0(6) + dcbst 0,6 /* Now do appropriate flushes to data... */ + sync + icbi 0,6 /* and instruction caches */ + stw 5,0(9) /* restore previous fault handler */ + dcbst 0,9 /* and flush data... */ + sync + icbi 0,9 /* and instruction caches */ + blr +#endif /* NIPKDB > 0 */ + +/* + * int setfault() + * + * Similar to setjmp to setup for handling faults on accesses to user memory. + * Any routine using this may only call bcopy, either the form below, + * or the (currently used) C code optimized, so it doesn't use any non-volatile + * registers. + */ + .globl _C_LABEL(setfault) + .type _C_LABEL(setfault),@function +_C_LABEL(setfault): + mflr 0 + mfcr 12 + mfmsr 2 + lis 4,_C_LABEL(curpcb)@ha + lwz 4,_C_LABEL(curpcb)@l(4) + stw 3,PCB_FAULT(4) + stw 0,0(3) + stw 2,4(3) + stw 1,8(3) + stmw 12,12(3) + xor 3,3,3 + blr + +/* + * The following code gets copied to the top of the user stack on process + * execution. It does signal trampolining on signal delivery. + * + * On entry r1 points to a struct sigframe at bottom of current stack. + * All other registers are unchanged. + */ + .globl _C_LABEL(sigcode),_C_LABEL(esigcode) + .type _C_LABEL(sigcode),@function + .type _C_LABEL(esigcode),@function +_C_LABEL(sigcode): + addi 1,1,-16 /* reserved space for callee */ + blrl + addi 3,1,16+8 /* compute &sf_sc */ + li 0,SYS_sigreturn + sc /* sigreturn(scp) */ + li 0,SYS_exit + sc /* exit(errno) */ +_C_LABEL(esigcode): + + + + .data + .globl _C_LABEL(intrnames) + .type _C_LABEL(intrnames),@object + .globl _C_LABEL(eintrnames) + .type _C_LABEL(eintrnames),@object +_C_LABEL(intrnames): + .string "irq0" "irq1" "irq2" "irq3" + .string "irq4" "irq5" "irq6" "irq7" + .string "irq8" "irq9" "irq10" "irq11" + .string "irq12" "irq13" "irq14" "irq15" + .string "irq16" "irq17" "irq18" "irq19" + .string "irq20" "irq21" "irq22" "irq23" + .string "irq24" "irq25" "irq26" "irq27" + .string "irq28" "irq29" "irq30" "irq31" + .string "irq32" "irq33" "irq34" "irq35" + .string "irq36" "irq37" "irq38" "irq39" + .string "irq40" "irq41" "irq42" "irq43" + .string "irq44" "irq45" "irq46" "irq47" + .string "irq48" "irq49" "irq50" "irq51" + .string "irq52" "irq53" "irq54" "irq55" + .string "irq56" "irq57" "irq58" "irq59" + .string "irq60" "irq61" "irq62" "irq63" + .string "clock" + .space 512 +_C_LABEL(eintrnames): + .align 4 + .globl _C_LABEL(intrcnt) + .type _C_LABEL(intrcnt),@object + .globl _C_LABEL(eintrcnt) + .type _C_LABEL(eintrcnt),@object +_C_LABEL(intrcnt): + .long 0,0,0,0 + .long 0,0,0,0 + .long 0,0,0,0 + .long 0,0,0,0 + .long 0,0,0,0 + .long 0,0,0,0 + .long 0,0,0,0 + .long 0,0,0,0 + .long 0,0,0,0 + .long 0,0,0,0 + .long 0,0,0,0 + .long 0,0,0,0 + .long 0,0,0,0 + .long 0,0,0,0 + .long 0,0,0,0 + .long 0,0,0,0 + .long 0 +_C_LABEL(eintrcnt): diff --git a/sys/arch/mvmeppc/mvmeppc/machdep.c b/sys/arch/mvmeppc/mvmeppc/machdep.c new file mode 100644 index 00000000000..387d81ad226 --- /dev/null +++ b/sys/arch/mvmeppc/mvmeppc/machdep.c @@ -0,0 +1,1594 @@ +/* $OpenBSD: machdep.c,v 1.1 2001/06/26 21:57:54 smurph Exp $ */ +/* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */ + +/* + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "machine/ipkdb.h" + +#include <sys/param.h> +#include <sys/buf.h> +#include <sys/timeout.h> +#include <sys/exec.h> +#include <sys/malloc.h> +#include <sys/map.h> +#include <sys/mbuf.h> +#include <sys/mount.h> +#include <sys/msgbuf.h> +#include <sys/proc.h> +#include <sys/signalvar.h> +#include <sys/reboot.h> +#include <sys/syscallargs.h> +#include <sys/syslog.h> +#include <sys/extent.h> +#include <sys/systm.h> +#include <sys/user.h> + +#include <vm/vm.h> +#include <vm/vm_kern.h> + +#ifdef SYSVSHM +#include <sys/shm.h> +#endif +#ifdef SYSVSEM +#include <sys/sem.h> +#endif +#ifdef SYSVMSG +#include <sys/msg.h> +#endif +#include <net/netisr.h> + +#include <machine/bat.h> +#include <machine/pmap.h> +#include <machine/powerpc.h> +#include <machine/trap.h> +#include <machine/autoconf.h> +#include <machine/bus.h> +#include <machine/pio.h> +#include <machine/prom.h> + +#ifdef DDB +#include <machine/db_machdep.h> +#include <ddb/db_access.h> +#include <ddb/db_sym.h> +#include <ddb/db_extern.h> +#endif + +/* + * Global variables used here and there + */ +struct pcb *curpcb; +struct pmap *curpm; +struct proc *fpuproc; + +extern struct user *proc0paddr; +extern int cold; + +/* + * XXX this is to fake out the console routines, while + * booting. New and improved! :-) smurph + */ +#include <dev/cons.h> + +int bootcnprobe __P((struct consdev *)); +int bootcninit __P((struct consdev *)); +void bootcnputc __P((dev_t, char)); +int bootcngetc __P((dev_t)); +extern void nullcnpollc __P((dev_t, int)); +#define bootcnpollc nullcnpollc +static struct consdev bootcons = { + (void (*))NULL, + (void (*))NULL, + bootcngetc, + (void (*))bootcnputc, + bootcnpollc, + (void (*))NULL, + makedev(14,0), + 1 +}; + +u_int32_t ppc_get_msr __P((void)); +u_int32_t ppc_set_msr __P((u_int32_t)); + +/* + * Declare these as initialized data so we can patch them. + */ +int nswbuf = 0; +#ifdef NBUF +int nbuf = NBUF; +#else +int nbuf = 0; +#endif +#ifdef BUFPAGES +int bufpages = BUFPAGES; +#else +int bufpages = 0; +#endif + +struct bat battable[16]; + +#ifdef UVM +/* ??? */ +vm_map_t exec_map = NULL; +vm_map_t mb_map = NULL; +vm_map_t phys_map = NULL; +#endif + +int astpending; +int ppc_malloc_ok = 0; + +#ifndef SYS_TYPE +/* XXX Hardwire it for now */ +#define SYS_TYPE MVME +#endif + +int system_type = SYS_TYPE; /* XXX Hardwire it for now */ + +char *bootpath; +char bootpathbuf[512]; + +struct firmware *fw = NULL; +extern struct firmware ppc1_firmware; + +caddr_t allocsys __P((caddr_t)); + +/* + * Extent maps to manage I/O. Allocate storage for 8 regions in each, + * initially. Later devio_malloc_safe will indicate that it's save to + * use malloc() to dynamically allocate region descriptors. + */ +static long devio_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof (long)]; +struct extent *devio_ex; +static int devio_malloc_safe = 0; + +/* HACK - XXX */ +int segment8_mapped = 0; +int segment0_mapped = 0; +int segmentC_mapped = 0; +unsigned char fw_vectors[0x3000]; + +extern int where; + +void +initppc(startkernel, endkernel, args) + u_int startkernel, endkernel; + char *args; +{ + int phandle, qhandle; + char name[32]; + struct machvec *mp; + extern trapcode, trapsize; + extern dsitrap, dsisize; + extern isitrap, isisize; + extern alitrap, alisize; + extern decrint, decrsize; + extern tlbimiss, tlbimsize; + extern tlbdlmiss, tlbdlmsize; + extern tlbdsmiss, tlbdsmsize; +#ifdef DDB + extern ddblow, ddbsize; +#endif +#if NIPKDB > 0 + extern ipkdblow, ipkdbsize; +#endif + extern void consinit __P((void)); + extern void callback __P((void *)); + int exc, scratch; + u_int32_t msr; + + proc0.p_addr = proc0paddr; + bzero(proc0.p_addr, sizeof *proc0.p_addr); + + bcopy((void *)0, &fw_vectors[0], 0x3000); + fw = &ppc1_firmware; /* Just PPC1-Bug for now... */ + /* + * XXX We use the page just above the interrupt vector as + * message buffer + */ + initmsgbuf((void *)0x3000, MSGBUFSIZE); + where = 3; + + curpcb = &proc0paddr->u_pcb; + + curpm = curpcb->pcb_pmreal = curpcb->pcb_pm = pmap_kernel(); + + /* startup fake console driver. It will be replaced by consinit() */ + cn_tab = &bootcons; +#ifdef STEVE_DEBUG + printf("initmsgbuf() done.\n"); +#endif + /* + * Initialize BAT registers to unmapped to not generate + * overlapping mappings below. + */ + __asm__ volatile ("mtibatu 0,%0" :: "r"(0)); + __asm__ volatile ("mtibatu 1,%0" :: "r"(0)); + __asm__ volatile ("mtibatu 2,%0" :: "r"(0)); + __asm__ volatile ("mtibatu 3,%0" :: "r"(0)); + __asm__ volatile ("mtdbatu 0,%0" :: "r"(0)); + __asm__ volatile ("mtdbatu 1,%0" :: "r"(0)); + __asm__ volatile ("mtdbatu 2,%0" :: "r"(0)); + __asm__ volatile ("mtdbatu 3,%0" :: "r"(0)); + + /* + * Set up initial BAT table to only map the lowest 256 MB area + */ + battable[0].batl = BATL(0x00000000, BAT_M); + battable[0].batu = BATU(0x00000000); + + /* map all of possible physical memory, ick */ + battable[0x1].batl = BATL(0x10000000, BAT_M); + battable[0x1].batu = BATU(0x10000000); + battable[0x2].batl = BATL(0x20000000, BAT_M); + battable[0x2].batu = BATU(0x20000000); + battable[0x3].batl = BATL(0x30000000, BAT_M); + battable[0x3].batu = BATU(0x30000000); + battable[0x4].batl = BATL(0x40000000, BAT_M); + battable[0x4].batu = BATU(0x40000000); + battable[0x5].batl = BATL(0x50000000, BAT_M); + battable[0x5].batu = BATU(0x50000000); + battable[0x6].batl = BATL(0x60000000, BAT_M); + battable[0x6].batu = BATU(0x60000000); + battable[0x7].batl = BATL(0x70000000, BAT_M); + battable[0x7].batu = BATU(0x70000000); + + battable[0x8].batl = BATL(0x80000000, BAT_I); + battable[0x8].batu = BATU(0x80000000); + battable[0x9].batl = BATL(0x90000000, BAT_I); + battable[0x9].batu = BATU(0x90000000); + battable[0xa].batl = BATL(0xf0000000, BAT_I); + battable[0xa].batu = BATU(0xf0000000); + + segment0_mapped = 1; + segment8_mapped = 1; + segmentC_mapped = 0; + + /* + * Now setup fixed bat registers + * + * Note that we still run in real mode, and the BAT + * registers were cleared above. + */ + /* IBAT0 used for initial 256 MB segment */ + __asm__ volatile ("mtibatl 0,%0; mtibatu 0,%1" + :: "r"(battable[0].batl), "r"(battable[0].batu)); + /* DBAT0 used similar */ + __asm__ volatile ("mtdbatl 0,%0; mtdbatu 0,%1" + :: "r"(battable[0].batl), "r"(battable[0].batu)); + +#if 0 + __asm__ volatile ("mtdbatl 1,%0; mtdbatu 1,%1" + :: "r"(battable[1].batl), "r"(battable[1].batu)); + __asm__ volatile ("sync;isync"); +#endif + /* IBAT1 used for last 256 MB segment ROM */ + __asm__ volatile ("mtibatl 1,%0; mtibatu 1,%1" + :: "r"(battable[0xa].batl), "r"(battable[0xa].batu)); + /* DBAT1 used similar */ + __asm__ volatile ("mtdbatl 1,%0; mtdbatu 1,%1" + :: "r"(battable[0xa].batl), "r"(battable[0xa].batu)); + /* IBAT2 used for last 256 MB segment ROM */ + __asm__ volatile ("mtibatl 2,%0; mtibatu 2,%1" + :: "r"(battable[0x8].batl), "r"(battable[0x8].batu)); + /* DBAT2 used similar */ + __asm__ volatile ("mtdbatl 2,%0; mtdbatu 2,%1" + :: "r"(battable[0x8].batl), "r"(battable[0x8].batu)); + +#if 0 + /* IBAT3 used for last 256 MB segment ROM */ + __asm__ volatile ("mtibatl 3,%0; mtibatu 3,%1" + :: "r"(battable[0x3].batl), "r"(battable[0x3].batu)); + /* DBAT3 used similar */ + __asm__ volatile ("mtdbatl 3,%0; mtdbatu 3,%1" + :: "r"(battable[0x3].batl), "r"(battable[0x3].batu)); +#endif +#ifdef STEVE_DEBUG + printf("bats mapped.\n"); +#endif +#if 1 + /* + * Set up trap vectors + */ + for (exc = EXC_RSVD; exc <= EXC_LAST; exc += 0x100) + switch (exc) { + default: + bcopy(&trapcode, (void *)exc, (size_t)&trapsize); + break; + case EXC_EXI: + /* + * This one is (potentially) installed during autoconf + */ + break; +#if 1 + case EXC_DSI: + bcopy(&dsitrap, (void *)EXC_DSI, (size_t)&dsisize); + break; + case EXC_ISI: + bcopy(&isitrap, (void *)EXC_ISI, (size_t)&isisize); + break; + case EXC_ALI: + bcopy(&alitrap, (void *)EXC_ALI, (size_t)&alisize); + break; +#endif + case EXC_DECR: + bcopy(&decrint, (void *)EXC_DECR, (size_t)&decrsize); + break; + case EXC_IMISS: + bcopy(&tlbimiss, (void *)EXC_IMISS, (size_t)&tlbimsize); + break; + case EXC_DLMISS: + bcopy(&tlbdlmiss, (void *)EXC_DLMISS, (size_t)&tlbdlmsize); + break; + case EXC_DSMISS: + bcopy(&tlbdsmiss, (void *)EXC_DSMISS, (size_t)&tlbdsmsize); + break; +#if NIPKDB > 0 || defined(DDB) + case EXC_PGM: + case EXC_TRC: + case EXC_BPT: +#ifdef DDB + bcopy(&ddblow, (void *)exc, (size_t)&ddbsize); +#else + bcopy(&ipkdblow, (void *)exc, (size_t)&ipkdbsize); +#endif + break; +#endif + } + + syncicache((void *)EXC_RST, EXC_LAST - EXC_RST + 0x100); +#endif +#ifdef STEVE_DEBUG + printf("vectors set.\n"); +#endif + +#ifdef UVM + uvmexp.pagesize = 4096; + uvm_setpagesize(); +#else + vm_set_page_size(); +#endif + +#ifdef STEVE_DEBUG + printf("page size set.\n"); +#endif + /* + * Initialize pmap module. + */ + pmap_bootstrap(startkernel, endkernel); + + /*(fw->vmon)();*/ + ppc_vmon(); + +#ifdef STEVE_DEBUG + printf("pmap_bootstrap() done.\n"); + /* mvmeprom_return(); */ +#endif + msr = ppc_get_msr(); + msr &= ~PSL_IP; + ppc_set_msr(msr); +#ifdef STEVE_DEBUG + printf("msr == 0x%08x\n", msr); + printf("bit == %032b\n", msr); + printf("made it!\n"); + /* mvmeprom_return(); */ +#endif + + /* + * Now enable translation (and machine checks/recoverable interrupts). + * This will also start using the exception vector prefix of 0x000. + */ + + __asm__ volatile ("eieio; mfmsr %0; ori %0,%0,%1; mtmsr %0; sync;isync" + : "=r"(scratch) : "K"(PSL_IR|PSL_DR|PSL_ME|PSL_RI)); + +#if 1 /*def STEVE_DEBUG*/ + printf("translation enabled.\n"); +#endif + /* + * Look at arguments passed to us and compute boothowto. + * Default to SINGLE and ASKNAME if no args or + * SINGLE and DFLTROOT if this is a ramdisk kernel. + */ +#ifdef RAMDISK_HOOKS + boothowto = RB_SINGLE | RB_DFLTROOT; +#else + boothowto = RB_AUTOBOOT; +#endif /* RAMDISK_HOOKS */ + + /* + * Parse arg string. + */ + + /* make a copy of the args! */ + strncpy(bootpathbuf, args, 512); + bootpath= &bootpathbuf[0]; + args = bootpath; + while ( *++args && *args != ' '); + if (*args) { + *args++ = 0; + while (*args) { + switch (*args++) { + case 'a': + boothowto |= RB_ASKNAME; + break; + case 's': + boothowto |= RB_SINGLE; + break; + case 'd': + boothowto |= RB_KDB; + break; + case 'c': + boothowto |= RB_CONFIG; + break; + } + } + } +#if 0 + ddb_init((int)(esym - (&_end)), &_end, esym); +#endif +#ifdef STEVE_DEBUG + printf("boothowto == %d\n", boothowto); +#endif + /* + * Set up extents for pci mappings + * Is this too late? + * + * what are good start and end values here?? + * 0x0 - 0x80000000 mcu bus + * MAP A MAP B + * 0x80000000 - 0xbfffffff io 0x80000000 - 0xefffffff mem + * 0xc0000000 - 0xffffffff mem 0xf0000000 - 0xffffffff io + * + * of course bsd uses 0xe and 0xf + * So the BSD PPC memory map will look like this + * 0x0 - 0x80000000 memory (whatever is filled) + * 0x80000000 - 0xdfffffff (pci space, memory or io) + * 0xe0000000 - kernel vm segment + * 0xf0000000 - kernel map segment (user space mapped here) + */ + +#ifdef STEVE_DEBUG + printf("before extent_create()\n"); +#endif + prep_bus_space_init(); + devio_ex = extent_create("devio", 0x80000000, 0xffffffff, M_DEVBUF, + (caddr_t)devio_ex_storage, sizeof(devio_ex_storage), + EX_NOCOALESCE|EX_NOWAIT); + +#ifdef STEVE_DEBUG + printf("extent_create() done.\n"); +#endif + /* + * Now we can set up the console as mapping is enabled. + */ +#ifdef STEVE_DEBUG + printf("before consinit()\n"); +#endif + consinit(); +#ifdef STEVE_DEBUG + printf("consinit() done.\n"); +#endif + /* while using openfirmware, run userconfig */ + if (boothowto & RB_CONFIG) { +#ifdef BOOT_CONFIG + user_config(); +#else + printf("kernel does not support -c; continuing..\n"); +#endif + } + /* + * Replace with real console. + */ + cninit(); +#ifdef STEVE_DEBUG + printf("cninit() done.\n"); +#endif +#ifdef OWF + ofwconprobe(); +#endif + +#if NIPKDB > 0 + /* + * Now trap to IPKDB + */ + ipkdb_init(); + if (boothowto & RB_KDB) + ipkdb_connect(0); +#else +#ifdef DDB + kdb_init(); + if (boothowto & RB_KDB) + Debugger(); +#endif +#endif + + /* + * Figure out ethernet address. + */ +#if 0 + (void)power4e_get_eth_addr(); +#endif +#ifdef STEVE_DEBUG + printf("return to locore.\n"); +#endif +} + +void +install_extint(handler) + void (*handler) __P((void)); +{ + extern extint, extsize; + extern u_long extint_call; + u_long offset = (u_long)handler - (u_long)&extint_call; + int omsr, msr; + +#ifdef DIAGNOSTIC + if (offset > 0x1ffffff) + panic("install_extint: too far away"); +#endif + __asm__ volatile ("mfmsr %0; andi. %1, %0, %2; mtmsr %1" + : "=r"(omsr), "=r"(msr) : "K"((u_short)~PSL_EE)); + extint_call = (extint_call & 0xfc000003) | offset; + bcopy(&extint, (void *)EXC_EXI, (size_t)&extsize); + syncicache((void *)&extint_call, sizeof extint_call); + syncicache((void *)EXC_EXI, (int)&extsize); + __asm__ volatile ("mtmsr %0" :: "r"(omsr)); +} + +/* + * Machine dependent startup code. + */ +void +cpu_startup() +{ + int sz, i; + caddr_t v; + vm_offset_t minaddr, maxaddr; + int base, residual; + v = (caddr_t)proc0paddr + USPACE; + + proc0.p_addr = proc0paddr; + + printf("%s", version); + + printf("real mem = %d\n", ctob(physmem)); + + /* + * Find out how much space we need, allocate it, + * and then give everything true virtual addresses. + */ + sz = (int)allocsys((caddr_t)0); +#ifdef UVM + if ((v = (caddr_t)uvm_km_zalloc(kernel_map, round_page(sz))) == 0) + panic("startup: no room for tables"); +#else + if ((v = (caddr_t)kmem_alloc(kernel_map, round_page(sz))) == 0) + panic("startup: no room for tables"); +#endif + if (allocsys(v) - v != sz) + panic("startup: table size inconsistency"); + + /* + * Now allocate buffers proper. They are different than the above + * in that they usually occupy more virtual memory than physical. + */ + sz = MAXBSIZE * nbuf; +#ifdef UVM + if (uvm_map(kernel_map, (vaddr_t *) &buffers, round_page(sz), + NULL, UVM_UNKNOWN_OFFSET, + UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE, + UVM_ADV_NORMAL, 0)) != KERN_SUCCESS) + panic("cpu_startup: cannot allocate VM for buffers"); + /* + addr = (vaddr_t)buffers; + */ +#else + buffer_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, sz, TRUE); + buffers = (char *)minaddr; + if (vm_map_find(buffer_map, vm_object_allocate(sz), (vm_offset_t)0, + &minaddr, sz, FALSE) != KERN_SUCCESS) + panic("startup: cannot allocate buffers"); +#endif + base = bufpages / nbuf; + residual = bufpages % nbuf; + if (base >= MAXBSIZE) { + /* Don't want to alloc more physical mem than ever needed */ + base = MAXBSIZE; + residual = 0; + } + for (i = 0; i < nbuf; i++) { + vm_size_t curbufsize; + vm_offset_t curbuf; + struct vm_page *pg; + + curbuf = (vm_offset_t)buffers + i * MAXBSIZE; + curbufsize = PAGE_SIZE * (i < residual ? base + 1 : base); +#ifdef UVM + while (curbufsize) { + pg = uvm_pagealloc(NULL, 0, NULL, 0); + if (pg == NULL) + panic("cpu_startup: not enough memory for" + " buffer cache"); + pmap_kenter_pa(curbuf, VM_PAGE_TO_PHYS(pg), + VM_PROT_READ|VM_PROT_WRITE); + curbuf += PAGE_SIZE; + curbufsize -= PAGE_SIZE; + } +#else + vm_map_pageable(buffer_map, curbuf, curbuf + curbufsize, + FALSE); + vm_map_simplify(buffer_map, curbuf); +#endif + } + + /* + * Allocate a submap for exec arguments. This map effectively + * limits the number of processes exec'ing at any time. + */ +#ifdef UVM + exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 16 * NCARGS, + TRUE, FALSE, NULL); +#else + exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, 16 * NCARGS, + TRUE); +#endif + + /* + * Allocate a submap for physio + */ +#ifdef UVM + phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, + VM_PHYS_SIZE, TRUE, FALSE, NULL); +#else + phys_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, VM_PHYS_SIZE, + TRUE); +#endif + ppc_malloc_ok = 1; + + +#ifdef UVM + mb_map = uvm_km_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr, + VM_MBUF_SIZE, FALSE, FALSE, NULL); +#else + mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr, + VM_MBUF_SIZE, FALSE); +#endif + + /* + * Initialize timeouts. + */ + timeout_init(); + +#ifdef UVM + printf("avail mem = %d\n", ptoa(uvmexp.free)); +#else + printf("avail mem = %d\n", ptoa(cnt.v_free_count)); +#endif + printf("using %d buffers containing %d bytes of memory\n", nbuf, + bufpages * PAGE_SIZE); + + + /* + * Set up the buffers. + */ + bufinit(); + + devio_malloc_safe = 1; +} + + +/* + * Allocate space for system data structures. + */ +caddr_t +allocsys(v) + caddr_t v; +{ +#define valloc(name, type, num) \ + v = (caddr_t)(((name) = (type *)v) + (num)) + + valloc(timeouts, struct timeout, ntimeout); +#ifdef SYSVSHM + valloc(shmsegs, struct shmid_ds, shminfo.shmmni); +#endif +#ifdef SYSVSEM + valloc(sema, struct semid_ds, seminfo.semmni); + valloc(sem, struct sem, seminfo.semmns); + valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int)); +#endif +#ifdef SYSVMSG + valloc(msgpool, char, msginfo.msgmax); + valloc(msgmaps, struct msgmap, msginfo.msgseg); + valloc(msghdrs, struct msg, msginfo.msgtql); + valloc(msqids, struct msqid_ds, msginfo.msgmni); +#endif + +#ifndef BUFCACHEPERCENT +#define BUFCACHEPERCENT 5 +#endif + /* + * Decide on buffer space to use. + */ + if (bufpages == 0) + bufpages = physmem * BUFCACHEPERCENT / 100; + if (nbuf == 0) { + nbuf = bufpages; + if (nbuf < 16) + nbuf = 16; + } + /* Restrict to at most 70% filled kvm */ + if (nbuf * MAXBSIZE > + (VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) * 7 / 10) + nbuf = (VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) / + MAXBSIZE * 7 / 10; + + /* More buffer pages than fits into the buffers is senseless. */ + if (bufpages > nbuf * MAXBSIZE / PAGE_SIZE) + bufpages = nbuf * MAXBSIZE / PAGE_SIZE; + + if (nswbuf == 0) { + nswbuf = (nbuf / 2) & ~1; + if (nswbuf > 256) + nswbuf = 256; + } +#if !defined(UVM) + valloc(swbuf, struct buf, nswbuf); +#endif + valloc(buf, struct buf, nbuf); + + return v; +} + +/* + * consinit + * Initialize system console. + */ +void +consinit() +{ + static int cons_initted = 0; + + if (cons_initted) + return; + cn_tab = NULL; + cninit(); + cons_initted = 1; +} + +/* + * Clear registers on exec + */ +void +setregs(p, pack, stack, retval) + struct proc *p; + struct exec_package *pack; + u_long stack; + register_t *retval; +{ + u_int32_t newstack; + u_int32_t pargs; + u_int32_t args[4]; + + struct trapframe *tf = trapframe(p); + pargs = -roundup(-stack + 8, 16); + newstack = (u_int32_t)(pargs - 32); + + copyin ((void*)(VM_MAX_ADDRESS-0x10), &args, 0x10); + + bzero(tf, sizeof *tf); + tf->fixreg[1] = newstack; + tf->fixreg[3] = retval[0] = args[1]; /* XXX */ + tf->fixreg[4] = retval[1] = args[0]; /* XXX */ + tf->fixreg[5] = args[2]; /* XXX */ + tf->fixreg[6] = args[3]; /* XXX */ + tf->srr0 = pack->ep_entry; + tf->srr1 = PSL_MBO | PSL_USERSET | PSL_FE_DFLT; + p->p_addr->u_pcb.pcb_flags = 0; +} + +/* + * Send a signal to process. + */ +void +sendsig(catcher, sig, mask, code, type, val) + sig_t catcher; + int sig, mask; + u_long code; + int type; + union sigval val; +{ + struct proc *p = curproc; + struct trapframe *tf; + struct sigframe *fp, frame; + struct sigacts *psp = p->p_sigacts; + int oldonstack; + int pa; + + frame.sf_signum = sig; + + tf = trapframe(p); + oldonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK; + + /* + * Allocate stack space for signal handler. + */ + if ((psp->ps_flags & SAS_ALTSTACK) + && !oldonstack + && (psp->ps_sigonstack & sigmask(sig))) { + fp = (struct sigframe *)(psp->ps_sigstk.ss_sp + + psp->ps_sigstk.ss_size); + psp->ps_sigstk.ss_flags |= SS_ONSTACK; + } else + fp = (struct sigframe *)tf->fixreg[1]; + fp = (struct sigframe *)((int)(fp - 1) & ~0xf); + + /* + * Generate signal context for SYS_sigreturn. + */ + frame.sf_sc.sc_onstack = oldonstack; + frame.sf_sc.sc_mask = mask; + frame.sf_sip = NULL; + bcopy(tf, &frame.sf_sc.sc_frame, sizeof *tf); + if (psp->ps_siginfo & sigmask(sig)) { + frame.sf_sip = &fp->sf_si; + initsiginfo(&frame.sf_si, sig, code, type, val); + } + if (copyout(&frame, fp, sizeof frame) != 0) + sigexit(p, SIGILL); + + + tf->fixreg[1] = (int)fp; + tf->lr = (int)catcher; + tf->fixreg[3] = (int)sig; + tf->fixreg[4] = (psp->ps_siginfo & sigmask(sig)) ? (int)&fp->sf_si : NULL; + tf->fixreg[5] = (int)&fp->sf_sc; + tf->srr0 = (int)(((char *)PS_STRINGS) + - (p->p_emul->e_esigcode - p->p_emul->e_sigcode)); + +#if WHEN_WE_ONLY_FLUSH_DATA_WHEN_DOING_PMAP_ENTER + pmap_extract(vm_map_pmap(&p->p_vmspace->vm_map),tf->srr0, &pa); + syncicache(pa, (p->p_emul->e_esigcode - p->p_emul->e_sigcode)); +#endif +} + +/* + * System call to cleanup state after a signal handler returns. + */ +int +sys_sigreturn(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct sys_sigreturn_args /* { + syscallarg(struct sigcontext *) sigcntxp; + } */ *uap = v; + struct sigcontext sc; + struct trapframe *tf; + int error; + + if (error = copyin(SCARG(uap, sigcntxp), &sc, sizeof sc)) + return error; + tf = trapframe(p); + if ((sc.sc_frame.srr1 & PSL_USERSTATIC) != (tf->srr1 & PSL_USERSTATIC)) + return EINVAL; + bcopy(&sc.sc_frame, tf, sizeof *tf); + if (sc.sc_onstack & 1) + p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK; + else + p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK; + p->p_sigmask = sc.sc_mask & ~sigcantmask; + return EJUSTRETURN; +} + +/* + * Machine dependent system variables. + * None for now. + */ +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; +{ + /* all sysctl names at this level are terminal */ + if (namelen != 1) + return ENOTDIR; + switch (name[0]) { + default: + return EOPNOTSUPP; + } +} + +void +dumpsys() +{ + printf("dumpsys: TBD\n"); +} + +volatile int cpl, ipending, astpending, tickspending; +int imask[7]; + +/* + * Soft networking interrupts. + */ +void +softnet(isr) + int isr; +{ +#ifdef INET +#include "ether.h" +#if NETHER > 0 + if (isr & (1 << NETISR_ARP)) + arpintr(); +#endif + if (isr & (1 << NETISR_IP)) + ipintr(); +#endif +#ifdef INET6 + if (isr & (1 << NETISR_IPV6)) + ip6intr(); +#endif +#ifdef NETATALK + if (isr & (1 << NETISR_ATALK)) + atintr(); +#endif +#ifdef IMP + if (isr & (1 << NETISR_IMP)) + impintr(); +#endif +#ifdef NS + if (isr & (1 << NETISR_NS)) + nsintr(); +#endif +#ifdef ISO + if (isr & (1 << NETISR_ISO)) + clnlintr(); +#endif +#ifdef CCITT + if (isr & (1 << NETISR_CCITT)) + ccittintr(); +#endif +#include "ppp.h" +#if NPPP > 0 + if (isr & (1 << NETISR_PPP)) + pppintr(); +#endif +#include "bridge.h" +#if NBRIDGE > 0 + if (isr & (1 << NETISR_BRIDGE)) + bridgeintr(); +#endif +} + +void +lcsplx(ipl) + int ipl; +{ + splx(ipl); +} + +/* + * Halt or reboot the machine after syncing/dumping according to howto. + */ +void +boot(howto) + int howto; +#if 0 + char *what; +#endif +{ + static int syncing; + static char str[256]; + char *ap = str, *ap1 = ap; + + boothowto = howto; + if (!cold && !(howto & RB_NOSYNC) && !syncing) { + syncing = 1; + vfs_shutdown(); /* sync */ +#if 0 + /* resettodr does not currently do anything, address + * this later + */ + /* + * 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"); + } +#endif + } + splhigh(); + if (howto & RB_HALT) { + doshutdownhooks(); + printf("halted\n\n"); + ppc_exit(); + /* + (fw->exit)(); + */ + } + if (!cold && (howto & RB_DUMP)) + dumpsys(); + doshutdownhooks(); + printf("rebooting\n\n"); + ppc_boot(str); + /* + (fw->boot)(); + */ + while(1) /* forever */; +} + +/* + * Get Ethernet address for the onboard ethernet chip. + */ +void +myetheraddr(cp) + u_char *cp; +{ + struct mvmeprom_brdid brdid; + + mvmeprom_brdid(&brdid); + bcopy(&brdid.etheraddr, cp, 6); +} + +typedef void (void_f) (void); +void_f *pending_int_f = NULL; + +/* call the bus/interrupt controller specific pending interrupt handler + * would be nice if the offlevel interrupt code was handled here + * instead of being in each of the specific handler code + */ +void +do_pending_int() +{ + if (pending_int_f != NULL) { + (*pending_int_f)(); + } +} + +/* + * set system type from string + */ +void +systype(char *name) +{ + /* this table may be order specific if substrings match several + * computers but a longer string matches a specific + */ + int i; + struct systyp { + char *name; + char *systypename; + int type; + } systypes[] = { + { "MOT", "(PWRSTK) MCG powerstack family", PWRSTK }, + { "V-I Power", "(POWER4e) V-I ppc vme boards ", POWER4e}, + { "iMac", "(APPL) Apple iMac ", APPL}, + { "PowerMac", "(APPL) Apple PowerMac ", APPL}, + { "PowerBook", "(APPL) Apple Powerbook ", APPL}, + { NULL,"",0} + }; + for (i = 0; systypes[i].name != NULL; i++) { + if (strncmp( name , systypes[i].name, + strlen (systypes[i].name)) == 0) + { + system_type = systypes[i].type; + printf("recognized system type of %s as %s\n", + name, systypes[i].systypename); + break; + } + } + if (system_type == OFWMACH) { + printf("System type %snot recognized, good luck\n", + name); + } +} +/* + * one attempt at interrupt stuff.. + * + */ +#include <dev/pci/pcivar.h> +typedef void *(intr_establish_t) __P((void *, pci_intr_handle_t, + int, int, int (*func)(void *), void *, char *)); +typedef void (intr_disestablish_t) __P((void *, void *)); + +int ppc_configed_intr_cnt = 0; +struct intrhand ppc_configed_intr[MAX_PRECONF_INTR]; + +void * +ppc_intr_establish(lcv, ih, type, level, func, arg, name) + void *lcv; + pci_intr_handle_t ih; + int type; + int level; + int (*func) __P((void *)); + void *arg; + char *name; +{ + if (ppc_configed_intr_cnt < MAX_PRECONF_INTR) { + ppc_configed_intr[ppc_configed_intr_cnt].ih_fun = func; + ppc_configed_intr[ppc_configed_intr_cnt].ih_arg = arg; + ppc_configed_intr[ppc_configed_intr_cnt].ih_level = level; + ppc_configed_intr[ppc_configed_intr_cnt].ih_irq = ih; + ppc_configed_intr[ppc_configed_intr_cnt].ih_what = name; + ppc_configed_intr_cnt++; + } else { + panic("ppc_intr_establish called before interrupt controller" + " configured: driver %s too many interrupts\n", name); + } + /* disestablish is going to be tricky to supported for these :-) */ + return (void *)ppc_configed_intr_cnt; +} + +intr_establish_t *intr_establish_func = ppc_intr_establish;; +intr_disestablish_t *intr_disestablish_func; + +void +ppc_intr_setup(intr_establish_t *establish, intr_disestablish_t *disestablish) +{ + intr_establish_func = establish; + intr_disestablish_func = disestablish; +} + +/* + * General functions to enable and disable interrupts + * without having inlined assembly code in many functions, + * should be moved into a header file for inlining the function + * so it is faster + */ +void +ppc_intr_enable(int enable) +{ + u_int32_t emsr, dmsr; + if (enable != 0) { + __asm__ volatile("mfmsr %0" : "=r"(emsr)); + dmsr = emsr | PSL_EE; + __asm__ volatile("mtmsr %0" :: "r"(dmsr)); + } +} + +int +ppc_intr_disable(void) +{ + u_int32_t emsr, dmsr; + __asm__ volatile("mfmsr %0" : "=r"(emsr)); + dmsr = emsr & ~PSL_EE; + __asm__ volatile("mtmsr %0" :: "r"(dmsr)); + return (emsr & PSL_EE); +} + +u_int32_t +ppc_get_msr(void) +{ + u_int32_t msr; + __asm__ volatile("mfmsr %0" : "=r"(msr)); + return(msr); +} + +u_int32_t +ppc_set_msr(msr) + u_int32_t msr; +{ + __asm__ volatile("mtmsr %0" :: "r"(msr)); + __asm__ volatile("mfmsr %0" : "=r"(msr)); + return(msr); +} + +#if 0 +/* BUS functions */ +int +bus_space_map(t, bpa, size, cacheable, bshp) + bus_space_tag_t t; + bus_addr_t bpa; + bus_size_t size; + int cacheable; + bus_space_handle_t *bshp; +{ + int error; + + if (POWERPC_BUS_TAG_BASE(t) == 0) { + /* if bus has base of 0 fail. */ + return 1; + } + bpa |= POWERPC_BUS_TAG_BASE(t); + if ((error = extent_alloc_region(devio_ex, bpa, size, EX_NOWAIT | + (ppc_malloc_ok ? EX_MALLOCOK : 0)))) + { + return error; + } + if ((bpa >= 0x80000000) && ((bpa+size) < 0x90000000)) { + if (segment8_mapped) { + *bshp = bpa; + return 0; + } + } + if (error = bus_mem_add_mapping(bpa, size, cacheable, bshp)) { + if (extent_free(devio_ex, bpa, size, EX_NOWAIT | + (ppc_malloc_ok ? EX_MALLOCOK : 0))) + { + printf("bus_space_map: pa 0x%x, size 0x%x\n", + bpa, size); + printf("bus_space_map: can't free region\n"); + } + } + return 0; +} +bus_addr_t bus_space_unmap_p __P((bus_space_tag_t t, bus_space_handle_t bsh, + bus_size_t size)); +void bus_space_unmap __P((bus_space_tag_t t, bus_space_handle_t bsh, + bus_size_t size)); +bus_addr_t +bus_space_unmap_p(t, bsh, size) + bus_space_tag_t t; + bus_space_handle_t bsh; + bus_size_t size; +{ + bus_addr_t paddr; + + pmap_extract(pmap_kernel(), bsh, &paddr); + bus_space_unmap((t), (bsh), (size)); + return paddr ; +} +void +bus_space_unmap(t, bsh, size) + bus_space_tag_t t; + bus_space_handle_t bsh; + bus_size_t size; +{ + bus_addr_t sva; + bus_size_t off, len; + bus_addr_t bpa; + + /* should this verify that the proper size is freed? */ + sva = trunc_page(bsh); + off = bsh - sva; + len = size+off; + +#ifdef UVM + uvm_km_free_wakeup(phys_map, sva, len); +#else + kmem_free_wakeup(phys_map, sva, len); +#endif +#if 0 + pmap_extract(pmap_kernel(), sva, &bpa); + if (extent_free(devio_ex, bpa, size, EX_NOWAIT | + (ppc_malloc_ok ? EX_MALLOCOK : 0))) + { + printf("bus_space_map: pa 0x%x, size 0x%x\n", + bpa, size); + printf("bus_space_map: can't free region\n"); + } +#endif + pmap_remove(vm_map_pmap(phys_map), sva, sva+len); +} + +int +bus_mem_add_mapping(bpa, size, cacheable, bshp) + bus_addr_t bpa; + bus_size_t size; + int cacheable; + bus_space_handle_t *bshp; +{ + bus_addr_t vaddr; + bus_addr_t spa, epa; + bus_size_t off; + int len; + + spa = trunc_page(bpa); + epa = bpa + size; + off = bpa - spa; + len = size+off; + +#if 0 + if (epa <= spa) { + panic("bus_mem_add_mapping: overflow"); + } +#endif + if (ppc_malloc_ok == 0) { + bus_size_t alloc_size; + + /* need to steal vm space before kernel vm is initialized */ + alloc_size = trunc_page(size + NBPG); + ppc_kvm_size -= alloc_size; + + vaddr = VM_MIN_KERNEL_ADDRESS + ppc_kvm_size; + } else { +#ifdef UVM + vaddr = uvm_km_valloc_wait(phys_map, len); +#else + vaddr = kmem_alloc_wait(phys_map, len); +#endif + } + *bshp = vaddr + off; +#ifdef DEBUG_BUS_MEM_ADD_MAPPING + printf("mapping %x size %x to %x vbase %x\n", + bpa, size, *bshp, spa); +#endif + for (; len > 0; len -= NBPG) { +#if 0 + pmap_enter(vm_map_pmap(phys_map), vaddr, spa, +#else + pmap_enter(pmap_kernel(), vaddr, spa, +#endif + VM_PROT_READ | VM_PROT_WRITE, TRUE, 0/* XXX */); + spa += NBPG; + vaddr += NBPG; + } + return 0; +} + +#endif /* 0 */ + +void * +mapiodev(pa, len) + paddr_t pa; + psize_t len; +{ + paddr_t spa; + vaddr_t vaddr, va; + int off; + int size; + + spa = trunc_page(pa); + off = pa - spa; + size = round_page(off+len); + if ((pa >= 0x80000000) && ((pa+len) < 0x90000000)) { + if (segment8_mapped) { + return (void *)pa; + } + } +#ifdef UVM + va = vaddr = uvm_km_valloc(phys_map, size); +#else + va = vaddr = kmem_alloc(phys_map, size); +#endif + + if (va == 0) + return NULL; + + for (; size > 0; size -= NBPG) { +#if 0 + pmap_enter(vm_map_pmap(phys_map), vaddr, spa, +#else + pmap_enter(pmap_kernel(), vaddr, spa, +#endif + VM_PROT_READ | VM_PROT_WRITE, TRUE, 0/* XXX */); + spa += NBPG; + vaddr += NBPG; + } + return (void*) (va+off); +} +void +unmapiodev(kva, p_size) + void *kva; + psize_t p_size; +{ + vaddr_t vaddr; + int size; + + size = p_size; + + vaddr = trunc_page((vaddr_t)kva); + +#ifdef UVM + uvm_km_free_wakeup(phys_map, vaddr, size); +#else + kmem_free_wakeup(phys_map, vaddr, size); +#endif + + for (; size > 0; size -= NBPG) { +#if 0 + pmap_remove(vm_map_pmap(phys_map), vaddr, vaddr+NBPG-1); +#else + pmap_remove(pmap_kernel(), vaddr, vaddr+NBPG-1); +#endif + vaddr += NBPG; + } + return; +} + +#if 0 + +/* + * probably should be ppc_space_copy + */ + +#define _CONCAT(A,B) A ## B +#define __C(A,B) _CONCAT(A,B) + +#define BUS_SPACE_COPY_N(BYTES,TYPE) \ +void \ +__C(bus_space_copy_,BYTES)(v, h1, o1, h2, o2, c) \ + void *v; \ + bus_space_handle_t h1, h2; \ + bus_size_t o1, o2, c; \ +{ \ + TYPE val; \ + TYPE *src, *dst; \ + int i; \ + \ + src = (TYPE *) (h1+o1); \ + dst = (TYPE *) (h2+o2); \ + \ + if (h1 == h2 && o2 > o1) { \ + for (i = c; i > 0; i--) { \ + dst[i] = src[i]; \ + } \ + } else { \ + for (i = 0; i < c; i++) { \ + dst[i] = src[i]; \ + } \ + } \ +} +BUS_SPACE_COPY_N(1,u_int8_t) +BUS_SPACE_COPY_N(2,u_int16_t) +BUS_SPACE_COPY_N(4,u_int32_t) + +#define BUS_SPACE_SET_REGION_N(BYTES,TYPE) \ +void \ +__C(bus_space_set_region_,BYTES)(v, h, o, val, c) \ + void *v; \ + bus_space_handle_t h; \ + TYPE val; \ + bus_size_t c; \ +{ \ + TYPE *dst; \ + int i; \ + \ + dst = (TYPE *) (h+o); \ + for (i = 0; i < c; i++) { \ + dst[i] = val; \ + } \ +} + +BUS_SPACE_SET_REGION_N(1,u_int8_t) +BUS_SPACE_SET_REGION_N(2,u_int16_t) +BUS_SPACE_SET_REGION_N(4,u_int32_t) + +#define BUS_SPACE_READ_RAW_MULTI_N(BYTES,SHIFT,TYPE) \ +void \ +__C(bus_space_read_raw_multi_,BYTES)(bst, h, o, dst, size) \ + bus_space_tag_t bst; \ + bus_space_handle_t h; \ + bus_addr_t o; \ + u_int8_t *dst; \ + bus_size_t size; \ +{ \ + TYPE *src; \ + TYPE *rdst = (TYPE *)dst; \ + int i; \ + int count = size >> SHIFT; \ + \ + src = (TYPE *)(h+o); \ + for (i = 0; i < count; i++) { \ + rdst[i] = *src; \ + __asm__("eieio"); \ + } \ +} +BUS_SPACE_READ_RAW_MULTI_N(1,0,u_int8_t) +BUS_SPACE_READ_RAW_MULTI_N(2,1,u_int16_t) +BUS_SPACE_READ_RAW_MULTI_N(4,2,u_int32_t) + +#define BUS_SPACE_WRITE_RAW_MULTI_N(BYTES,SHIFT,TYPE) \ +void \ +__C(bus_space_write_raw_multi_,BYTES)(bst, h, o, src, size) \ + bus_space_tag_t bst; \ + bus_space_handle_t h; \ + bus_addr_t o; \ + const u_int8_t *src; \ + bus_size_t size; \ +{ \ + int i; \ + TYPE *dst; \ + TYPE *rsrc = (TYPE *)src; \ + int count = size >> SHIFT; \ + \ + dst = (TYPE *)(h+o); \ + for (i = 0; i < count; i++) { \ + *dst = rsrc[i]; \ + __asm__("eieio"); \ + } \ +} + +BUS_SPACE_WRITE_RAW_MULTI_N(1,0,u_int8_t) +BUS_SPACE_WRITE_RAW_MULTI_N(2,1,u_int16_t) +BUS_SPACE_WRITE_RAW_MULTI_N(4,2,u_int32_t) + +int +bus_space_subregion(t, bsh, offset, size, nbshp) + bus_space_tag_t t; + bus_space_handle_t bsh; + bus_size_t offset, size; + bus_space_handle_t *nbshp; +{ + *nbshp = bsh + offset; + return (0); +} + +#endif /* 0 */ + +/* bcopy(), error on fault */ +int +kcopy(from, to, size) + const void *from; + void *to; + size_t size; +{ + faultbuf env; + register void *oldh = curproc->p_addr->u_pcb.pcb_onfault; + + if (setfault(env)) { + curpcb->pcb_onfault = 0; + return EFAULT; + } + bcopy(from, to, size); + curproc->p_addr->u_pcb.pcb_onfault = oldh; + + return 0; +} +void +nameinterrupt(replace, newstr) + int replace; + char *newstr; +{ +#define NENTRIES 66 + char intrname[NENTRIES][30]; + char *p, *src; + int i; + extern char intrnames[]; + extern char eintrnames[]; + + if (replace > NENTRIES) { + return; + } + src = intrnames; + + for (i = 0; i < NENTRIES; i++) { + src += strlcpy(intrname[i], src, 30); + src+=1; /* skip the NUL */ + } + + strcat(intrname[replace], "/"); + strcat(intrname[replace], newstr); + + p = intrnames; + for (i = 0; i < NENTRIES; i++) { + p += strlcpy(p, intrname[i], eintrnames - p); + p += 1; /* skip the NUL */ + } +} diff --git a/sys/arch/mvmeppc/mvmeppc/pmap.c b/sys/arch/mvmeppc/mvmeppc/pmap.c new file mode 100644 index 00000000000..ef298c8d6bd --- /dev/null +++ b/sys/arch/mvmeppc/mvmeppc/pmap.c @@ -0,0 +1,1709 @@ +/* $OpenBSD: pmap.c,v 1.1 2001/06/26 21:57:54 smurph Exp $ */ +/* $NetBSD: pmap.c,v 1.1 1996/09/30 16:34:52 ws Exp $ */ + +/* + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/param.h> +#include <sys/malloc.h> +#include <sys/proc.h> +#include <sys/user.h> +#include <sys/queue.h> +#include <sys/systm.h> +#include <sys/pool.h> + +#include <vm/vm.h> +#include <vm/vm_kern.h> + +#ifdef UVM +#include <uvm/uvm.h> +#endif + +#include <machine/pcb.h> +#include <machine/powerpc.h> + +pte_t *ptable; +int ptab_cnt; +u_int ptab_mask; +#define HTABSIZE (ptab_cnt * 64) + +struct pte_ovfl { + LIST_ENTRY(pte_ovfl) po_list; /* Linked list of overflow entries */ + struct pte po_pte; /* PTE for this mapping */ +}; + +LIST_HEAD(pte_ovtab, pte_ovfl) *potable; /* Overflow entries for ptable */ + +struct pmap kernel_pmap_; + +int physmem; +static int npgs; +static u_int nextavail; + +static struct mem_region *mem, *avail; + +#ifndef UVM + extern vm_offset_t pager_sva, pager_eva; +#endif + +#if 0 +void +dump_avail() +{ + int cnt; + struct mem_region *mp; + extern struct mem_region *avail; + + printf("memory %x\n", mem); + for (cnt = 0, mp = mem; mp->size; mp++) { + printf("memory region %x: start 0x%08x, size 0x%08x\n", + cnt, mp->start, mp->size); + cnt++; + } + printf("available %x\n", avail); + for (cnt = 0, mp = avail; mp->size; mp++) { + printf("avail region %x: start 0x%08x, size 0x%08x\n", + cnt, mp->start, mp->size); + cnt++; + } +} +#endif + + +/* virtual to physical map */ +static inline int +VP_SR(va) + paddr_t va; +{ + return (va >> VP_SR_POS) & VP_SR_MASK; +} +static inline int +VP_IDX1(va) + paddr_t va; +{ + return (va >> VP_IDX1_POS) & VP_IDX1_MASK; +} + +static inline int +VP_IDX2(va) + paddr_t va; +{ + return (va >> VP_IDX2_POS) & VP_SR_MASK; +} + +int +pmap_vp_valid(pm, va) + pmap_t pm; + vaddr_t va; +{ + pmapv_t *vp1; + vp1 = pm->vps[VP_SR(va)]; + if (vp1 != NULL) { + return (vp1[VP_IDX1(va)] & (1 << VP_IDX2(va))); + } + return 0; +} +int +pmap_vp_remove(pm, va) + pmap_t pm; + vaddr_t va; +{ + pmapv_t *vp1; + int s; + int retcode; + retcode = 0; + vp1 = pm->vps[VP_SR(va)]; +#ifdef DEBUG + printf("pmap_vp_remove: removing va %x pm %x", va, pm); +#endif + if (vp1 != NULL) { + s = splhigh(); + retcode = vp1[VP_IDX1(va)] & (1 << VP_IDX2(va)); + vp1[VP_IDX1(va)] &= ~(1 << VP_IDX2(va)); + splx(s); + } +#ifdef DEBUG + printf(" ret %x\n", retcode); +#endif + return retcode; +} +void +pmap_vp_enter(pm, va, pa) + pmap_t pm; + vaddr_t va; + paddr_t pa; +{ + pmapv_t *vp1; + pmapv_t *mem1; + int s; + int idx; + idx = VP_SR(va); + vp1 = pm->vps[idx]; +#ifdef DEBUG + printf("pmap_vp_enter: pm %x va %x vp1 %x idx %x ", pm, va, vp1, idx); +#endif + if (vp1 == NULL) { +#ifdef DEBUG + printf("l1 entry idx %x ", idx); +#endif + if (pm == pmap_kernel()) { + printf(" irk kernel allocating map?\n"); + } else { +#ifdef UVM + if (!(mem1 = (pmapv_t *)uvm_km_zalloc(kernel_map, NBPG))) + panic("pmap_vp_enter: uvm_km_zalloc() failed"); +#else + if (!(mem1 = (pmapv_t *)kmem_alloc(kernel_map, NBPG))) + panic("pmap_vp_enter: kmem_alloc() failed"); +#endif + } + pm->vps[idx] = mem1; +#ifdef DEBUG + printf("got %x ", mem1); +#endif + vp1 = mem1; + } +#ifdef DEBUG + printf("l2 idx %x\n", VP_IDX2(va)); +#endif + + s = splhigh(); + vp1[VP_IDX1(va)] |= (1 << VP_IDX2(va)); + splx(s); + return; +} + +void +pmap_vp_destroy(pm) + pmap_t pm; +{ + pmapv_t *vp1; + int sr, idx1; + + for (sr = 0; sr < 32; sr++) { + vp1 = pm->vps[sr]; + if (vp1 == NULL) { + continue; + } +#ifdef SANITY + for(idx1 = 0; idx1 < 1024; idx1++) { + if (vp1[idx1] != 0) { + printf("mapped page at %x \n" + 0); /* XXX what page was this... */ + vp1[idx2] = 0; + + } + } +#endif +#ifdef UVM + uvm_km_free(kernel_map, (vaddr_t)vp1, NBPG); +#else + kmem_free(kernel_map, (vm_offset_t)vp1, NBPG); +#endif + pm->vps[sr] = 0; + } +} +static int vp_page0[1024]; +static int vp_page1[1024]; +void +pmap_vp_preinit() +{ + pmap_t pm = pmap_kernel(); + /* magic addresses are 0xe0000000, 0xe8000000 */ + pm->vps[VP_SR(0xe0000000)] = vp_page0; + pm->vps[VP_SR(0xe8000000)] = vp_page1; +} + + +/* + * This is a cache of referenced/modified bits. + * Bits herein are shifted by ATTRSHFT. + */ +static char *pmap_attrib; +#define ATTRSHFT 4 + +struct pv_entry { + struct pv_entry *pv_next; /* Linked list of mappings */ + int pv_idx; /* Index into ptable */ + vm_offset_t pv_va; /* virtual address of mapping */ + struct pmap *pv_pmap; /* pmap associated with this map */ +}; + +struct pv_entry *pv_table; + +struct pool pmap_pv_pool; +static struct pv_entry *pmap_alloc_pv __P((void)); +static void pmap_free_pv __P((struct pv_entry *)); + +struct pool pmap_po_pool; +static struct pte_ovfl *poalloc __P((void)); +static void pofree __P((struct pte_ovfl *, int)); + +static u_int usedsr[NPMAPS / sizeof(u_int) / 8]; + +static int pmap_initialized; + +/* + * These small routines may have to be replaced, + * if/when we support processors other that the 604. + */ +static inline void +tlbie(ea) + caddr_t ea; +{ + asm volatile ("tlbie %0" :: "r"(ea)); +} + +static inline void +tlbsync() +{ + asm volatile ("sync; tlbsync; sync"); +} + +static void +tlbia() +{ + caddr_t i; + + asm volatile ("sync"); + for (i = 0; i < (caddr_t)0x00040000; i += 0x00001000) + tlbie(i); + tlbsync(); +} + +static inline int +ptesr(sr, addr) + sr_t *sr; + vm_offset_t addr; +{ + return sr[(u_int)addr >> ADDR_SR_SHFT]; +} + +static inline int +pteidx(sr, addr) + sr_t sr; + vm_offset_t addr; +{ + int hash; + + hash = (sr & SR_VSID) ^ (((u_int)addr & ADDR_PIDX) >> ADDR_PIDX_SHFT); + return hash & ptab_mask; +} + +static inline int +ptematch(ptp, sr, va, which) + pte_t *ptp; + sr_t sr; + vm_offset_t va; + int which; +{ + return ptp->pte_hi + == (((sr & SR_VSID) << PTE_VSID_SHFT) + | (((u_int)va >> ADDR_API_SHFT) & PTE_API) + | which); +} + +/* + * Try to insert page table entry *pt into the ptable at idx. + * + * Note: *pt mustn't have PTE_VALID set. + * This is done here as required by Book III, 4.12. + */ +static int +pte_insert(idx, pt) + int idx; + pte_t *pt; +{ + pte_t *ptp; + int i; + + /* + * First try primary hash. + */ + for (ptp = ptable + idx * 8, i = 8; --i >= 0; ptp++) + if (!(ptp->pte_hi & PTE_VALID)) { + *ptp = *pt; + ptp->pte_hi &= ~PTE_HID; + asm volatile ("sync"); + ptp->pte_hi |= PTE_VALID; + return 1; + } + idx ^= ptab_mask; + for (ptp = ptable + idx * 8, i = 8; --i >= 0; ptp++) + if (!(ptp->pte_hi & PTE_VALID)) { + *ptp = *pt; + ptp->pte_hi |= PTE_HID; + asm volatile ("sync"); + ptp->pte_hi |= PTE_VALID; + return 1; + } + return 0; +} + +/* + * Spill handler. + * + * Tries to spill a page table entry from the overflow area. + * Note that this routine runs in real mode on a separate stack, + * with interrupts disabled. + */ +int +pte_spill(addr) + vm_offset_t addr; +{ + int idx, i; + sr_t sr; + struct pte_ovfl *po; + pte_t ps; + pte_t *pt; + + asm ("mfsrin %0,%1" : "=r"(sr) : "r"(addr)); + idx = pteidx(sr, addr); + for (po = potable[idx].lh_first; po; po = po->po_list.le_next) + if (ptematch(&po->po_pte, sr, addr, 0)) { + /* + * Now found an entry to be spilled into the real ptable. + */ + if (pte_insert(idx, &po->po_pte)) { + LIST_REMOVE(po, po_list); + pofree(po, 0); + return 1; + } + /* + * Have to substitute some entry. Use the primary hash for this. + * + * Use low bits of timebase as random generator + */ + asm ("mftb %0" : "=r"(i)); + pt = ptable + idx * 8 + (i & 7); + pt->pte_hi &= ~PTE_VALID; + ps = *pt; + asm volatile ("sync"); + tlbie(addr); + tlbsync(); + *pt = po->po_pte; + asm volatile ("sync"); + pt->pte_hi |= PTE_VALID; + po->po_pte = ps; + if (ps.pte_hi & PTE_HID) { + /* + * We took an entry that was on the alternate hash + * chain, so move it to it's original chain. + */ + po->po_pte.pte_hi &= ~PTE_HID; + LIST_REMOVE(po, po_list); + LIST_INSERT_HEAD(potable + (idx ^ ptab_mask), + po, po_list); + } + return 1; + } + return 0; +} + +int avail_start; +int avail_end; +/* + * This is called during initppc, before the system is really initialized. + */ +void +pmap_bootstrap(kernelstart, kernelend) + u_int kernelstart, kernelend; +{ + struct mem_region *mp, *mp1; + int cnt, i; + u_int s, sz; + u_int addr; + + avail_start = kernelend; + /* + * Get memory. + */ + (fw->mem_regions)(&mem, &avail); + physmem = 0; + for (mp = mem; mp->size; mp++) { + physmem += btoc(mp->size); + } + + /* + * Count the number of available entries. + */ + for (cnt = 0, mp = avail; mp->size; mp++) + cnt++; + + /* + * Page align all regions. + * Non-page memory isn't very interesting to us. + * Also, sort the entries for ascending addresses. + */ + kernelstart &= ~PGOFSET; + kernelend = (kernelend + PGOFSET) & ~PGOFSET; + + /* make certain that each section is page aligned for base and size */ + for (mp = avail; mp->size; mp++) { + u_int32_t end; + s = mp->start - round_page(mp->start); + if (s != 0) { + mp->start = round_page(mp->start); + end = trunc_page(mp->size + mp->start); + mp->size = end - mp->start; + } + mp->size = trunc_page(mp->size); + } + for (mp = avail; mp->size; mp++) { + /* + * Check whether this region holds all of the kernel. + */ + s = mp->start + mp->size; + if (mp->start < kernelstart && s > kernelend) { + mp->start = kernelend; + mp->size = kernelstart - mp->start; + } + /* + * Look whether this regions starts within the kernel. + */ + if (mp->start >= kernelstart && mp->start < kernelend) { + s = kernelend - mp->start; + if (mp->size > s) + mp->size -= s; + else + mp->size = 0; + mp->start = kernelend; + } + /* + * Now look whether this region ends within the kernel. + */ + s = mp->start + mp->size; + if (s > kernelstart && s < kernelend) + mp->size -= s - kernelstart; + /* + * Now page align the start of the region. + */ + s = mp->start % NBPG; + if (mp->size >= s) { + mp->size -= s; + mp->start += s; + } + /* + * And now align the size of the region. + */ + mp->size -= mp->size % NBPG; + /* + * Check whether some memory is left here. + */ + if (mp->size == 0) { + bcopy(mp + 1, mp, + (cnt - (mp - avail)) * sizeof *mp); + cnt--; + mp--; + continue; + } + s = mp->start; + sz = mp->size; + npgs += btoc(sz); + for (mp1 = avail; mp1 < mp; mp1++) + if (s < mp1->start) + break; + if (mp1 < mp) { + bcopy(mp1, mp1 + 1, (void *)mp - (void *)mp1); + mp1->start = s; + mp1->size = sz; + } + } +#if 0 +avail_start = 0; +avail_end = npgs * NBPG; +#endif + +#ifdef HTABENTS + ptab_cnt = HTABENTS; +#else /* HTABENTS */ + ptab_cnt = 1024; + while ((HTABSIZE << 7) < ctob(physmem)) { + ptab_cnt <<= 1; + } +#endif /* HTABENTS */ + + /* + * Find suitably aligned memory for HTAB. + */ + for (mp = avail; mp->size; mp++) { + if (mp->start % HTABSIZE == 0) { + s = 0; + } else { + s = HTABSIZE - (mp->start % HTABSIZE) ; + } + if (mp->size < s + HTABSIZE) + continue; + ptable = (pte_t *)(mp->start + s); + if (mp->size == s + HTABSIZE) { + if (s) + mp->size = s; + else { + bcopy(mp + 1, mp, + (cnt - (mp - avail)) * sizeof *mp); + mp = avail; + } + break; + } +#if 0 + if (s != 0) { + printf("resizing avail\n"); + bcopy(mp, mp + 1, + (cnt - (mp - avail)) * sizeof *mp); + mp++->size = s; + } +#endif + mp->start += s + HTABSIZE; + mp->size -= s + HTABSIZE; + break; + } + if (!mp->size) + panic("not enough memory?"); + bzero((void *)ptable, HTABSIZE); + ptab_mask = ptab_cnt - 1; + + /* + * We cannot do vm_bootstrap_steal_memory here, + * since we don't run with translation enabled yet. + */ + s = sizeof(struct pte_ovtab) * ptab_cnt; + sz = round_page(s); + for (mp = avail; mp->size; mp++) + if (mp->size >= sz) + break; + if (!mp->size) + panic("not enough memory?"); + potable = (struct pte_ovtab *)mp->start; + mp->size -= sz; + mp->start += sz; + if (mp->size == 0) + bcopy(mp + 1, mp, (cnt - (mp - avail)) * sizeof *mp); + for (i = 0; i < ptab_cnt; i++) + LIST_INIT(potable + i); + + /* use only one memory list */ + { + u_int32_t size; + struct mem_region *curmp; + size = 0; + curmp = NULL; + for (mp = avail; mp->size; mp++) { + if (mp->size > size) { + size = mp->size; + curmp=mp; + } + } + mp = avail; + if (curmp == mp) { + ++mp; + mp->size = 0; /* lose the rest of memory */ + } else { + *mp = *curmp; + ++mp; + mp->size = 0; /* lose the rest of memory */ + } + } + +#ifdef MACHINE_NEW_NONCONTIG + for (mp = avail; mp->size; mp++) { +#ifdef UVM + uvm_page_physload(atop(mp->start), atop(mp->start + mp->size), + atop(mp->start), atop(mp->start + mp->size), + VM_FREELIST_DEFAULT); +#else + vm_page_physload(atop(mp->start), atop(mp->start + mp->size), + atop(mp->start), atop(mp->start + mp->size)); +#endif + } +#endif + + /* + * Initialize kernel pmap and hardware. + */ +#if NPMAPS >= KERNEL_SEGMENT / 16 + usedsr[KERNEL_SEGMENT / 16 / (sizeof usedsr[0] * 8)] + |= 1 << ((KERNEL_SEGMENT / 16) % (sizeof usedsr[0] * 8)); +#endif + for (i = 0; i < 16; i++) { + pmap_kernel()->pm_sr[i] = EMPTY_SEGMENT; + asm volatile ("mtsrin %0,%1" + :: "r"(EMPTY_SEGMENT), "r"(i << ADDR_SR_SHFT) ); + } + pmap_kernel()->pm_sr[KERNEL_SR] = KERNEL_SEGMENT; + asm volatile ("mtsr %0,%1" + :: "n"(KERNEL_SR), "r"(KERNEL_SEGMENT)); + asm volatile ("sync; mtsdr1 %0; isync" + :: "r"((u_int)ptable | (ptab_mask >> 10))); + tlbia(); + pmap_vp_preinit(); + nextavail = avail->start; +} + +/* + * Restrict given range to physical memory + */ +void +pmap_real_memory(start, size) + vm_offset_t *start; + vm_size_t *size; +{ + struct mem_region *mp; + + for (mp = mem; mp->size; mp++) { + if (*start + *size > mp->start + && *start < mp->start + mp->size) { + if (*start < mp->start) { + *size -= mp->start - *start; + *start = mp->start; + } + if (*start + *size > mp->start + mp->size) + *size = mp->start + mp->size - *start; + return; + } + } + *size = 0; +} + +/* + * Initialize anything else for pmap handling. + * Called during vm_init(). + */ +void +pmap_init() +{ + struct pv_entry *pv; + vsize_t sz; + vaddr_t addr; + int i, s; +#ifdef MACHINE_NEW_NONCONTIG + int bank; + char *attr; +#endif + + sz = (vm_size_t)((sizeof(struct pv_entry) + 1) * npgs); + sz = round_page(sz); +#ifdef UVM + addr = uvm_km_zalloc(kernel_map, sz); +#else + addr = kmem_alloc(kernel_map, sz); +#endif + s = splimp(); + pv = pv_table = (struct pv_entry *)addr; + for (i = npgs; --i >= 0;) + pv++->pv_idx = -1; + pool_init(&pmap_pv_pool, sizeof(struct pv_entry), 0, 0, 0, "pvpl", + 0, NULL, NULL, M_VMPMAP); + pool_init(&pmap_po_pool, sizeof(struct pte_ovfl), 0, 0, 0, "popl", + 0, NULL, NULL, M_VMPMAP); + pmap_attrib = (char *)pv; + bzero(pv, npgs); +#ifdef MACHINE_NEW_NONCONTIG + pv = pv_table; + attr = pmap_attrib; + for (bank = 0; bank < vm_nphysseg; bank++) { + sz = vm_physmem[bank].end - vm_physmem[bank].start; + vm_physmem[bank].pmseg.pvent = pv; + vm_physmem[bank].pmseg.attrs = attr; + pv += sz; + attr += sz; + } +#endif + pmap_initialized = 1; + splx(s); +} + +/* + * Return the index of the given page in terms of pmap_next_page() calls. + */ +int +pmap_page_index(pa) + vm_offset_t pa; +{ + struct mem_region *mp; + vm_size_t pre; + + pa &= ~PGOFSET; + for (pre = 0, mp = avail; mp->size; mp++) { + if (pa >= mp->start + && pa < mp->start + mp->size) + return btoc(pre + (pa - mp->start)); + pre += mp->size; + } + return -1; +} +#ifdef MACHINE_NEW_NONCONTIG +static __inline struct pv_entry * +pmap_find_pv(paddr_t pa) +{ + int bank, off; + + bank = vm_physseg_find(atop(pa), &off); + if (bank != -1) { + return &vm_physmem[bank].pmseg.pvent[off]; + } + return NULL; +} +static __inline char * +pmap_find_attr(paddr_t pa) +{ + int bank, off; + + bank = vm_physseg_find(atop(pa), &off); + if (bank != -1) { + return &vm_physmem[bank].pmseg.attrs[off]; + } + return NULL; +} +#endif + +vm_offset_t ppc_kvm_size = VM_KERN_ADDR_SIZE_DEF; + +/* + * How much virtual space is available to the kernel? + */ +void +pmap_virtual_space(start, end) + vm_offset_t *start, *end; +{ + /* + * Reserve one segment for kernel virtual memory + */ + *start = (vm_offset_t)(KERNEL_SR << ADDR_SR_SHFT); + *end = *start + VM_KERN_ADDRESS_SIZE; +} + +/* + * Return the number of possible page indices returned + * from pmap_page_index for any page provided by pmap_next_page. + */ +u_int +pmap_free_pages() +{ + return npgs; +} + +/* + * If there are still physical pages available, put the address of + * the next available one at paddr and return TRUE. Otherwise, + * return FALSE to indicate that there are no more free pages. + */ +int +pmap_next_page(paddr) + vm_offset_t *paddr; +{ + static int lastidx = -1; + + if (lastidx == -1) { + nextavail = avail->start; + } + if (lastidx < 0 + || nextavail >= avail[lastidx].start + avail[lastidx].size) { + if (avail[++lastidx].size == 0) + return FALSE; + nextavail = avail[lastidx].start; + } + *paddr = nextavail; + nextavail += NBPG; + return TRUE; +} + +/* + * Create and return a physical map. + */ +#if defined(PMAP_NEW) +struct pmap * +pmap_create() +#else +struct pmap * +pmap_create(size) + vsize_t size; +#endif +{ + struct pmap *pm; + + pm = (struct pmap *)malloc(sizeof *pm, M_VMPMAP, M_WAITOK); + bzero((caddr_t)pm, sizeof *pm); + pmap_pinit(pm); + return pm; +} + +/* + * Initialize a preallocated and zeroed pmap structure. + */ +void +pmap_pinit(pm) + struct pmap *pm; +{ + int i, j, k; + int s, seg; + + /* + * Allocate some segment registers for this pmap. + */ + s = splimp(); + pm->pm_refs = 1; + for (i = 0; i < sizeof usedsr / sizeof usedsr[0]; i++) + if (usedsr[i] != 0xffffffff) { + j = ffs(~usedsr[i]) - 1; + usedsr[i] |= 1 << j; + seg = (i * sizeof usedsr[0] * 8 + j) * 16; + for (k = 0; k < 16; k++) + pm->pm_sr[k] = seg + k; + splx(s); + return; + } + splx(s); + panic("out of segments"); +} + +/* + * Add a reference to the given pmap. + */ +void +pmap_reference(pm) + struct pmap *pm; +{ + pm->pm_refs++; +} + +/* + * Retire the given pmap from service. + * Should only be called if the map contains no valid mappings. + */ +void +pmap_destroy(pm) + struct pmap *pm; +{ + if (--pm->pm_refs == 0) { + pmap_release(pm); + free((caddr_t)pm, M_VMPMAP); + } +} + +/* + * Release any resources held by the given physical map. + * Called when a pmap initialized by pmap_pinit is being released. + */ +void +pmap_release(pm) + struct pmap *pm; +{ + int i, j; + int s; + + pmap_vp_destroy(pm); + if (!pm->pm_sr[0]) + panic("pmap_release"); + i = pm->pm_sr[0] / 16; + j = i % (sizeof usedsr[0] * 8); + i /= sizeof usedsr[0] * 8; + s = splimp(); + usedsr[i] &= ~(1 << j); + splx(s); +} + +/* + * Copy the range specified by src_addr/len + * from the source map to the range dst_addr/len + * in the destination map. + * + * This routine is only advisory and need not do anything. + */ +void +pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr) + struct pmap *dst_pmap, *src_pmap; + vm_offset_t dst_addr, src_addr; + vm_size_t len; +{ +} + +/* + * Require that all active physical maps contain no + * incorrect entries NOW. + */ +void +pmap_update() +{ +} + +/* + * Garbage collects the physical map system for + * pages which are no longer used. + * Success need not be guaranteed -- that is, there + * may well be pages which are not referenced, but + * others may be collected. + * Called by the pageout daemon when pages are scarce. + */ +void +pmap_collect(pm) + struct pmap *pm; +{ +} + +/* + * Fill the given physical page with zeroes. + */ +void +pmap_zero_page(pa) + vm_offset_t pa; +{ +#if 0 + bzero((caddr_t)pa, NBPG); +#else + int i; + + for (i = NBPG/CACHELINESIZE; i > 0; i--) { + __asm __volatile ("dcbz 0,%0" :: "r"(pa)); + pa += CACHELINESIZE; + } +#endif +} + +/* + * Copy the given physical source page to its destination. + */ +void +pmap_copy_page(src, dst) + vm_offset_t src, dst; +{ + bcopy((caddr_t)src, (caddr_t)dst, NBPG); +} + +static struct pv_entry * +pmap_alloc_pv() +{ + struct pv_entry *pv; + int s; + + /* + * XXX - this splimp can go away once we have PMAP_NEW and + * a correct implementation of pmap_kenter. + */ + /* + * Note that it's completly ok to use a pool here because it will + * never map anything or call pmap_enter because we have + * PMAP_MAP_POOLPAGE. + */ + s = splimp(); + pv = pool_get(&pmap_pv_pool, PR_NOWAIT); + splx(s); + /* + * XXX - some day we might want to implement pv stealing, or + * to pass down flags from pmap_enter about allowed failure. + * Right now - just panic. + */ + if (pv == NULL) + panic("pmap_alloc_pv: failed to allocate pv"); + + return pv; +} + +static void +pmap_free_pv(pv) + struct pv_entry *pv; +{ + int s; + + /* XXX - see pmap_alloc_pv */ + s = splimp(); + pool_put(&pmap_pv_pool, pv); + splx(s); +} + +/* + * We really hope that we don't need overflow entries + * before the VM system is initialized! XXX + * XXX - see pmap_alloc_pv + */ +static struct pte_ovfl * +poalloc() +{ + struct pte_ovfl *po; + int s; + +#ifdef DIAGNOSTIC + if (!pmap_initialized) + panic("poalloc"); +#endif + s = splimp(); + po = pool_get(&pmap_po_pool, PR_NOWAIT); + splx(s); + if (po == NULL) + panic("poalloc: failed to alloc po"); + return po; +} + +static void +pofree(po, freepage) + struct pte_ovfl *po; + int freepage; +{ + int s; + s = splimp(); + pool_put(&pmap_po_pool, po); + splx(s); +} + +/* + * This returns whether this is the first mapping of a page. + */ +static inline int +pmap_enter_pv(pm, pteidx, va, pa) + struct pmap *pm; + int pteidx; + vm_offset_t va; + vm_offset_t pa; +{ + struct pv_entry *npv; + int s, first; + struct pv_entry *pv; + + if (!pmap_initialized) + return 0; + + pv = pmap_find_pv( pa ); + if (pv == NULL) + return 0; + + s = splimp(); + + if (first = pv->pv_idx == -1) { + /* + * No entries yet, use header as the first entry. + */ + pv->pv_va = va; + pv->pv_idx = pteidx; + pv->pv_pmap = pm; + pv->pv_next = NULL; + } else { + /* + * There is at least one other VA mapping this page. + * Place this entry after the header. + */ + npv = pmap_alloc_pv(); + npv->pv_va = va; + npv->pv_idx = pteidx; + npv->pv_pmap = pm; + npv->pv_next = pv->pv_next; + pv->pv_next = npv; + } + splx(s); + return first; +} + +static void +pmap_remove_pv(pm, pteidx, va, pte_lo) + struct pmap *pm; + int pteidx; + vm_offset_t va; + u_int32_t pte_lo; +{ + struct pv_entry *pv, *npv; + + int bank, pg; + vm_offset_t pa; + char *attr; + + pa = pte_lo & ~PGOFSET; + + bank = vm_physseg_find(atop(pa), &pg); + if (bank == -1) + return; + pv = &vm_physmem[bank].pmseg.pvent[pg]; + attr = &vm_physmem[bank].pmseg.attrs[pg]; + + /* + * First transfer reference/change bits to cache. + */ + *attr |= (pte_lo & (PTE_REF | PTE_CHG)) >> ATTRSHFT; + + /* + * Remove from the PV table. + * + * If it is the first entry on the list, it is actually + * in the header and we must copy the following entry up + * to the header. Otherwise we must search the list for + * the entry. In either case we free the now unused entry. + */ + if (va == pv->pv_va && pm == pv->pv_pmap) { + npv = pv->pv_next; + if (npv) { + *pv = *npv; + pmap_free_pv(npv); + } else { + pv->pv_pmap = 0; + pv->pv_idx = -1; + } + } else { + for (; npv = pv->pv_next; pv = npv) { + if (va == npv->pv_va && pm == npv->pv_pmap) + { + break; + } + } + if (npv) { + pv->pv_next = npv->pv_next; + pmap_free_pv(npv); + } +#if 1 +#ifdef DIAGNOSTIC + else { + printf("pmap_remove_pv: not on list\n"); + /* + panic("pmap_remove_pv: not on list"); + */ + } +#endif +#endif + } +} + +/* + * Insert physical page at pa into the given pmap at virtual address va. + */ +void +pmap_enter(pm, va, pa, prot, wired, access_type) + struct pmap *pm; + vm_offset_t va, pa; + vm_prot_t prot; + int wired; + vm_prot_t access_type; +{ + sr_t sr; + int idx, i, s; + pte_t pte; + struct pte_ovfl *po; + struct mem_region *mp; + + /* + * Have to remove any existing mapping first. + */ + pmap_remove(pm, va, va + NBPG-1); + + pm->pm_stats.resident_count++; + + pmap_vp_enter(pm, va, pa); + + /* + * Compute the HTAB index. + */ + sr = ptesr(pm->pm_sr, va); + idx = pteidx(sr, va); + /* + * Construct the PTE. + * + * Note: Don't set the valid bit for correct operation of tlb update. + */ + pte.pte_hi = ((sr & SR_VSID) << PTE_VSID_SHFT) + | ((va & ADDR_PIDX) >> ADDR_API_SHFT); + pte.pte_lo = (pa & PTE_RPGN) | PTE_M | PTE_I | PTE_G; + for (mp = mem; mp->size; mp++) { + if (pa >= mp->start && pa < mp->start + mp->size) { + pte.pte_lo &= ~(PTE_I | PTE_G); + break; + } + } + if (prot & VM_PROT_WRITE) + pte.pte_lo |= PTE_RW; + else + pte.pte_lo |= PTE_RO; + + /* + * Now record mapping for later back-translation. + */ + if (pmap_enter_pv(pm, idx, va, pa)) { + /* + * Flush the real memory from the cache. + */ + syncicache((void *)pa, NBPG); + } + + s = splimp(); + /* + * Try to insert directly into HTAB. + */ + if (pte_insert(idx, &pte)) { + splx(s); + return; + } + + /* + * Have to allocate overflow entry. + * + * Note, that we must use real addresses for these. + */ + po = poalloc(); + po->po_pte = pte; + LIST_INSERT_HEAD(potable + idx, po, po_list); + splx(s); +} + +void +pmap_kenter_pa(va, pa, prot) + vaddr_t va; + paddr_t pa; + vm_prot_t prot; +{ + pmap_enter(pmap_kernel(), va, pa, prot, 1, 0); +} + +void +pmap_kenter_pgs(va, pgs, npgs) + vaddr_t va; + struct vm_page **pgs; + int npgs; +{ + int i; + + for (i = 0; i < npgs; i++, va += PAGE_SIZE) { + pmap_enter(pmap_kernel(), va, VM_PAGE_TO_PHYS(pgs[i]), + VM_PROT_READ|VM_PROT_WRITE, 1, 0); + } +} + +void +pmap_kremove(va, len) + vaddr_t va; + vsize_t len; +{ + for (len >>= PAGE_SHIFT; len > 0; len--, va += PAGE_SIZE) { + pmap_remove(pmap_kernel(), va, va + PAGE_SIZE); + } +} + + +/* + * Remove the given range of mapping entries. + */ +void +pmap_remove(pm, va, endva) + struct pmap *pm; + vm_offset_t va, endva; +{ + int idx, i, s; + int found; /* if found, we are done, only one mapping per va */ + sr_t sr; + pte_t *ptp; + struct pte_ovfl *po, *npo; + struct pv_entry *pv; + + s = splimp(); + for (; va < endva; va += NBPG) { + if (0 == pmap_vp_remove(pm, va)) { + /* no mapping */ + continue; + } + found = 0; + sr = ptesr(pm->pm_sr, va); + idx = pteidx(sr, va); + for (ptp = ptable + idx * 8, i = 8; --i >= 0; ptp++) + if (ptematch(ptp, sr, va, PTE_VALID)) { + ptp->pte_hi &= ~PTE_VALID; + asm volatile ("sync"); + tlbie(va); + tlbsync(); + pmap_remove_pv(pm, idx, va, ptp->pte_lo); + pm->pm_stats.resident_count--; + found = 1; + break; + } + if (found) { + continue; + } + for (ptp = ptable + (idx ^ ptab_mask) * 8, i = 8; --i >= 0; ptp++) + if (ptematch(ptp, sr, va, PTE_VALID | PTE_HID)) { + ptp->pte_hi &= ~PTE_VALID; + asm volatile ("sync"); + tlbie(va); + tlbsync(); + pmap_remove_pv(pm, idx, va, ptp->pte_lo); + pm->pm_stats.resident_count--; + found = 1; + break; + } + if (found) { + continue; + } + for (po = potable[idx].lh_first; po; po = npo) { + npo = po->po_list.le_next; + if (ptematch(&po->po_pte, sr, va, 0)) { + pmap_remove_pv(pm, idx, va, po->po_pte.pte_lo); + LIST_REMOVE(po, po_list); + pofree(po, 1); + pm->pm_stats.resident_count--; + break; + } + } + } + splx(s); +} + +static pte_t * +pte_find(pm, va) + struct pmap *pm; + vm_offset_t va; +{ + int idx, i; + sr_t sr; + pte_t *ptp; + struct pte_ovfl *po; + + sr = ptesr(pm->pm_sr, va); + idx = pteidx(sr, va); + for (ptp = ptable + idx * 8, i = 8; --i >= 0; ptp++) + if (ptematch(ptp, sr, va, PTE_VALID)) + return ptp; + for (ptp = ptable + (idx ^ ptab_mask) * 8, i = 8; --i >= 0; ptp++) + if (ptematch(ptp, sr, va, PTE_VALID | PTE_HID)) + return ptp; + for (po = potable[idx].lh_first; po; po = po->po_list.le_next) + if (ptematch(&po->po_pte, sr, va, 0)) + return &po->po_pte; + return 0; +} + +/* + * Get the physical page address for the given pmap/virtual address. + */ +boolean_t +pmap_extract(pm, va, pap) + struct pmap *pm; + vaddr_t va; + paddr_t *pap; +{ + pte_t *ptp; + int s = splimp(); + + if (!(ptp = pte_find(pm, va))) { + splx(s); + return (FALSE); + } + *pap = (ptp->pte_lo & PTE_RPGN) | (va & ADDR_POFF); + splx(s); + return (TRUE); +} + +/* + * Lower the protection on the specified range of this pmap. + * + * There are only two cases: either the protection is going to 0, + * or it is going to read-only. + */ +void +pmap_protect(pm, sva, eva, prot) + struct pmap *pm; + vm_offset_t sva, eva; + vm_prot_t prot; +{ + pte_t *ptp; + int valid, s; + + if (prot & VM_PROT_READ) { + s = splimp(); + while (sva < eva) { + if (ptp = pte_find(pm, sva)) { + valid = ptp->pte_hi & PTE_VALID; + ptp->pte_hi &= ~PTE_VALID; + asm volatile ("sync"); + tlbie(sva); + tlbsync(); + ptp->pte_lo &= ~PTE_PP; + ptp->pte_lo |= PTE_RO; + asm volatile ("sync"); + ptp->pte_hi |= valid; + } + sva += NBPG; + } + splx(s); + return; + } + pmap_remove(pm, sva, eva); +} + +void +ptemodify(pa, mask, val) + vm_offset_t pa; + u_int mask; + u_int val; +{ + struct pv_entry *pv; + pte_t *ptp; + struct pte_ovfl *po; + int i, s; + char * pattr; + + pv = pmap_find_pv(pa); + if (pv == NULL) + return; + pattr = pmap_find_attr(pa); + + /* + * First modify bits in cache. + */ + *pattr &= ~mask >> ATTRSHFT; + *pattr |= val >> ATTRSHFT; + + if (pv->pv_idx < 0) + return; + + s = splimp(); + for (; pv; pv = pv->pv_next) { + for (ptp = ptable + pv->pv_idx * 8, i = 8; --i >= 0; ptp++) + if ((ptp->pte_hi & PTE_VALID) + && (ptp->pte_lo & PTE_RPGN) == pa) { + ptp->pte_hi &= ~PTE_VALID; + asm volatile ("sync"); + tlbie(pv->pv_va); + tlbsync(); + ptp->pte_lo &= ~mask; + ptp->pte_lo |= val; + asm volatile ("sync"); + ptp->pte_hi |= PTE_VALID; + } + for (ptp = ptable + (pv->pv_idx ^ ptab_mask) * 8, i = 8; --i >= 0; ptp++) + if ((ptp->pte_hi & PTE_VALID) + && (ptp->pte_lo & PTE_RPGN) == pa) { + ptp->pte_hi &= ~PTE_VALID; + asm volatile ("sync"); + tlbie(pv->pv_va); + tlbsync(); + ptp->pte_lo &= ~mask; + ptp->pte_lo |= val; + asm volatile ("sync"); + ptp->pte_hi |= PTE_VALID; + } + for (po = potable[pv->pv_idx].lh_first; po; po = po->po_list.le_next) + if ((po->po_pte.pte_lo & PTE_RPGN) == pa) { + po->po_pte.pte_lo &= ~mask; + po->po_pte.pte_lo |= val; + } + } + splx(s); +} + +int +ptebits(pa, bit) + vm_offset_t pa; + int bit; +{ + struct pv_entry *pv; + pte_t *ptp; + struct pte_ovfl *po; + int i, s, bits = 0; + char *pattr; + + pv = pmap_find_pv(pa); + if (pv == NULL) + return 0; + pattr = pmap_find_attr(pa); + + /* + * First try the cache. + */ + bits |= ((*pattr) << ATTRSHFT) & bit; + if (bits == bit) + return bits; + + pv = pv_table; + if (pv->pv_idx < 0) + return 0; + + s = splimp(); + for (; pv; pv = pv->pv_next) { + for (ptp = ptable + pv->pv_idx * 8, i = 8; --i >= 0; ptp++) + if ((ptp->pte_hi & PTE_VALID) + && (ptp->pte_lo & PTE_RPGN) == pa) { + bits |= ptp->pte_lo & bit; + if (bits == bit) { + splx(s); + return bits; + } + } + for (ptp = ptable + (pv->pv_idx ^ ptab_mask) * 8, i = 8; --i >= 0; ptp++) + if ((ptp->pte_hi & PTE_VALID) + && (ptp->pte_lo & PTE_RPGN) == pa) { + bits |= ptp->pte_lo & bit; + if (bits == bit) { + splx(s); + return bits; + } + } + for (po = potable[pv->pv_idx].lh_first; po; po = po->po_list.le_next) + if ((po->po_pte.pte_lo & PTE_RPGN) == pa) { + bits |= po->po_pte.pte_lo & bit; + if (bits == bit) { + splx(s); + return bits; + } + } + } + splx(s); + return bits; +} + +/* + * Lower the protection on the specified physical page. + * + * There are only two cases: either the protection is going to 0, + * or it is going to read-only. + */ +#if defined(PMAP_NEW) +void +pmap_page_protect(pg, prot) + struct vm_page *pg; + vm_prot_t prot; +#else +void +pmap_page_protect(pa, prot) + vm_offset_t pa; + vm_prot_t prot; +#endif +{ +#if defined(PMAP_NEW) + vm_offset_t pa = VM_PAGE_TO_PHYS(pg); +#endif + vm_offset_t va; + pte_t *ptp; + struct pte_ovfl *po, *npo; + int i, s, pind, idx; + struct pmap *pm; + struct pv_entry *pv; + + pa &= ~ADDR_POFF; + if (prot & VM_PROT_READ) { + ptemodify(pa, PTE_PP, PTE_RO); + return; + } + + pv = pmap_find_pv(pa); + if (pv == NULL) + return; + + s = splimp(); + while (pv->pv_idx != -1) { + va = pv->pv_va; + pm = pv->pv_pmap; +#ifdef UVM + if ((va >=uvm.pager_sva) && (va < uvm.pager_eva)) { + continue; + } +#else + if (va >= pager_sva && va < pager_eva) { + continue; + } +#endif + pmap_remove(pm, va, va + NBPG); + } + splx(s); +} +/* + * this code to manipulate the BAT tables was added here + * because it is closely related to the vm system. + * --dsr + */ + +#include <machine/bat.h> + +/* one major problem of mapping IO with bats, is that it + * is not possible to use caching on any level of granularity + * that is reasonable. + * This is just enhancing an existing design (that should be + * replaced in my opinion). + * + * Current design only allow mapping of 256 MB block. (normally 1-1) + * but not necessarily (in the case of PCI io at 0xf0000000 where + * it might be desireable to map it elsewhere because that is + * where the stack is?) + */ +void +addbatmap(u_int32_t vaddr, u_int32_t raddr, u_int32_t wimg) +{ + u_int32_t segment; + segment = vaddr >> (32 - 4); + battable[segment].batu = BATU(vaddr); + battable[segment].batl = BATL(raddr, wimg); +} + +/* ??? */ +void +pmap_activate(struct proc *p) +{ +#if 0 + struct pcb *pcb = &p->p_addr->u_pcb; + pmap_t pmap = p->p_vmspace->vm_map.pmap; + + /* + * XXX Normally performed in cpu_fork(); + */ + if (pcb->pcb_pm != pmap) { + pcb->pcb_pm = pmap; + (void) pmap_extract(pmap_kernel(), (vaddr_t)pcb->pcb_pm, + (paddr_t *)&pcb->pcb_pmreal); + } + curpcb=pcb; + if (p == curproc) { + /* Disable interrupts while switching. */ + __asm __volatile("mfmsr %0" : "=r"(psl) :); + psl &= ~PSL_EE; + __asm __volatile("mtmsr %0" :: "r"(psl)); + + /* Store pointer to new current pmap. */ + curpm = pcb->pcb_pmreal; + + /* Save kernel SR. */ + __asm __volatile("mfsr %0,14" : "=r"(ksr) :); + + /* + * Set new segment registers. We use the pmap's real + * address to avoid accessibility problems. + */ + rpm = pcb->pcb_pmreal; + for (i = 0; i < 16; i++) { + seg = rpm->pm_sr[i]; + __asm __volatile("mtsrin %0,%1" + :: "r"(seg), "r"(i << ADDR_SR_SHFT)); + } + + /* Restore kernel SR. */ + __asm __volatile("mtsr 14,%0" :: "r"(ksr)); + + /* Interrupts are OK again. */ + psl |= PSL_EE; + __asm __volatile("mtmsr %0" :: "r"(psl)); + } +#endif + return; +} +/* ??? */ +void +pmap_deactivate(struct proc *p) +{ + return; +} diff --git a/sys/arch/mvmeppc/mvmeppc/ppc1_machdep.c b/sys/arch/mvmeppc/mvmeppc/ppc1_machdep.c new file mode 100644 index 00000000000..14cc5cf4090 --- /dev/null +++ b/sys/arch/mvmeppc/mvmeppc/ppc1_machdep.c @@ -0,0 +1,364 @@ +/* $OpenBSD: ppc1_machdep.c,v 1.1 2001/06/26 21:57:54 smurph Exp $ */ +/* $NetBSD: ofw_machdep.c,v 1.1 1996/09/30 16:34:50 ws Exp $ */ + +/* + * Copyright (C) 1996 Wolfgang Solfrank. + * Copyright (C) 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/param.h> +#include <sys/buf.h> +#include <sys/conf.h> +#include <sys/device.h> +#include <sys/disk.h> +#include <sys/disklabel.h> +#include <sys/fcntl.h> +#include <sys/ioctl.h> +#include <sys/malloc.h> +#include <sys/stat.h> +#include <sys/systm.h> + +#include <vm/vm.h> +#include <vm/vm_kern.h> + +#include <machine/powerpc.h> +#include <machine/autoconf.h> +#include <machine/prom.h> +#include <mvmeppc/dev/nvramreg.h> + +#include <dev/cons.h> + +void PPC1_exit __P((void)) __attribute__((__noreturn__)); +void PPC1_boot __P((char *bootspec)) __attribute__((__noreturn__)); +void PPC1_mem_regions __P((struct mem_region **memp, struct mem_region **availp)); +void PPC1_vmon __P((void)); +unsigned char PPC1_nvram_rd __P((unsigned long offset)); +void PPC1_nvram_wr __P((unsigned long offset, unsigned char val)); +unsigned long PPC1_tps __P((void)); + +int PPC1_clock_read __P((int *sec, int *min, int *hour, int *day, + int *mon, int *yr)); +int PPC1_clock_write __P((int sec, int min, int hour, int day, + int mon, int yr)); + +struct firmware ppc1_firmware = { + PPC1_mem_regions, + PPC1_exit, + PPC1_boot, + PPC1_vmon, + PPC1_nvram_rd, + PPC1_nvram_wr, + PPC1_tps, + PPC1_clock_read, + PPC1_clock_write, + NULL, + NULL, +#ifdef FW_HAS_PUTC + mvmeprom_outchar; +#endif +}; + +#define PPC1_REGIONS 32 +static struct mem_region PPC1mem[PPC1_REGIONS + 1], PPC1avail[PPC1_REGIONS + 3]; + +/* + * 1 - Figure and find the end of local memory. This is now a Bug call. + * This requires that the correct amount of local memory be entered + * in the Bug environment. (see: Bug ENV command.) + * 2 - Start looking from the megabyte after the end of the kernel data, + * until we find non-memory to figure the total memory available. + * 3 - Initialize from the end of local memory to the end of total + * memory. (As required by some VME memory boards) - smurph + */ +#define MAXPHYSMEM 0x10000000 /* max physical memory */ + +vm_offset_t +size_memory(void) +{ + volatile unsigned int *look; + unsigned int *max; + extern char *end; + vm_offset_t local_mem, total_mem; +#ifdef USE_BUG + bugenvrd(); /* read the bug environment */ + local_mem = (vm_offset_t)bug_localmemsize(); +#endif +#define PATTERN 0x5a5a5a5a +#define STRIDE (4*1024) /* 4k at a time */ +#define Roundup(value, stride) (((unsigned)(value) + (stride) - 1) & ~((stride)-1)) + /* + * count it up. + */ + max = (void*)MAXPHYSMEM; + for (look = (void*)Roundup(end, STRIDE); look < max; + look = (int*)((unsigned)look + STRIDE)) { + unsigned save; + + /* if can't access, we've reached the end */ + if (badaddr((char *)look, 4)) { +#if defined(DEBUG) + printf("%x\n", look); +#endif + look = (int *)((int)look - STRIDE); + break; + } + + /* + * If we write a value, we expect to read the same value back. + * We'll do this twice, the 2nd time with the opposite bit + * pattern from the first, to make sure we check all bits. + */ + save = *look; + if (*look = PATTERN, *look != PATTERN) + break; + if (*look = ~PATTERN, *look != ~PATTERN) + break; + *look = save; + } + look = (unsigned int *)0x02000000; + physmem = btoc(trunc_page((unsigned)look)); /* in pages */ + total_mem = trunc_page((unsigned)look); +#ifdef USE_BUG + /* Initialize the off-board (non-local) memory. */ + printf("Initializing %d bytes of off-board memory.\n", total_mem - local_mem); + bzero((void *)local_mem, total_mem - local_mem); +#endif + return (total_mem); +} + +/* + * This is called during initppc, before the system is really initialized. + * It shall provide the total and the available regions of RAM. + * Both lists must have a zero-size entry as terminator. + * The available regions need not take the kernel into account, but needs + * to provide space for two additional entry beyond the terminating one. + */ +void +PPC1_mem_regions(memp, availp) +struct mem_region **memp, **availp; +{ + int phandle, i, j, cnt; + extern int avail_start; + + bzero(&PPC1mem[0], sizeof(struct mem_region) * PPC1_REGIONS); + bzero(&PPC1avail[0], sizeof(struct mem_region) * PPC1_REGIONS); + /* + * Get memory. + */ + PPC1mem[0].start = 0; + PPC1mem[0].size = size_memory(); + + PPC1avail[0].start = avail_start; + PPC1avail[0].size = (PPC1mem[0].size - avail_start); + + *memp = PPC1mem; + *availp = PPC1avail; +} + +void +PPC1_vmon() +{ +} + +void +PPC1_exit() +{ + mvmeprom_return(); + panic ("PPC1_exit returned!"); /* just in case */ + while (1); +} +void +PPC1_boot(bootspec) +char *bootspec; +{ + u_int32_t msr, i = 10000; + + /* set exception prefix high - to the prom */ + msr = ppc_get_msr(); + msr |= PSL_IP; + ppc_set_msr(msr); + + /* make sure bit 0 (reset) is a 0 */ + outb(0x80000092, inb(0x80000092) & ~1L); + /* signal a reset to system control port A - soft reset */ + outb(0x80000092, inb(0x92) | 1); + + while ( i != 0 ) i++; + panic("restart failed\n"); + mvmeprom_return(); + printf ("PPC1_boot returned!"); /* just in case */ + while (1); +} + +unsigned char PPC1_nvram_rd(addr) +unsigned long addr; +{ + outb(NVRAM_S0, addr); + outb(NVRAM_S1, addr>>8); + return inb(NVRAM_DATA); +} + +void PPC1_nvram_wr(addr, val) +unsigned long addr; +unsigned char val; +{ + outb(NVRAM_S0, addr); + outb(NVRAM_S1, addr>>8); + outb(NVRAM_DATA, val); +} + +/* Function to get ticks per second. */ + +unsigned long PPC1_tps(void) +{ + unsigned long start_val, ticks; + unsigned char val, sec; + + /* Start RTC */ + val = PPC1_nvram_rd(RTC_CONTROLB); + PPC1_nvram_wr(RTC_CONTROLA, (val & (~RTC_CB_STOP))); + val = PPC1_nvram_rd(RTC_CONTROLA); + PPC1_nvram_wr(RTC_CONTROLA, (val & (~RTC_CA_READ))); + + /* look at seconds. */ + sec = PPC1_nvram_rd(RTC_SECONDS); + while (1) { + if (PPC1_nvram_rd(RTC_SECONDS) != sec) + break; + } + + start_val = ppc_get_spr(SPR_DEC); + + /* wait until it changes. */ + sec = PPC1_nvram_rd(RTC_SECONDS); + while (1) { + if (PPC1_nvram_rd(RTC_SECONDS) != sec) + break; + } + ticks = start_val - ppc_get_spr(SPR_DEC); + return (ticks); +} + +int PPC1_clock_write(int sec, int min, int hour, int day, + int mon, int yr) +{ + unsigned char val; + + /* write command */ + val = PPC1_nvram_rd(RTC_CONTROLA); + PPC1_nvram_wr(RTC_CONTROLA, (val | RTC_CA_WRITE)); + + PPC1_nvram_wr(RTC_SECONDS, sec); + PPC1_nvram_wr(RTC_MINUTES, min); + PPC1_nvram_wr(RTC_HOURS, hour); + PPC1_nvram_wr(RTC_MONTH, mon); + PPC1_nvram_wr(RTC_DAY_OF_MONTH, day); + PPC1_nvram_wr(RTC_YEAR, yr); + + /* cancel write */ + PPC1_nvram_wr(RTC_CONTROLA, val); + + return 0; +} + +int PPC1_clock_read(int *sec, int *min, int *hour, int *day, + int *mon, int *yr) +{ + unsigned char val; + int i; + + /* Is there time? */ + val = PPC1_nvram_rd(RTC_CONTROLB); + PPC1_nvram_wr(RTC_CONTROLA, (val & (~RTC_CB_STOP))); + val = PPC1_nvram_rd(RTC_CONTROLA); + val &= ~RTC_CA_READ; + PPC1_nvram_wr(RTC_CONTROLA, val); + + /* Read the seconds value. */ + *sec = PPC1_nvram_rd(RTC_SECONDS); + + /* Wait for a new second. */ + for (i = 0 ; i < 1000000 ; i++) { + if (PPC1_nvram_rd(RTC_SECONDS) != *sec) { + break; + } + } + + /* stop time. */ + PPC1_nvram_wr(RTC_CONTROLA, (val | RTC_CA_READ)); + + *sec = PPC1_nvram_rd(RTC_SECONDS); + *min = PPC1_nvram_rd(RTC_MINUTES); + *hour = PPC1_nvram_rd(RTC_HOURS); + *day = PPC1_nvram_rd(RTC_DAY_OF_MONTH); + *mon = PPC1_nvram_rd(RTC_MONTH); + *yr = PPC1_nvram_rd(RTC_YEAR); + + /* restart time. */ + PPC1_nvram_wr(RTC_CONTROLA, val); + return 0; +} + +/* + * Boot console routines: + * Enables printing of boot messages before consinit(). + */ +int +bootcnprobe(cp) +struct consdev *cp; +{ + cp->cn_dev = makedev(14, 0); + cp->cn_pri = CN_NORMAL; + return (1); +} + +int +bootcninit(cp) +struct consdev *cp; +{ + /* Nothing to do */ + return (1); +} + +int +bootcngetc(dev) +dev_t dev; +{ + return (mvmeprom_getchar()); +} + +void +bootcnputc(dev, c) +dev_t dev; +char c; +{ + if (c == '\n') + mvmeprom_outchar('\r'); + mvmeprom_outchar(c); +} + diff --git a/sys/arch/mvmeppc/mvmeppc/process_machdep.c b/sys/arch/mvmeppc/mvmeppc/process_machdep.c new file mode 100644 index 00000000000..8cf911b8236 --- /dev/null +++ b/sys/arch/mvmeppc/mvmeppc/process_machdep.c @@ -0,0 +1,107 @@ +/* $OpenBSD: process_machdep.c,v 1.1 2001/06/26 21:57:55 smurph Exp $ */ +/* $NetBSD: process_machdep.c,v 1.1 1996/09/30 16:34:53 ws Exp $ */ + +/* + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/param.h> +#include <sys/proc.h> +#include <machine/reg.h> + +/* + * Set the process's program counter. + */ +int +process_set_pc(p, addr) + struct proc *p; + caddr_t addr; +{ + struct trapframe *tf = trapframe(p); + + tf->srr0 = (int)addr; + return 0; +} + +int +process_sstep(p, sstep) + struct proc *p; + int sstep; +{ + struct trapframe *tf = trapframe(p); + + if (sstep) + tf->srr1 |= PSL_SE; + else + tf->srr1 &= ~PSL_SE; + return 0; +} +int +process_read_regs(p, regs) + struct proc *p; + struct reg *regs; +{ + struct trapframe *tf = trapframe(p); + + bcopy(&(tf->fixreg[0]), &(regs->gpr[0]), sizeof(regs->gpr)); + bzero(&(regs->fpr[0]), sizeof(regs->fpr)); + /* + * need to do floating point here + */ + regs->pc = tf->srr0; + regs->ps = tf->srr1; /* is this the correct value for this ? */ + regs->cnd = tf->cr; + regs->lr = tf->lr; + regs->cnt = tf->ctr; + regs->xer = tf->xer; + regs->mq = 0; /* what should this really be? */ + + return (0); +} +int +process_write_regs(p, regs) + struct proc *p; + struct reg *regs; +{ + struct trapframe *tf = trapframe(p); + + bcopy(&(regs->gpr[0]), &(tf->fixreg[0]), sizeof(regs->gpr)); + /* + * need to do floating point here + */ + tf->srr0 = regs->pc; + tf->srr1 = regs->ps; /* is this the correct value for this ? */ + tf->cr = regs->cnd; + tf->lr = regs->lr; + tf->ctr = regs->cnt; + tf->xer = regs->xer; + /* regs->mq = 0; what should this really be? */ + + return (0); +} diff --git a/sys/arch/mvmeppc/mvmeppc/swapgeneric.c b/sys/arch/mvmeppc/mvmeppc/swapgeneric.c new file mode 100644 index 00000000000..b418837bdff --- /dev/null +++ b/sys/arch/mvmeppc/mvmeppc/swapgeneric.c @@ -0,0 +1,56 @@ +/* $OpenBSD: swapgeneric.c,v 1.1 2001/06/26 21:57:55 smurph Exp $ */ +/* $NetBSD: swapgeneric.c,v 1.1 1996/09/30 16:34:55 ws Exp $ */ + +/*- + * Copyright (c) 1994 + * 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. 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, Berkeley and its contributors. + * 4. 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. + * + * @(#)swapgeneric.c 8.2 (Berkeley) 3/21/94 + */ + +/* + * fake swapgeneric.c -- should do this differently. + */ + +#include <sys/param.h> +#include <sys/conf.h> + +int (*mountroot) __P((void *)) = NULL; /* tells autoconf.c that we are "generic" */ + +dev_t rootdev = NODEV; +dev_t dumpdev = NODEV; + +struct swdevt swdevt[] = { + { NODEV, 0, 0 }, /* Setup by autoconf.c/disksubr.c */ + { NODEV, 0, 0 }, + { NODEV, 0, 0 }, + { NODEV, 0, 0 }, +}; diff --git a/sys/arch/mvmeppc/mvmeppc/sys_machdep.c b/sys/arch/mvmeppc/mvmeppc/sys_machdep.c new file mode 100644 index 00000000000..3afbcf27fb5 --- /dev/null +++ b/sys/arch/mvmeppc/mvmeppc/sys_machdep.c @@ -0,0 +1,47 @@ +/* $OpenBSD: sys_machdep.c,v 1.1 2001/06/26 21:57:55 smurph Exp $ */ +/* $NetBSD: sys_machdep.c,v 1.1 1996/09/30 16:34:56 ws Exp $ */ + +/* + * Copyright (C) 1996 Wolfgang Solfrank. + * Copyright (C) 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/param.h> + +int +sys_sysarch(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + /* + * Currently no special system calls + */ + return EINVAL; +} diff --git a/sys/arch/mvmeppc/mvmeppc/trap.c b/sys/arch/mvmeppc/mvmeppc/trap.c new file mode 100644 index 00000000000..be257184e65 --- /dev/null +++ b/sys/arch/mvmeppc/mvmeppc/trap.c @@ -0,0 +1,652 @@ +/* $OpenBSD: trap.c,v 1.1 2001/06/26 21:57:55 smurph Exp $ */ +/* $NetBSD: trap.c,v 1.3 1996/10/13 03:31:37 christos Exp $ */ + +/* + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/signalvar.h> +#include <sys/reboot.h> +#include <sys/syscall.h> +#include <sys/systm.h> +#include <sys/user.h> +#include <sys/ktrace.h> + +#include <vm/vm.h> +#include <vm/vm_kern.h> + +#ifdef UVM +#include <uvm/uvm_extern.h> +#endif + +#include <machine/cpu.h> +#include <machine/frame.h> +#include <machine/pcb.h> +#include <machine/pmap.h> +#include <machine/psl.h> +#include <machine/trap.h> +#include <machine/db_machdep.h> + +static int fix_unaligned __P((struct proc *p, struct trapframe *frame)); + +/* These definitions should probably be somewhere else XXX */ +#define FIRSTARG 3 /* first argument is in reg 3 */ +#define NARGREG 8 /* 8 args are in registers */ +#define MOREARGS(sp) ((caddr_t)((int)(sp) + 8)) /* more args go here */ + +volatile int want_resched; + +#ifdef DDB +u_int32_t db_dumpframe(u_int32_t); +void +ppc_dumpbt(struct trapframe *frame) +{ + u_int32_t addr; + /* dumpframe is defined in db_trace.c */ + addr=frame->fixreg[1]; + while (addr != 0) { + addr = db_dumpframe(addr); + } + return; +} +#endif +void +trap(frame) + struct trapframe *frame; +{ + struct proc *p = curproc; + int type = frame->exc; + u_quad_t sticks; + union sigval sv; + + if (frame->srr1 & PSL_PR) { + type |= EXC_USER; + sticks = p->p_sticks; + } + + switch (type) { + case EXC_TRC|EXC_USER: + { + sv.sival_int = frame->srr0; + trapsignal(p, SIGTRAP, type, TRAP_TRACE, sv); + } + break; + + case EXC_MCHK: + { + faultbuf *fb; + + if (fb = p->p_addr->u_pcb.pcb_onfault) { + p->p_addr->u_pcb.pcb_onfault = 0; + frame->srr0 = fb->pc; /* PC */ + frame->srr1 = fb->sr; /* SR */ + frame->fixreg[1] = fb->sp; /* SP */ + frame->fixreg[3] = 1; /* != 0 */ + frame->cr = fb->cr; + bcopy(&fb->regs[0], &frame->fixreg[13], 19*4); + return; + } + } + goto brain_damage; + + case EXC_DSI: + { + vm_map_t map; + vm_offset_t va; + int ftype; + faultbuf *fb; + + map = kernel_map; + va = frame->dar; + if ((va >> ADDR_SR_SHFT) == USER_SR) { + sr_t user_sr; + + asm ("mfsr %0, %1" + : "=r"(user_sr) : "K"(USER_SR)); + va &= ADDR_PIDX | ADDR_POFF; + va |= user_sr << ADDR_SR_SHFT; + map = &p->p_vmspace->vm_map; + } + if (frame->dsisr & DSISR_STORE) + ftype = VM_PROT_READ | VM_PROT_WRITE; + else + ftype = VM_PROT_READ; +#ifdef UVM + if (uvm_fault(map, trunc_page(va), 0, ftype) + == KERN_SUCCESS) +#else + if (vm_fault(map, trunc_page(va), ftype, FALSE) + == KERN_SUCCESS) +#endif + { + return; + } + if (fb = p->p_addr->u_pcb.pcb_onfault) { + p->p_addr->u_pcb.pcb_onfault = 0; + frame->srr0 = fb->pc; /* PC */ + frame->fixreg[1] = fb->sp; /* SP */ + frame->fixreg[3] = 1; /* != 0 */ + frame->cr = fb->cr; + bcopy(&fb->regs[0], &frame->fixreg[13], 19*4); + return; + } + map = kernel_map; + } +printf("kern dsi on addr %x iar %x\n", frame->dar, frame->srr0); + goto brain_damage; + case EXC_DSI|EXC_USER: + { + int ftype, vftype; + + if (frame->dsisr & DSISR_STORE) { + ftype = VM_PROT_READ | VM_PROT_WRITE; + vftype = VM_PROT_WRITE; + } else + vftype = ftype = VM_PROT_READ; +#ifdef UVM + if (uvm_fault(&p->p_vmspace->vm_map, + trunc_page(frame->dar), 0, ftype) + == KERN_SUCCESS) +#else + if (vm_fault(&p->p_vmspace->vm_map, + trunc_page(frame->dar), ftype, FALSE) + == KERN_SUCCESS) +#endif + { + break; + } +#if 0 +printf("dsi on addr %x iar %x lr %x\n", frame->dar, frame->srr0,frame->lr); +#endif +/* + * keep this for later in case we want it later. +*/ + sv.sival_int = frame->dar; + trapsignal(p, SIGSEGV, vftype, SEGV_MAPERR, sv); + } + break; + case EXC_ISI|EXC_USER: + { + int ftype; + + ftype = VM_PROT_READ | VM_PROT_EXECUTE; +#ifdef UVM + if (uvm_fault(&p->p_vmspace->vm_map, + trunc_page(frame->srr0), 0, ftype) + == KERN_SUCCESS) +#else + if (vm_fault(&p->p_vmspace->vm_map, + trunc_page(frame->srr0), ftype, FALSE) + == KERN_SUCCESS) +#endif + { + break; + } + } +#if 0 +printf("isi iar %x\n", frame->srr0); +#endif + case EXC_MCHK|EXC_USER: +/* XXX Likely that returning from this trap is bogus... */ +/* XXX Have to make sure that sigreturn does the right thing. */ + sv.sival_int = frame->srr0; + trapsignal(p, SIGSEGV, VM_PROT_EXECUTE, SEGV_MAPERR, sv); + break; + case EXC_SC|EXC_USER: + { + struct sysent *callp; + size_t argsize; + register_t code, error; + register_t *params, rval[2]; + int nsys, n; + register_t args[10]; + +#ifdef UVM + uvmexp.syscalls++; +#else + cnt.v_syscall++; +#endif + + nsys = p->p_emul->e_nsysent; + callp = p->p_emul->e_sysent; + + code = frame->fixreg[0]; + params = frame->fixreg + FIRSTARG; + + switch (code) { + case SYS_syscall: + /* + * code is first argument, + * followed by actual args. + */ + code = *params++; + break; + case SYS___syscall: + /* + * Like syscall, but code is a quad, + * so as to maintain quad alignment + * for the rest of the args. + */ + if (callp != sysent) + break; + params++; + code = *params++; + break; + default: + break; + } + if (code < 0 || code >= nsys) + callp += p->p_emul->e_nosys; + else + callp += code; + argsize = callp->sy_argsize; + n = NARGREG - (params - (frame->fixreg + FIRSTARG)); + if (argsize > n * sizeof(register_t)) { + bcopy(params, args, n * sizeof(register_t)); + if (error = copyin(MOREARGS(frame->fixreg[1]), + args + n, + argsize - n * sizeof(register_t))) { +#ifdef KTRACE + /* Can't get all the arguments! */ + if (KTRPOINT(p, KTR_SYSCALL)) + ktrsyscall(p, code, + argsize, args); +#endif + goto syscall_bad; + } + params = args; + } +#ifdef KTRACE + if (KTRPOINT(p, KTR_SYSCALL)) + ktrsyscall(p, code, argsize, params); +#endif + rval[0] = 0; + rval[1] = frame->fixreg[FIRSTARG + 1]; + +#ifdef SYSCALL_DEBUG + scdebug_call(p, code, params); +#endif + + + switch (error = (*callp->sy_call)(p, params, rval)) { + case 0: + frame->fixreg[0] = error; + frame->fixreg[FIRSTARG] = rval[0]; + frame->fixreg[FIRSTARG + 1] = rval[1]; + frame->cr &= ~0x10000000; + break; + case ERESTART: + /* + * Set user's pc back to redo the system call. + */ + frame->srr0 -= 4; + break; + case EJUSTRETURN: + /* nothing to do */ + break; + default: +syscall_bad: + if (p->p_emul->e_errno) + error = p->p_emul->e_errno[error]; + frame->fixreg[0] = error; + frame->fixreg[FIRSTARG] = error; + frame->fixreg[FIRSTARG + 1] = rval[1]; + frame->cr |= 0x10000000; + break; + } +#ifdef SYSCALL_DEBUG + scdebug_ret(p, code, error, rval); +#endif +#ifdef KTRACE + if (KTRPOINT(p, KTR_SYSRET)) + ktrsysret(p, code, error, rval[0]); +#endif + } + break; + + case EXC_FPU|EXC_USER: + if (fpuproc) + save_fpu(fpuproc); + fpuproc = p; + enable_fpu(p); + break; + + case EXC_ALI|EXC_USER: + /* alignment exception + * we check to see if this can be fixed up + * by the code that fixes the typical gcc misaligned code + * then kill the process if not. + */ + if (fix_unaligned(p, frame) == 0) { + frame->srr0 += 4; + } else { + sv.sival_int = frame->srr0; + trapsignal(p, SIGSEGV, VM_PROT_EXECUTE, SEGV_MAPERR, + sv); + } + break; + + default: + +brain_damage: +/* +mpc_print_pci_stat(); +*/ + +#ifdef DDB + /* set up registers */ + db_save_regs(frame); +#endif + panic ("trap type %x at %x lr %x\n", + type, frame->srr0, frame->lr); + + + case EXC_PGM|EXC_USER: + { + char *errstr[8]; + int errnum = 0; + int i; + + if (frame->srr1 & (1<<(31-11))) { + /* floating point enabled program exception */ + errstr[errnum] = "floating point"; + errnum++; + } + if (frame->srr1 & (1<<(31-12))) { + /* illegal instruction program exception */ + errstr[errnum] = "illegal instruction"; + errnum++; + } + if (frame->srr1 & (1<<(31-13))) { + /* privileged instruction exception */ + errstr[errnum] = "priviledged instr"; + errnum++; + } + if (frame->srr1 & (1<<(31-14))) { + errstr[errnum] = "trap instr"; + errnum++; + /* trap instruction exception */ + /* + instr = copyin (srr0) + if (instr == BKPT_INST && uid == 0) { + db_trap(T_BREAKPOINT?) + break; + } + */ + } + if (frame->srr1 & (1<<(31-15))) { + errstr[errnum] = "previous address"; + errnum++; + } +#if 0 +printf("pgm iar %x srr1 %x\n", frame->srr0, frame->srr1); +for (i = 0; i < errnum; i++) { + printf("\t[%s]\n", errstr[i]); +} +#endif + sv.sival_int = frame->srr0; + trapsignal(p, SIGILL, 0, ILL_ILLOPC, sv); + break; + case EXC_PGM: + /* should check for correct byte here or panic */ +#ifdef DDB + db_save_regs(frame); + db_trap(T_BREAKPOINT); +#else + panic("trap EXC_PGM"); +#endif + break; + + } + case EXC_AST|EXC_USER: + /* This is just here that we trap */ + break; + } + + astpending = 0; /* we are about to do it */ + +#ifdef UVM + uvmexp.softs++; +#else + cnt.v_soft++; +#endif + + if (p->p_flag & P_OWEUPC) { + p->p_flag &= ~P_OWEUPC; + ADDUPROF(p); + } + + /* take pending signals */ + { + int sig; + + while (sig = CURSIG(p)) + postsig(sig); + } + + p->p_priority = p->p_usrpri; + if (want_resched) { + int s, sig; + + /* + * Since we are curproc, a clock interrupt could + * change our priority without changing run queues + * (the running process is not kept on a run queue). + * If this happened after we setrunqueue ourselves but + * before switch()'ed, we might not be on the queue + * indicated by our priority. + */ + s = splstatclock(); + setrunqueue(p); + p->p_stats->p_ru.ru_nivcsw++; + mi_switch(); + splx(s); + while (sig = CURSIG(p)) + postsig(sig); + } + + /* + * If profiling, charge recent system time to the trapped pc. + */ + if (p->p_flag & P_PROFIL) { + extern int psratio; + + addupc_task(p, frame->srr0, + (int)(p->p_sticks - sticks) * psratio); + } + /* + * If someone stole the fpu while we were away, disable it + */ + if (p != fpuproc) + frame->srr1 &= ~PSL_FP; + curpriority = p->p_priority; +} + +void +child_return(p) + struct proc *p; +{ + struct trapframe *tf = trapframe(p); + + tf->fixreg[0] = 0; + tf->fixreg[FIRSTARG] = 0; + tf->fixreg[FIRSTARG + 1] = 1; + tf->cr &= ~0x10000000; + tf->srr1 &= ~PSL_FP; /* Disable FPU, as we can't be fpuproc */ +#ifdef KTRACE + if (KTRPOINT(p, KTR_SYSRET)) + ktrsysret(p, SYS_fork, 0, 0); +#endif + /* Profiling? XXX */ + curpriority = p->p_priority; +} + +static inline void +setusr(content) + int content; +{ + asm volatile ("isync; mtsr %0,%1; isync" + :: "n"(USER_SR), "r"(content)); +} + +int +badaddr(addr, len) + char *addr; + u_int32_t len; +{ + faultbuf env; + u_int32_t v; + + if (setfault(env)) { + curpcb->pcb_onfault = 0; + return EFAULT; + } + switch(len) { + case 4: + v = *((volatile u_int32_t *)addr); + break; + case 2: + v = *((volatile u_int16_t *)addr); + break; + default: + v = *((volatile u_int8_t *)addr); + break; + } + curpcb->pcb_onfault = 0; + return(0); +} + +int +copyin(udaddr, kaddr, len) + const void *udaddr; + void *kaddr; + size_t len; +{ + void *p; + size_t l; + faultbuf env; + + if (setfault(env)) { + curpcb->pcb_onfault = 0; + return EFAULT; + } + while (len > 0) { + p = USER_ADDR + ((u_int)udaddr & ~SEGMENT_MASK); + l = (USER_ADDR + SEGMENT_LENGTH) - p; + if (l > len) + l = len; + setusr(curpcb->pcb_pm->pm_sr[(u_int)udaddr >> ADDR_SR_SHFT]); + bcopy(p, kaddr, l); + udaddr += l; + kaddr += l; + len -= l; + } + curpcb->pcb_onfault = 0; + return 0; +} + +int +copyout(kaddr, udaddr, len) + const void *kaddr; + void *udaddr; + size_t len; +{ + void *p; + size_t l; + faultbuf env; + + if (setfault(env)) { + curpcb->pcb_onfault = 0; + return EFAULT; + } + while (len > 0) { + p = USER_ADDR + ((u_int)udaddr & ~SEGMENT_MASK); + l = (USER_ADDR + SEGMENT_LENGTH) - p; + if (l > len) + l = len; + setusr(curpcb->pcb_pm->pm_sr[(u_int)udaddr >> ADDR_SR_SHFT]); + bcopy(kaddr, p, l); + udaddr += l; + kaddr += l; + len -= l; + } + curpcb->pcb_onfault = 0; + return 0; +} + +/* + * For now, this only deals with the particular unaligned access case + * that gcc tends to generate. Eventually it should handle all of the + * possibilities that can happen on a 32-bit PowerPC in big-endian mode. + */ + +static int +fix_unaligned(p, frame) + struct proc *p; + struct trapframe *frame; +{ + int indicator = EXC_ALI_OPCODE_INDICATOR(frame->dsisr); + + switch (indicator) { + case EXC_ALI_LFD: + case EXC_ALI_STFD: + { + int reg = EXC_ALI_RST(frame->dsisr); + double *fpr = &p->p_addr->u_pcb.pcb_fpu.fpr[reg]; + + /* Juggle the FPU to ensure that we've initialized + * the FPRs, and that their current state is in + * the PCB. + */ + if (fpuproc != p) { + if (fpuproc) + save_fpu(fpuproc); + enable_fpu(p); + } + save_fpu(p); + + if (indicator == EXC_ALI_LFD) { + if (copyin((void *)frame->dar, fpr, + sizeof(double)) != 0) + return -1; + enable_fpu(p); + } else { + if (copyout(fpr, (void *)frame->dar, + sizeof(double)) != 0) + return -1; + } + return 0; + } + break; + } + + return -1; +} diff --git a/sys/arch/mvmeppc/mvmeppc/vm_machdep.c b/sys/arch/mvmeppc/mvmeppc/vm_machdep.c new file mode 100644 index 00000000000..ff794fe8cea --- /dev/null +++ b/sys/arch/mvmeppc/mvmeppc/vm_machdep.c @@ -0,0 +1,289 @@ +/* $OpenBSD: vm_machdep.c,v 1.1 2001/06/26 21:57:55 smurph Exp $ */ +/* $NetBSD: vm_machdep.c,v 1.1 1996/09/30 16:34:57 ws Exp $ */ + +/* + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/param.h> +#include <sys/core.h> +#include <sys/exec.h> +#include <sys/proc.h> +#include <sys/signalvar.h> +#include <sys/user.h> +#include <sys/vnode.h> + +#include <vm/vm.h> +#include <vm/vm_kern.h> + +#ifdef UVM +#include <uvm/uvm_extern.h> +#endif + +#include <machine/pcb.h> + +/* + * Finish a fork operation, with process p2 nearly set up. + */ +void +cpu_fork(p1, p2, stack, stacksize) + struct proc *p1, *p2; + void *stack; + size_t stacksize; +{ + struct trapframe *tf; + struct callframe *cf; + struct switchframe *sf; + caddr_t stktop1, stktop2; + extern void fork_trampoline __P((void)); + extern void child_return __P((struct proc *)); + struct pcb *pcb = &p2->p_addr->u_pcb; + + if (p1 == fpuproc) + save_fpu(p1); + *pcb = p1->p_addr->u_pcb; + +#ifdef UVM + pcb->pcb_pm = p2->p_vmspace->vm_map.pmap; +#else + pcb->pcb_pm = &p2->p_vmspace->vm_pmap; +#endif + + pmap_extract(pmap_kernel(), + (vm_offset_t)pcb->pcb_pm, (paddr_t *)&pcb->pcb_pmreal); + + /* + * Setup the trap frame for the new process + */ + stktop1 = (caddr_t)trapframe(p1); + stktop2 = (caddr_t)trapframe(p2); + bcopy(stktop1, stktop2, sizeof(struct trapframe)); + + /* + * If specified, give the child a different stack. + */ + if (stack != NULL) + tf->fixreg[1] = (register_t)stack + stacksize; + + stktop2 = (caddr_t)((u_long)stktop2 & ~15); /* Align stack pointer */ + + /* + * There happens to be a callframe, too. + */ + cf = (struct callframe *)stktop2; + cf->lr = (int)fork_trampoline; + + /* + * Below the trap frame, there is another call frame: + */ + stktop2 -= 16; + cf = (struct callframe *)stktop2; + cf->r31 = (register_t)child_return; + cf->r30 = (register_t)p2; + + /* + * Below that, we allocate the switch frame: + */ + stktop2 -= roundup(sizeof *sf, 16); /* must match SFRAMELEN in genassym */ + sf = (struct switchframe *)stktop2; + bzero((void *)sf, sizeof *sf); /* just in case */ + sf->sp = (int)cf; + sf->user_sr = pmap_kernel()->pm_sr[USER_SR]; /* again, just in case */ + pcb->pcb_sp = (int)stktop2; + pcb->pcb_spl = 0; +} + +/* + * Set initial pc of process forked by above. + */ +void +cpu_set_kpc(p, pc, arg) + struct proc *p; + void (*pc) __P((void *)); + void *arg; +{ + struct switchframe *sf = (struct switchframe *)p->p_addr->u_pcb.pcb_sp; + struct callframe *cf = (struct callframe *)sf->sp; + + cf->r30 = (register_t)arg; + cf->r31 = (register_t)pc; + cf++->lr = (register_t)pc; +} + +void +cpu_swapin(p) + struct proc *p; +{ + struct pcb *pcb = &p->p_addr->u_pcb; + + pmap_extract(pmap_kernel(), + (vm_offset_t)pcb->pcb_pm, (paddr_t *)pcb->pcb_pmreal); +} + +/* + * Move pages from one kernel virtual address to another. + */ +void +pagemove(from, to, size) + caddr_t from, to; + size_t size; +{ + vaddr_t va; + paddr_t pa; + + for (va = (vm_offset_t)from; size > 0; size -= NBPG) { + pmap_extract(pmap_kernel(), va, &pa); + pmap_remove(pmap_kernel(), va, va + NBPG); + pmap_enter(pmap_kernel(), (vm_offset_t)to, pa, + VM_PROT_READ | VM_PROT_WRITE, 1, + VM_PROT_READ | VM_PROT_WRITE); + va += NBPG; + to += NBPG; + } +} + +/* + * cpu_exit is called as the last action during exit. + * We release the address space and machine-dependent resources, + * including the memory for the user structure and kernel stack. + * + * Since we don't have curproc anymore, we cannot sleep, and therefor + * this is at least incorrect for the multiprocessor version. + * Not sure whether we can get away with this in the single proc version. XXX + */ +void +cpu_exit(p) + struct proc *p; +{ + if (p == fpuproc) /* release the fpu */ + fpuproc = 0; + + (void)splhigh(); + switchexit(p); +} + +/* + * Write the machine-dependent part of a core dump. + */ +int +cpu_coredump(p, vp, cred, chdr) + struct proc *p; + struct vnode *vp; + struct ucred *cred; + struct core *chdr; +{ + struct coreseg cseg; + struct md_coredump md_core; + struct trapframe *tf; + int error; + +#if 1 + CORE_SETMAGIC(*chdr, COREMAGIC, MID_ZERO, 0); + chdr->c_hdrsize = ALIGN(sizeof *chdr); + chdr->c_seghdrsize = ALIGN(sizeof cseg); + chdr->c_cpusize = sizeof md_core; + + process_read_regs(p, &md_core); + + CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_ZERO, CORE_CPU); + cseg.c_addr = 0; + cseg.c_size = chdr->c_cpusize; + + if (error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&cseg, chdr->c_seghdrsize, + (off_t)chdr->c_hdrsize, UIO_SYSSPACE, + IO_NODELOCKED|IO_UNIT, cred, NULL, p)) + return error; + if (error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&md_core, sizeof md_core, + (off_t)(chdr->c_hdrsize + chdr->c_seghdrsize), UIO_SYSSPACE, + IO_NODELOCKED|IO_UNIT, cred, NULL, p)) + return error; + + chdr->c_nseg++; +#endif + return 0; +} + +/* + * Map an IO request into kernel virtual address space. + */ +void +vmapbuf(bp, len) + struct buf *bp; + vm_size_t len; +{ + vm_offset_t faddr, taddr, off; + vm_offset_t pa; + +#ifdef DIAGNOSTIC + if (!(bp->b_flags & B_PHYS)) + panic("vmapbuf"); +#endif + faddr = trunc_page((vaddr_t)(bp->b_saveaddr = bp->b_data)); + off = (vm_offset_t)bp->b_data - faddr; + len = round_page(off + len); +#ifdef UVM + taddr = uvm_km_valloc_wait(phys_map, len); +#else + taddr = kmem_alloc_wait(phys_map, len); +#endif + bp->b_data = (caddr_t)(taddr + off); + for (; len > 0; len -= NBPG) { + pmap_extract(vm_map_pmap(&bp->b_proc->p_vmspace->vm_map), faddr, &pa); + pmap_enter(vm_map_pmap(phys_map), taddr, pa, + VM_PROT_READ | VM_PROT_WRITE, 1, 0); + faddr += NBPG; + taddr += NBPG; + } +} + +/* + * Free the io map addresses associated with this IO operation. + */ +void +vunmapbuf(bp, len) + struct buf *bp; + vm_size_t len; +{ + vm_offset_t addr, off; + +#ifdef DIAGNOSTIC + if (!(bp->b_flags & B_PHYS)) + panic("vunmapbuf"); +#endif + addr = trunc_page((vaddr_t)bp->b_data); + off = (vm_offset_t)bp->b_data - addr; + len = round_page(off + len); +#ifdef UVM + uvm_km_free_wakeup(phys_map, addr, len); +#else + kmem_free_wakeup(phys_map, addr, len); +#endif + bp->b_data = bp->b_saveaddr; + bp->b_saveaddr = 0; +} diff --git a/sys/arch/mvmeppc/mvmeppc/wscons_machdep.c b/sys/arch/mvmeppc/mvmeppc/wscons_machdep.c new file mode 100644 index 00000000000..0d3616ad7b7 --- /dev/null +++ b/sys/arch/mvmeppc/mvmeppc/wscons_machdep.c @@ -0,0 +1,105 @@ +/* $OpenBSD: wscons_machdep.c,v 1.1 2001/06/26 21:57:56 smurph Exp $ */ + +/* + * Copyright (c) 2001 Aaron Campbell + * 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 Aaron Campbell. + * 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 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/kernel.h> +#include <sys/conf.h> +#include <sys/device.h> +#include <sys/extent.h> + +#include <machine/bus.h> + +#include <dev/cons.h> + +#include "wsdisplay.h" +#if NWSDISPLAY > 0 +#include <dev/wscons/wsdisplayvar.h> +#endif + +void wscnprobe __P((struct consdev *)); +void wscninit __P((struct consdev *)); +void wscnputc __P((dev_t, char)); +int wscngetc __P((dev_t)); +void wscnpollc __P((dev_t, int)); + +void +wscnprobe(cp) + struct consdev *cp; +{ + int maj; + + /* locate the major number */ + for (maj = 0; maj < nchrdev; maj++) { + if (cdevsw[maj].d_open == wsdisplayopen) + break; + } + + if (maj == nchrdev) { + /* we are not in cdevsw[], give up */ + panic("wsdisplay is not in cdevsw[]"); + } + + cp->cn_dev = makedev(maj, 0); + cp->cn_pri = CN_INTERNAL; +} + +void +wscninit(cp) + struct consdev *cp; +{ + return; +} + +void +wscnputc(dev, i) + dev_t dev; + char i; +{ + wsdisplay_cnputc(dev, (int)i); +} + +int +wscngetc(dev) + dev_t dev; +{ + return (wskbd_cngetc(dev)); +} + +void +wscnpollc(dev, on) + dev_t dev; + int on; +{ + wskbd_cnpollc(dev, on); +} diff --git a/sys/arch/mvmeppc/pci/mpcpcibr.c b/sys/arch/mvmeppc/pci/mpcpcibr.c new file mode 100644 index 00000000000..65166225d51 --- /dev/null +++ b/sys/arch/mvmeppc/pci/mpcpcibr.c @@ -0,0 +1,666 @@ +/* $OpenBSD: mpcpcibr.c,v 1.1 2001/06/26 21:57:56 smurph Exp $ */ + +/* + * Copyright (c) 2001 Steve Murphree, Jr. + * + * 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 under OpenBSD for RTMX Inc + * by Per Fogelstrom, Opsycon AB. + * 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. + * + */ + +/* + * Motorola 'Raven' PCI BUS Bridge driver. + * specialized hooks for different config methods. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/malloc.h> +#include <sys/device.h> +#include <sys/proc.h> +#include <vm/vm.h> + +#include <machine/autoconf.h> +#include <machine/bat.h> +#include <machine/bus.h> +#include <dev/pci/pcireg.h> +#include <dev/pci/pcivar.h> +#include <dev/pci/pcidevs.h> + +#include <mvmeppc/pci/pcibrvar.h> +#include <mvmeppc/dev/ravenreg.h> + +extern vm_map_t phys_map; + +int mpcpcibrmatch __P((struct device *, void *, void *)); +void mpcpcibrattach __P((struct device *, struct device *, void *)); + +void mpc_attach_hook __P((struct device *, struct device *, + struct pcibus_attach_args *)); +int mpc_bus_maxdevs __P((void *, int)); +pcitag_t mpc_make_tag __P((void *, int, int, int)); +void mpc_decompose_tag __P((void *, pcitag_t, int *, int *, int *)); +pcireg_t mpc_conf_read __P((void *, pcitag_t, int)); +void mpc_conf_write __P((void *, pcitag_t, int, pcireg_t)); + +int mpc_intr_map __P((void *, pcitag_t, int, int, pci_intr_handle_t *)); +const char *mpc_intr_string __P((void *, pci_intr_handle_t)); +void *mpc_intr_establish __P((void *, pci_intr_handle_t, + int, int (*func)(void *), void *, char *)); +void mpc_intr_disestablish __P((void *, void *)); +int mpc_ether_hw_addr __P((struct ppc_pci_chipset *, u_int8_t *)); + +void +mpc_cfg_write_1( struct pcibr_config *cp, u_int32_t reg, u_int8_t val); +void +mpc_cfg_write_2( struct pcibr_config *cp, u_int32_t reg, u_int16_t val); +void +mpc_cfg_write_4( struct pcibr_config *cp, u_int32_t reg, u_int32_t val); + +u_int8_t +mpc_cfg_read_1( struct pcibr_config *cp, u_int32_t reg); + +u_int16_t +mpc_cfg_read_2( struct pcibr_config *cp, u_int32_t reg); + +u_int32_t +mpc_cfg_read_4( struct pcibr_config *cp, u_int32_t reg); + +struct cfattach mpcpcibr_ca = { + sizeof(struct pcibr_softc), mpcpcibrmatch, mpcpcibrattach, +}; + +struct cfdriver mpcpcibr_cd = { + NULL, "mpcpcibr", DV_DULL, +}; + +static int mpcpcibrprint __P((void *, const char *pnp)); + +struct pcibr_config mpc_config; + +/* + * config types + * bit meanings + * 0 - standard cf8/cfc type configurations, + * sometimes the base addresses for these are different + * 1 - Config Method #2 configuration - uni-north + * + * 2 - 64 bit config bus, data for accesses &4 is at daddr+4; + */ + +struct powerpc_bus_dma_tag pci_bus_dma_tag = { + NULL, + _bus_dmamap_create, + _bus_dmamap_destroy, + _bus_dmamap_load, + _bus_dmamap_load_mbuf, + _bus_dmamap_load_uio, + _bus_dmamap_load_raw, + _bus_dmamap_unload, + _bus_dmamap_sync, + _bus_dmamem_alloc, + _bus_dmamem_free, + _bus_dmamem_map, + _bus_dmamem_unmap, + _bus_dmamem_mmap +}; + +int +mpcpcibrmatch(parent, match, aux) +struct device *parent; +void *match, *aux; +{ + struct confargs *ca = aux; + int found = 0; + + /* We must be a child of the raven device */ + if (strcmp(parent->dv_cfdata->cf_driver->cd_name, "raven") != 0) + return (0); +#if 0 + if (strcmp(ca->ca_name, mpcpcibr_cd.cd_name) != 0) + return (0); +#endif + return 1; +} + +int pci_map_a = 0; +void +mpcpcibrattach(parent, self, aux) +struct device *parent, *self; +void *aux; +{ + struct pcibr_softc *sc = (struct pcibr_softc *)self; + struct confargs *ca = aux; + struct pcibr_config *lcp; + struct pcibus_attach_args pba; + int map, node; + char *bridge; + int of_node = 0; + + lcp = sc->sc_pcibr = &mpc_config; + + /* + addbatmap(RAVEN_V_PCI_MEM_SPACE, RAVEN_P_PCI_MEM_SPACE, BAT_I); + */ + sc->sc_membus_space = prep_mem_space_tag; + sc->sc_iobus_space = prep_io_space_tag; + + lcp->lc_pc.pc_conf_v = lcp; + lcp->lc_pc.pc_attach_hook = mpc_attach_hook; + lcp->lc_pc.pc_bus_maxdevs = mpc_bus_maxdevs; + lcp->lc_pc.pc_make_tag = mpc_make_tag; + lcp->lc_pc.pc_decompose_tag = mpc_decompose_tag; + lcp->lc_pc.pc_conf_read = mpc_conf_read; + lcp->lc_pc.pc_conf_write = mpc_conf_write; + lcp->lc_pc.pc_ether_hw_addr = mpc_ether_hw_addr; + lcp->lc_iot = &sc->sc_iobus_space; + lcp->lc_memt = &sc->sc_membus_space; + + lcp->ioh_cf8 = PREP_CONFIG_ADD; + lcp->ioh_cfc = PREP_CONFIG_DAT; + + lcp->config_type = 0; + + lcp->lc_pc.pc_intr_v = lcp; + lcp->lc_pc.pc_intr_map = mpc_intr_map; + lcp->lc_pc.pc_intr_string = mpc_intr_string; + lcp->lc_pc.pc_intr_establish = mpc_intr_establish; + lcp->lc_pc.pc_intr_disestablish = mpc_intr_disestablish; + + printf(": Raven, Revision 0x%x.\n", + mpc_cfg_read_1(lcp, RAVEN_PCI_REVID)); + bridge = "RAVEN"; + pba.pba_dmat = &pci_bus_dma_tag; + + pba.pba_busname = "pci"; + pba.pba_iot = &sc->sc_iobus_space; + pba.pba_memt = &sc->sc_membus_space; + pba.pba_pc = &lcp->lc_pc; + pba.pba_bus = 0; +/* + pba.pba_flags = PCI_FLAGS_MEM_ENABLED | PCI_FLAGS_IO_ENABLED; +*/ +#if 1 + /* set up prep environment */ + *(unsigned int *)RAVEN_MSADD0 = RAVEN_MSADD0_PREP; + *(unsigned int *)RAVEN_MSOFF0 = RAVEN_MSOFF0_PREP; + *(unsigned int *)RAVEN_MSADD1 = RAVEN_MSADD1_PREP; + *(unsigned int *)RAVEN_MSOFF1 = RAVEN_MSOFF1_PREP; + *(unsigned int *)RAVEN_MSADD2 = RAVEN_MSADD2_PREP; + *(unsigned int *)RAVEN_MSOFF2 = RAVEN_MSOFF2_PREP; + *(unsigned int *)RAVEN_MSADD3 = RAVEN_MSADD3_PREP; + *(unsigned int *)RAVEN_MSOFF3 = RAVEN_MSOFF3_PREP; + + /* set up PCI local bus */ + mpc_cfg_write_4(lcp, RAVEN_PCI_PSADD0, RAVEN_PCI_PSADD0_VAL); + mpc_cfg_write_4(lcp, RAVEN_PCI_PSOFF0, RAVEN_PCI_PSOFF0_VAL); + mpc_cfg_write_4(lcp, RAVEN_PCI_PSADD1, RAVEN_PCI_PSADD1_VAL); + mpc_cfg_write_4(lcp, RAVEN_PCI_PSOFF1, RAVEN_PCI_PSOFF1_VAL); + mpc_cfg_write_4(lcp, RAVEN_PCI_PSADD2, RAVEN_PCI_PSADD2_VAL); + mpc_cfg_write_4(lcp, RAVEN_PCI_PSOFF2, RAVEN_PCI_PSOFF2_VAL); + mpc_cfg_write_4(lcp, RAVEN_PCI_PSADD3, RAVEN_PCI_PSADD3_VAL); + mpc_cfg_write_4(lcp, RAVEN_PCI_PSOFF3, RAVEN_PCI_PSOFF3_VAL); + + /* set up VME -> PCI local bus */ + + mpc_cfg_write_4(lcp, 0x100, 0x0); + mpc_cfg_write_4(lcp, 0x114, 0x0); + mpc_cfg_write_4(lcp, 0x128, 0x0); + mpc_cfg_write_4(lcp, 0x13C, 0x0); + + mpc_cfg_write_4(lcp, 0xF00, 0x0); + mpc_cfg_write_4(lcp, 0xF14, 0x0); + mpc_cfg_write_4(lcp, 0xF28, 0x0); + mpc_cfg_write_4(lcp, 0xF3C, 0x0); +#endif + /* enable mem and io mapping, and bus master */ + mpc_cfg_write_2(lcp, RAVEN_PCI_CMD, + RAVEN_CMD_IOSP|RAVEN_CMD_MEMSP|RAVEN_CMD_MASTR); + + config_found(self, &pba, mpcpcibrprint); +} + +static int +mpcpcibrprint(aux, pnp) +void *aux; +const char *pnp; +{ + struct pcibus_attach_args *pba = aux; + + if (pnp) + printf("%s at %s", pba->pba_busname, pnp); + printf(" bus %d", pba->pba_bus); + return (UNCONF); +} + +/* + * Get PCI physical address from given viritual address. + * XXX Note that cross page boundarys are *not* garantueed to work! + */ +#if 0 +vm_offset_t +vtophys(p) +void *p; +{ + vm_offset_t pa; + vm_offset_t va; + + va = (vm_offset_t)p; + if ((vm_offset_t)va < VM_MIN_KERNEL_ADDRESS) { + pa = va; + } else { + pmap_extract(vm_map_pmap(phys_map), va, (paddr_t *)&pa); + } + return (pa | ((pci_map_a == 1) ? RAVEN_PCI_CPUMEM : 0 )); +} + +#else +vm_offset_t +vtophys(p) + void *p; +{ + vm_offset_t pa; + vm_offset_t va; + extern int segment8_mapped; + extern int segmentC_mapped; + + va = (vm_offset_t)p; + /* This crap gets maped by bats 1:1 */ + if ((vm_offset_t)va < VM_MIN_KERNEL_ADDRESS) { + pa = va; + } else if (segment8_mapped && (va >= 0x80000000 && va < 0x90000000)) { + pa = va; + } else if (segmentC_mapped && (va >= 0xC0000000 && va < 0xD0000000)) { + pa = va; + } else if (pmap_extract(pmap_kernel(), va, &pa)) + return pa; + return va; +} +#endif + +void +mpc_attach_hook(parent, self, pba) +struct device *parent, *self; +struct pcibus_attach_args *pba; +{ +} + +int +mpc_ether_hw_addr(p, ethaddr) +struct ppc_pci_chipset *p; +u_int8_t *ethaddr; +{ + printf("mpc_ether_hw_addr not supported\n"); + return (0); +} + +int +mpc_bus_maxdevs(cpv, busno) +void *cpv; +int busno; +{ + return (32); +} + +#define BUS_SHIFT 16 +#define DEVICE_SHIFT 11 +#define FNC_SHIFT 8 + +pcitag_t +mpc_make_tag(cpv, bus, dev, fnc) +void *cpv; +int bus, dev, fnc; +{ + return (bus << BUS_SHIFT) | (dev << DEVICE_SHIFT) | (fnc << FNC_SHIFT); +} + +void +mpc_decompose_tag(cpv, tag, busp, devp, fncp) +void *cpv; +pcitag_t tag; +int *busp, *devp, *fncp; +{ + if (busp != NULL) + *busp = (tag >> BUS_SHIFT) & 0xff; + if (devp != NULL) + *devp = (tag >> DEVICE_SHIFT) & 0x1f; + if (fncp != NULL) + *fncp = (tag >> FNC_SHIFT) & 0x7; +} + +static u_int32_t +mpc_gen_config_reg(cpv, tag, offset) +void *cpv; +pcitag_t tag; +int offset; +{ + struct pcibr_config *cp = cpv; + unsigned int bus, dev, fcn; + u_int32_t reg; + /* + static int spin = 0; + while (spin > 85); + spin++; + */ + + mpc_decompose_tag(cpv, tag, &bus, &dev, &fcn); + + if (cp->config_type & 1) { + /* Config Mechanism #2 */ + if (bus == 0) { + if (dev < 11) { + return 0xffffffff; + } + /* + * Need to do config type 0 operation + * 1 << (11?+dev) | fcn << 8 | reg + * 11? is because pci spec states + * that 11-15 is reserved. + */ + reg = 1 << (dev) | fcn << 8 | offset; + + } else { + if (dev > 15) { + return 0xffffffff; + } + /* + * config type 1 + */ + reg = tag | offset | 1; + + } + } else { + /* config mechanism #2, type 0 + /* standard cf8/cfc config */ + reg = 0x80000000 | tag | offset; + + } + return reg; +} + +/*#define DEBUG_CONFIG */ +pcireg_t +mpc_conf_read(cpv, tag, offset) +void *cpv; +pcitag_t tag; +int offset; +{ + struct pcibr_config *cp = cpv; + + pcireg_t data; + u_int32_t reg; + int device; + int s; + int handle; + int daddr = 0; + + if (offset & 3 || offset < 0 || offset >= 0x100) { + printf ("pci_conf_read: bad reg %x\n", offset); + return (~0); + } + + reg = mpc_gen_config_reg(cpv, tag, offset); + /* if invalid tag, return -1 */ + if (reg == 0xffffffff) { + return 0xffffffff; + } + + if ((cp->config_type & 2) && (offset & 0x04)) { + daddr += 4; + } + + s = splhigh(); + + bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, reg); + bus_space_read_4(cp->lc_iot, cp->ioh_cf8, 0); /* XXX */ + data = bus_space_read_4(cp->lc_iot, cp->ioh_cfc, daddr); + bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, 0); /* disable */ + bus_space_read_4(cp->lc_iot, cp->ioh_cf8, 0); /* XXX */ + + splx(s); +#ifdef DEBUG_CONFIG + if (!((offset == 0) && (data == 0xffffffff))) { + unsigned int bus, dev, fcn; + mpc_decompose_tag(cpv, tag, &bus, &dev, &fcn); + printf("mpc_conf_read bus %x dev %x fcn %x offset %x", bus, dev, fcn, + offset); + printf(" daddr %x reg %x",daddr, reg); + printf(" data %x\n", data); + } +#endif + + return (data); +} + +void +mpc_conf_write(cpv, tag, offset, data) +void *cpv; +pcitag_t tag; +int offset; +pcireg_t data; +{ + struct pcibr_config *cp = cpv; + u_int32_t reg; + int s; + int handle; + int daddr = 0; + + reg = mpc_gen_config_reg(cpv, tag, offset); + + /* if invalid tag, return ??? */ + if (reg == 0xffffffff) { + return; + } + if ((cp->config_type & 2) && (offset & 0x04)) { + daddr += 4; + } +#ifdef DEBUG_CONFIG + { + unsigned int bus, dev, fcn; + mpc_decompose_tag(cpv, tag, &bus, &dev, &fcn); + printf("mpc_conf_write bus %x dev %x fcn %x offset %x", bus, + dev, fcn, offset); + printf(" daddr %x reg %x",daddr, reg); + printf(" data %x\n", data); + } +#endif + + s = splhigh(); + + bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, reg); + bus_space_read_4(cp->lc_iot, cp->ioh_cf8, 0); /* XXX */ + bus_space_write_4(cp->lc_iot, cp->ioh_cfc, daddr, data); + bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, 0); /* disable */ + bus_space_read_4(cp->lc_iot, cp->ioh_cf8, 0); /* XXX */ + + splx(s); +} + + +int +mpc_intr_map(lcv, bustag, buspin, line, ihp) +void *lcv; +pcitag_t bustag; +int buspin, line; +pci_intr_handle_t *ihp; +{ + struct pcibr_config *lcp = lcv; + pci_chipset_tag_t pc = &lcp->lc_pc; + int error = 0; + int route; + int lvl; + int device; + + *ihp = -1; + if (buspin == 0) { + /* No IRQ used. */ + error = 1; + } else if (buspin > 4) { + printf("mpc_intr_map: bad interrupt pin %d\n", buspin); + error = 1; + } + + if (!error) + *ihp = line; + return error; +} + +const char * +mpc_intr_string(lcv, ih) +void *lcv; +pci_intr_handle_t ih; +{ + static char str[16]; + + sprintf(str, "irq %d", ih); + return (str); +} + +typedef void *(intr_establish_t) __P((void *, pci_intr_handle_t, + int, int, int (*func)(void *), void *, char *)); +typedef void (intr_disestablish_t) __P((void *, void *)); +extern intr_establish_t *intr_establish_func; +extern intr_disestablish_t *intr_disestablish_func; + +void * +mpc_intr_establish(lcv, ih, level, func, arg, name) +void *lcv; +pci_intr_handle_t ih; +int level; +int (*func) __P((void *)); +void *arg; +char *name; +{ + return (*intr_establish_func)(lcv, ih, IST_LEVEL, level, func, arg, + name); +} + +void +mpc_intr_disestablish(lcv, cookie) +void *lcv, *cookie; +{ + /* XXX We should probably do something clever here.... later */ +} + +u_int32_t +pci_iack() +{ + /* do pci IACK cycle */ + /* this should be bus allocated. */ + volatile u_int8_t *iack = (u_int8_t *)RAVEN_PIACK; + u_int8_t val; + + val = *iack; + return val; +} + +void +mpc_cfg_write_1(cp, reg, val) +struct pcibr_config *cp; +u_int32_t reg; +u_int8_t val; +{ + int s; + s = splhigh(); + bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, + RAVEN_REGOFFS(reg)); + bus_space_write_1(cp->lc_iot, cp->ioh_cfc, 0, val); + splx(s); +} + +void +mpc_cfg_write_2(cp, reg, val) +struct pcibr_config *cp; +u_int32_t reg; +u_int16_t val; +{ + int s; + s = splhigh(); + bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, RAVEN_REGOFFS(reg)); + bus_space_write_2(cp->lc_iot, cp->ioh_cfc, 0, val); + splx(s); +} + +void +mpc_cfg_write_4(cp, reg, val) +struct pcibr_config *cp; +u_int32_t reg; +u_int32_t val; +{ + + int s; + s = splhigh(); + bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, RAVEN_REGOFFS(reg)); + bus_space_write_4(cp->lc_iot, cp->ioh_cfc, 0, val); + splx(s); +} + +u_int8_t +mpc_cfg_read_1(cp, reg) +struct pcibr_config *cp; +u_int32_t reg; +{ + u_int8_t _v_; + + int s; + s = splhigh(); + bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, RAVEN_REGOFFS(reg)); + _v_ = bus_space_read_1(cp->lc_iot, cp->ioh_cfc, 0); + splx(s); + return (_v_); +} + +u_int16_t +mpc_cfg_read_2(cp, reg) +struct pcibr_config *cp; +u_int32_t reg; +{ + u_int16_t _v_; + + int s; + s = splhigh(); + bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, RAVEN_REGOFFS(reg)); + _v_ = bus_space_read_2(cp->lc_iot, cp->ioh_cfc, 0); + splx(s); + return (_v_); +} + +u_int32_t +mpc_cfg_read_4(cp, reg) +struct pcibr_config *cp; +u_int32_t reg; +{ + u_int32_t _v_; + + int s; + s = splhigh(); + bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, RAVEN_REGOFFS(reg)); + _v_ = bus_space_read_4(cp->lc_iot, cp->ioh_cfc, 0); + splx(s); + return (_v_); +} diff --git a/sys/arch/mvmeppc/pci/pchb.c b/sys/arch/mvmeppc/pci/pchb.c new file mode 100644 index 00000000000..9c72921a720 --- /dev/null +++ b/sys/arch/mvmeppc/pci/pchb.c @@ -0,0 +1,106 @@ +/* $NetBSD: pchb.c,v 1.4 2000/01/25 07:19:11 tsubai Exp $ */ + +/*- + * Copyright (c) 1996 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by 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 REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> + +#include <machine/bus.h> + +#include <dev/pci/pcivar.h> +#include <dev/pci/pcireg.h> +#include <dev/pci/pcidevs.h> + +int pchbmatch __P((struct device *, void *, void *)); +void pchbattach __P((struct device *, struct device *, void *)); + +struct cfattach pchb_ca = { + sizeof(struct device), pchbmatch, pchbattach +}; + +struct cfdriver pchb_cd = { + NULL, "pchb", DV_DULL +}; + +int +pchbmatch(parent, cf, aux) + struct device *parent; + void *cf; + void *aux; +{ + struct pci_attach_args *pa = aux; + + /* + * Match all known PCI host chipsets. + */ + switch (PCI_VENDOR(pa->pa_id)) { + + case PCI_VENDOR_MOT: + switch (PCI_PRODUCT(pa->pa_id)) { + case PCI_PRODUCT_MOT_RAVEN: + return (1); + } + break; + } + + return (0); +} + +void +pchbattach(parent, self, aux) + struct device *parent, *self; + void *aux; +{ + struct pci_attach_args *pa = aux; + char devinfo[256]; + + printf("\n"); + + /* + * All we do is print out a description. Eventually, we + * might want to add code that does something that's + * possibly chipset-specific. + */ + + /* + pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo); + printf("%s: %s (rev. 0x%02x)\n", self->dv_xname, devinfo, + PCI_REVISION(pa->pa_class)); + */ +} diff --git a/sys/arch/mvmeppc/pci/pci_machdep.h b/sys/arch/mvmeppc/pci/pci_machdep.h new file mode 100644 index 00000000000..08181e158af --- /dev/null +++ b/sys/arch/mvmeppc/pci/pci_machdep.h @@ -0,0 +1,93 @@ +/* $OpenBSD: pci_machdep.h,v 1.1 2001/06/26 21:57:57 smurph Exp $ */ + +/* + * Copyright (c) 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. + */ + +/* + * Machine-specific definitions for PCI autoconfiguration. + */ + +/* + * Types provided to machine-independent PCI code + */ +typedef struct ppc_pci_chipset *pci_chipset_tag_t; +typedef u_long pcitag_t; +typedef u_long pci_intr_handle_t; + +/* + * ppc-specific PCI structure and type definitions. + * NOT TO BE USED DIRECTLY BY MACHINE INDEPENDENT CODE. + */ +struct ppc_pci_chipset { + void *pc_conf_v; + void (*pc_attach_hook) __P((struct device *, + struct device *, struct pcibus_attach_args *)); + int (*pc_bus_maxdevs) __P((void *, int)); + pcitag_t (*pc_make_tag) __P((void *, int, int, int)); + void (*pc_decompose_tag) __P((void *, pcitag_t, int *, + int *, int *)); + pcireg_t (*pc_conf_read) __P((void *, pcitag_t, int)); + void (*pc_conf_write) __P((void *, pcitag_t, int, pcireg_t)); + + void *pc_intr_v; + int (*pc_intr_map) __P((void *, pcitag_t, int, int, + pci_intr_handle_t *)); + const char *(*pc_intr_string) __P((void *, pci_intr_handle_t)); + void *(*pc_intr_establish) __P((void *, pci_intr_handle_t, + int, int (*)(void *), void *, char *)); + void (*pc_intr_disestablish) __P((void *, void *)); + int (*pc_ether_hw_addr) __P((struct ppc_pci_chipset *, u_int8_t *)); +}; + +/* + * 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)->pc_conf_v, (b)) +#define pci_make_tag(c, b, d, f) \ + (*(c)->pc_make_tag)((c)->pc_conf_v, (b), (d), (f)) +#define pci_decompose_tag(c, t, bp, dp, fp) \ + (*(c)->pc_decompose_tag)((c)->pc_conf_v, (t), (bp), (dp), (fp)) +#define pci_conf_read(c, t, r) \ + (*(c)->pc_conf_read)((c)->pc_conf_v, (t), (r)) +#define pci_conf_write(c, t, r, v) \ + (*(c)->pc_conf_write)((c)->pc_conf_v, (t), (r), (v)) +#define pci_intr_map(c, it, ip, il, ihp) \ + (*(c)->pc_intr_map)((c)->pc_intr_v, (it), (ip), (il), (ihp)) +#define pci_intr_string(c, ih) \ + (*(c)->pc_intr_string)((c)->pc_intr_v, (ih)) +#define pci_intr_establish(c, ih, l, h, a, nm) \ + (*(c)->pc_intr_establish)((c)->pc_intr_v, (ih), (l), (h), (a), (nm)) +#define pci_intr_disestablish(c, iv) \ + (*(c)->pc_intr_disestablish)((c)->pc_intr_v, (iv)) +#define pci_ether_hw_addr(c, s) \ + (*(c)->pc_ether_hw_addr)((c), (s)) + +vm_offset_t vtophys __P((void *)); + diff --git a/sys/arch/mvmeppc/pci/pcib.c b/sys/arch/mvmeppc/pci/pcib.c new file mode 100644 index 00000000000..2f7a56b5193 --- /dev/null +++ b/sys/arch/mvmeppc/pci/pcib.c @@ -0,0 +1,143 @@ +/* $OpenBSD: pcib.c,v 1.1 2001/06/26 21:57:57 smurph Exp $ */ +/* $NetBSD: pcib.c,v 1.6 1997/06/06 23:29:16 thorpej Exp $ */ + +/*- + * Copyright (c) 1996 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by 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. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> + +#include <machine/bus.h> +#include <dev/isa/isavar.h> + +#include <dev/pci/pcivar.h> +#include <dev/pci/pcireg.h> + +#include <dev/pci/pcidevs.h> +#include <mvmeppc/dev/ravenreg.h> + +#include "isa.h" + +int pcibmatch __P((struct device *, void *, void *)); +void pcibattach __P((struct device *, struct device *, void *)); +void pcib_callback __P((struct device *)); +int pcib_print __P((void *, const char *)); + +struct ppc_bus_space ppc_isa_io, ppc_isa_mem; + +struct cfattach pcib_ca = { + sizeof(struct device), pcibmatch, pcibattach +}; + +struct cfdriver pcib_cd = { + NULL, "pcib", DV_DULL +}; + +int +pcibmatch(parent, match, aux) + struct device *parent; + void *match, *aux; +{ + struct pci_attach_args *pa = aux; + + if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE && + PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_ISA) + return (1); + + switch (PCI_VENDOR(pa->pa_id)) { + case PCI_VENDOR_SYMPHONY: + switch (PCI_PRODUCT(pa->pa_id)) { + case PCI_PRODUCT_SYMPHONY_82C565: + return (1); + } + } + + return (0); +} + +void +pcibattach(parent, self, aux) + struct device *parent, *self; + void *aux; +{ + + ppc_isa_io = prep_isa_io_space_tag; + ppc_isa_mem = prep_isa_mem_space_tag; + + /* + * Cannot attach isa bus now; must postpone for various reasons + */ + + printf("\n"); + + config_defer(self, pcib_callback); +} + +void +pcib_callback(self) + struct device *self; +{ + struct isabus_attach_args iba; + +#if NPCIBIOS > 0 + pci_intr_post_fixup(); +#endif + + /* + * Attach the ISA bus behind this bridge. + */ + memset(&iba, 0, sizeof(iba)); + iba.iba_busname = "isa"; + iba.iba_iot = &ppc_isa_io; + iba.iba_memt = &ppc_isa_mem; +#if NISADMA > 0 + iba.iba_dmat = &isa_bus_dma_tag; +#endif + config_found(self, &iba, pcib_print); +} + +int +pcib_print(aux, pnp) + void *aux; + const char *pnp; +{ + /* Only ISAs can attach to pcib's; easy. */ + if (pnp) + printf("isa at %s", pnp); + return (UNCONF); +} diff --git a/sys/arch/mvmeppc/pci/pcibrvar.h b/sys/arch/mvmeppc/pci/pcibrvar.h new file mode 100644 index 00000000000..e3222f70272 --- /dev/null +++ b/sys/arch/mvmeppc/pci/pcibrvar.h @@ -0,0 +1,56 @@ +/* $OpenBSD: pcibrvar.h,v 1.1 2001/06/26 21:57:57 smurph Exp $ */ + +/* + * Copyright (c) 1997 Per Fogelstrom + * + * 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 under OpenBSD by + * Per Fogelstrom. + * 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. + * + */ + +struct pcibr_config { + bus_space_tag_t lc_memt; + bus_space_tag_t lc_iot; + bus_space_handle_t ioh_cf8; + bus_space_handle_t ioh_cfc; + struct ppc_pci_chipset lc_pc; + int config_type; + int bus; + int pci_init_done; + int node; +}; + +struct pcibr_softc { + struct device sc_dev; + struct pcibr_config *sc_pcibr; + struct ppc_bus_space sc_membus_space; + struct ppc_bus_space sc_iobus_space; + struct powerpc_bus_dma_tag sc_dmatag; + struct pcibr_config pcibr_config; +}; + + diff --git a/sys/arch/mvmeppc/pci/raven.c b/sys/arch/mvmeppc/pci/raven.c new file mode 100644 index 00000000000..1747ee0e9a4 --- /dev/null +++ b/sys/arch/mvmeppc/pci/raven.c @@ -0,0 +1,600 @@ +/* $OpenBSD: raven.c,v 1.1 2001/06/26 21:57:57 smurph Exp $ */ + +/* + * Copyright (c) 2001 Steve Murphree, Jr. + * + * 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 under OpenBSD for RTMX Inc + * by Per Fogelstrom, Opsycon AB. + * 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. + * + */ + +/* + * Motorola 'Raven' PCI BUS Bridge driver. + * specialized hooks for different config methods. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/malloc.h> +#include <sys/device.h> +#include <sys/proc.h> +#include <vm/vm.h> + +#include <machine/autoconf.h> +#include <machine/bat.h> + +#include <dev/pci/pcireg.h> +#include <dev/pci/pcivar.h> +#include <dev/pci/pcidevs.h> + +#include <mvmeppc/pci/pcibrvar.h> +#include <mvmeppc/pci/ravenreg.h> + +extern vm_map_t phys_map; + +int mpcpcibrmatch __P((struct device *, void *, void *)); +void mpcpcibrattach __P((struct device *, struct device *, void *)); + +void mpc_attach_hook __P((struct device *, struct device *, + struct pcibus_attach_args *)); +int mpc_bus_maxdevs __P((void *, int)); +pcitag_t mpc_make_tag __P((void *, int, int, int)); +void mpc_decompose_tag __P((void *, pcitag_t, int *, int *, int *)); +pcireg_t mpc_conf_read __P((void *, pcitag_t, int)); +void mpc_conf_write __P((void *, pcitag_t, int, pcireg_t)); + +int mpc_intr_map __P((void *, pcitag_t, int, int, pci_intr_handle_t *)); +const char *mpc_intr_string __P((void *, pci_intr_handle_t)); +void *mpc_intr_establish __P((void *, pci_intr_handle_t, + int, int (*func)(void *), void *, char *)); +void mpc_intr_disestablish __P((void *, void *)); +int mpc_ether_hw_addr __P((struct ppc_pci_chipset *, u_int8_t *)); + +struct cfattach mpcpcibr_ca = { + sizeof(struct pcibr_softc), mpcpcibrmatch, mpcpcibrattach, +}; + +struct cfdriver mpcpcibr_cd = { + NULL, "mpcpcibr", DV_DULL, +}; + +static int mpcpcibrprint __P((void *, const char *pnp)); + +struct pcibr_config mpc_config; + +/* + * config types + * bit meanings + * 0 - standard cf8/cfc type configurations, + * sometimes the base addresses for these are different + * 1 - Config Method #2 configuration - uni-north + * + * 2 - 64 bit config bus, data for accesses &4 is at daddr+4; + */ + +struct powerpc_bus_dma_tag pci_bus_dma_tag = { + NULL, + _dmamap_create, + _dmamap_destroy, + _dmamap_load, + _dmamap_load_mbuf, + _dmamap_load_uio, + _dmamap_load_raw, + _dmamap_unload, + _dmamap_sync, + _dmamem_alloc, + _dmamem_free, + _dmamem_map, + _dmamem_unmap, + _dmamem_mmap +}; + +int +mpcpcibrmatch(parent, match, aux) + struct device *parent; + void *match, *aux; +{ + struct confargs *ca = aux; + int handle; + int found = 0; + int err; + unsigned int val; + int qhandle; + char type[32]; + + if (strcmp(ca->ca_name, mpcpcibr_cd.cd_name) != 0) + return (found); + + found = 1; + + return found; +} + +int pci_map_a = 0; +void +mpcpcibrattach(parent, self, aux) + struct device *parent, *self; + void *aux; +{ + struct pcibr_softc *sc = (struct pcibr_softc *)self; + struct confargs *ca = aux; + struct pcibr_config *lcp; + struct pcibus_attach_args pba; + int map, node; + char *bridge; + int of_node = 0; + + lcp = sc->sc_pcibr = &mpc_config; + + addbatmap(RAVEN_V_PCI_MEM_SPACE, RAVEN_P_PCI_MEM_SPACE, BAT_I); + + sc->sc_membus_space.bus_base = RAVEN_V_PCI_MEM_SPACE; + sc->sc_membus_space.bus_reverse = 1; + sc->sc_iobus_space.bus_base = RAVEN_V_PCI_IO_SPACE; + sc->sc_iobus_space.bus_reverse = 1; + + lcp->lc_pc.pc_conf_v = lcp; + lcp->lc_pc.pc_attach_hook = mpc_attach_hook; + lcp->lc_pc.pc_bus_maxdevs = mpc_bus_maxdevs; + lcp->lc_pc.pc_make_tag = mpc_make_tag; + lcp->lc_pc.pc_decompose_tag = mpc_decompose_tag; + lcp->lc_pc.pc_conf_read = mpc_conf_read; + lcp->lc_pc.pc_conf_write = mpc_conf_write; + lcp->lc_pc.pc_ether_hw_addr = mpc_ether_hw_addr; + lcp->lc_iot = &sc->sc_iobus_space; + lcp->lc_memt = &sc->sc_membus_space; + + lcp->ioh_cf8 = PREP_CONFIG_ADD; + lcp->ioh_cfc = PREP_CONFIG_DAT; + + lcp->config_type = 0; + + lcp->lc_pc.pc_intr_v = lcp; + lcp->lc_pc.pc_intr_map = mpc_intr_map; + lcp->lc_pc.pc_intr_string = mpc_intr_string; + lcp->lc_pc.pc_intr_establish = mpc_intr_establish; + lcp->lc_pc.pc_intr_disestablish = mpc_intr_disestablish; + + printf(": RAVEN, Revision 0x%x.\n", + mpc_cfg_read_1(lcp, RAVEN_PCI_REVID)); + bridge = "RAVEN"; + pba.pba_dmat = &pci_bus_dma_tag; + + pba.pba_busname = "pci"; + pba.pba_iot = &sc->sc_iobus_space; + pba.pba_memt = &sc->sc_membus_space; + pba.pba_pc = &lcp->lc_pc; + pba.pba_bus = 0; + pba.pba_flags = PCI_FLAGS_MEM_ENABLED | PCI_FLAGS_IO_ENABLED; + /* set mem and io base addresses */ + mpc_cfg_write_4(lcp, RAVEN_PCI_MEM, RAVEN_P_PCI_MEM_SPACE); + mpc_cfg_write_4(lcp, RAVEN_PCI_IO, RAVEN_P_PCI_IO_SPACE); + /* enable mem and io mapping, and bus master */ + mpc_cfg_write_2(lcp, RAVEN_PCI_CMD, + RAVEN_CMD_IOSP|RAVEN_CMD_MEMSP|RAVEN_CMD_MASTR); + + config_found(self, &pba, mpcpcibrprint); +} + +static int +mpcpcibrprint(aux, pnp) + void *aux; + const char *pnp; +{ + struct pcibus_attach_args *pba = aux; + + if(pnp) + printf("%s at %s", pba->pba_busname, pnp); + printf(" bus %d", pba->pba_bus); + return(UNCONF); +} + +/* + * Get PCI physical address from given viritual address. + * XXX Note that cross page boundarys are *not* garantueed to work! + */ + +vm_offset_t +vtophys(p) + void *p; +{ + vm_offset_t pa; + vm_offset_t va; + + va = (vm_offset_t)p; + if((vm_offset_t)va < VM_MIN_KERNEL_ADDRESS) { + pa = va; + } + else { + pa = pmap_extract(vm_map_pmap(phys_map), va); + } + return(pa | ((pci_map_a == 1) ? RAVEN_PCI_CPUMEM : 0 )); +} + +void +mpc_attach_hook(parent, self, pba) + struct device *parent, *self; + struct pcibus_attach_args *pba; +{ +} + +int +mpc_ether_hw_addr(p, ethaddr) + struct ppc_pci_chipset *p; + u_int8_t *ethaddr; +{ + printf("mpc_ether_hw_addr not supported\n"); + return(0); +} + +int +mpc_bus_maxdevs(cpv, busno) + void *cpv; + int busno; +{ + return(32); +} + +#define BUS_SHIFT 16 +#define DEVICE_SHIFT 11 +#define FNC_SHIFT 8 + +pcitag_t +mpc_make_tag(cpv, bus, dev, fnc) + void *cpv; + int bus, dev, fnc; +{ + return (bus << BUS_SHIFT) | (dev << DEVICE_SHIFT) | (fnc << FNC_SHIFT); +} + +void +mpc_decompose_tag(cpv, tag, busp, devp, fncp) + void *cpv; + pcitag_t tag; + int *busp, *devp, *fncp; +{ + if (busp != NULL) + *busp = (tag >> BUS_SHIFT) & 0xff; + if (devp != NULL) + *devp = (tag >> DEVICE_SHIFT) & 0x1f; + if (fncp != NULL) + *fncp = (tag >> FNC_SHIFT) & 0x7; +} + +static u_int32_t +mpc_gen_config_reg(cpv, tag, offset) + void *cpv; + pcitag_t tag; + int offset; +{ + struct pcibr_config *cp = cpv; + unsigned int bus, dev, fcn; + u_int32_t reg; + /* + static int spin = 0; + while (spin > 85); + spin++; + */ + + mpc_decompose_tag(cpv, tag, &bus, &dev, &fcn); + + if (cp->config_type & 1) { + /* Config Mechanism #2 */ + if (bus == 0) { + if (dev < 11) { + return 0xffffffff; + } + /* + * Need to do config type 0 operation + * 1 << (11?+dev) | fcn << 8 | reg + * 11? is because pci spec states + * that 11-15 is reserved. + */ + reg = 1 << (dev) | fcn << 8 | offset; + + } else { + if (dev > 15) { + return 0xffffffff; + } + /* + * config type 1 + */ + reg = tag | offset | 1; + + } + } else { + /* config mechanism #2, type 0 + /* standard cf8/cfc config */ + reg = 0x80000000 | tag | offset; + + } + return reg; +} + +/*#define DEBUG_CONFIG */ +pcireg_t +mpc_conf_read(cpv, tag, offset) + void *cpv; + pcitag_t tag; + int offset; +{ + struct pcibr_config *cp = cpv; + + pcireg_t data; + u_int32_t reg; + int device; + int s; + int handle; + int daddr = 0; + + if(offset & 3 || offset < 0 || offset >= 0x100) { + printf ("pci_conf_read: bad reg %x\n", offset); + return(~0); + } + + reg = mpc_gen_config_reg(cpv, tag, offset); + /* if invalid tag, return -1 */ + if (reg == 0xffffffff) { + return 0xffffffff; + } + + if ((cp->config_type & 2) && (offset & 0x04)) { + daddr += 4; + } + + s = splhigh(); + + bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, reg); + bus_space_read_4(cp->lc_iot, cp->ioh_cf8, 0); /* XXX */ + data = bus_space_read_4(cp->lc_iot, cp->ioh_cfc, daddr); + bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, 0); /* disable */ + bus_space_read_4(cp->lc_iot, cp->ioh_cf8, 0); /* XXX */ + + splx(s); +#ifdef DEBUG_CONFIG + if (!((offset == 0) && (data == 0xffffffff))) { + unsigned int bus, dev, fcn; + mpc_decompose_tag(cpv, tag, &bus, &dev, &fcn); + printf("mpc_conf_read bus %x dev %x fcn %x offset %x", bus, dev, fcn, + offset); + printf(" daddr %x reg %x",daddr, reg); + printf(" data %x\n", data); + } +#endif + + return(data); +} + +void +mpc_conf_write(cpv, tag, offset, data) + void *cpv; + pcitag_t tag; + int offset; + pcireg_t data; +{ + struct pcibr_config *cp = cpv; + u_int32_t reg; + int s; + int handle; + int daddr = 0; + + reg = mpc_gen_config_reg(cpv, tag, offset); + + /* if invalid tag, return ??? */ + if (reg == 0xffffffff) { + return; + } + if ((cp->config_type & 2) && (offset & 0x04)) { + daddr += 4; + } +#ifdef DEBUG_CONFIG + { + unsigned int bus, dev, fcn; + mpc_decompose_tag(cpv, tag, &bus, &dev, &fcn); + printf("mpc_conf_write bus %x dev %x fcn %x offset %x", bus, + dev, fcn, offset); + printf(" daddr %x reg %x",daddr, reg); + printf(" data %x\n", data); + } +#endif + + s = splhigh(); + + bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, reg); + bus_space_read_4(cp->lc_iot, cp->ioh_cf8, 0); /* XXX */ + bus_space_write_4(cp->lc_iot, cp->ioh_cfc, daddr, data); + bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, 0); /* disable */ + bus_space_read_4(cp->lc_iot, cp->ioh_cf8, 0); /* XXX */ + + splx(s); +} + + +int +mpc_intr_map(lcv, bustag, buspin, line, ihp) + void *lcv; + pcitag_t bustag; + int buspin, line; + pci_intr_handle_t *ihp; +{ + struct pcibr_config *lcp = lcv; + pci_chipset_tag_t pc = &lcp->lc_pc; + int error = 0; + int route; + int lvl; + int device; + + *ihp = -1; + if (buspin == 0) { + /* No IRQ used. */ + error = 1; + } + else if (buspin > 4) { + printf("mpc_intr_map: bad interrupt pin %d\n", buspin); + error = 1; + } + + if(!error) + *ihp = line; + return error; +} + +const char * +mpc_intr_string(lcv, ih) + void *lcv; + pci_intr_handle_t ih; +{ + static char str[16]; + + sprintf(str, "irq %d", ih); + return(str); +} + +typedef void *(intr_establish_t) __P((void *, pci_intr_handle_t, + int, int, int (*func)(void *), void *, char *)); +typedef void (intr_disestablish_t) __P((void *, void *)); +extern intr_establish_t *intr_establish_func; +extern intr_disestablish_t *intr_disestablish_func; + +void * +mpc_intr_establish(lcv, ih, level, func, arg, name) + void *lcv; + pci_intr_handle_t ih; + int level; + int (*func) __P((void *)); + void *arg; + char *name; +{ + return (*intr_establish_func)(lcv, ih, IST_LEVEL, level, func, arg, + name); +} + +void +mpc_intr_disestablish(lcv, cookie) + void *lcv, *cookie; +{ + /* XXX We should probably do something clever here.... later */ +} + +u_int32_t +pci_iack() +{ + /* do pci IACK cycle */ + /* this should be bus allocated. */ + volatile u_int8_t *iack = (u_int8_t *)RAVEN_PIACK; + u_int8_t val; + + val = *iack; + return val; +} + +void +mpc_cfg_write_1(cp, reg, val) + struct pcibr_config *cp; + u_int32_t reg; + u_int8_t val; +{ + int s; + s = splhigh(); + bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, + RAVEN_REGOFFS(reg)); + bus_space_write_1(cp->lc_iot, cp->ioh_cfc, 0, val); + splx(s); +} + +void +mpc_cfg_write_2(cp, reg, val) + struct pcibr_config *cp; + u_int32_t reg; + u_int16_t val; +{ + int s; + s = splhigh(); + bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, RAVEN_REGOFFS(reg)); + bus_space_write_2(cp->lc_iot, cp->ioh_cfc, 0, val); + splx(s); +} + +void +mpc_cfg_write_4(cp, reg, val) + struct pcibr_config *cp; + u_int32_t reg; + u_int32_t val; +{ + + int s; + s = splhigh(); + bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, RAVEN_REGOFFS(reg)); + bus_space_write_4(cp->lc_iot, cp->ioh_cfc, 0, val); + splx(s); +} + +u_int8_t +mpc_cfg_read_1(cp, reg) + struct pcibr_config *cp; + u_int32_t reg; +{ + u_int8_t _v_; + + int s; + s = splhigh(); + bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, RAVEN_REGOFFS(reg)); + _v_ = bus_space_read_1(cp->lc_iot, cp->ioh_cfc, 0); + splx(s); + return(_v_); +} + +u_int16_t +mpc_cfg_read_2(cp, reg) + struct pcibr_config *cp; + u_int32_t reg; +{ + u_int16_t _v_; + + int s; + s = splhigh(); + bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, RAVEN_REGOFFS(reg)); + _v_ = bus_space_read_2(cp->lc_iot, cp->ioh_cfc, 0); + splx(s); + return(_v_); +} + +u_int32_t +mpc_cfg_read_4(cp, reg) + struct pcibr_config *cp; + u_int32_t reg; +{ + u_int32_t _v_; + + int s; + s = splhigh(); + bus_space_write_4(cp->lc_iot, cp->ioh_cf8, 0, RAVEN_REGOFFS(reg)); + _v_ = bus_space_read_4(cp->lc_iot, cp->ioh_cfc, 0); + splx(s); + return(_v_); +} diff --git a/sys/arch/mvmeppc/stand/Makefile b/sys/arch/mvmeppc/stand/Makefile new file mode 100644 index 00000000000..e88a919c8ab --- /dev/null +++ b/sys/arch/mvmeppc/stand/Makefile @@ -0,0 +1,10 @@ +# $OpenBSD: Makefile,v 1.1 2001/06/26 21:57:58 smurph Exp $ +#.if ${MACHINE} == "mvmeppc" + +SUBDIR= bugcrt libbug libsa libz bootsd bootxx bootst tftpboot +#sboot XXX future +#.endif + +SUBDIR+=installboot + +.include <bsd.subdir.mk> diff --git a/sys/arch/mvmeppc/stand/Makefile.inc b/sys/arch/mvmeppc/stand/Makefile.inc new file mode 100644 index 00000000000..5404d746abb --- /dev/null +++ b/sys/arch/mvmeppc/stand/Makefile.inc @@ -0,0 +1,10 @@ +# $OpenBSD: Makefile.inc,v 1.1 2001/06/26 21:57:58 smurph Exp $ + +MDEC_DIR?=/usr/mdec + +# Load addresses for first and second stage bootstraps +STAGE1_RELOC=4000 +STAGE2_RELOC=6000 +STAGE3_RELOC=6000 + + diff --git a/sys/arch/mvmeppc/stand/bootsd/Makefile b/sys/arch/mvmeppc/stand/bootsd/Makefile new file mode 100644 index 00000000000..158ce346fe2 --- /dev/null +++ b/sys/arch/mvmeppc/stand/bootsd/Makefile @@ -0,0 +1,36 @@ +# from: @(#)Makefile 8.1 (Berkeley) 6/10/93 +# $OpenBSD: Makefile,v 1.1 2001/06/26 21:57:59 smurph Exp $ + + +S= ${.CURDIR}/../../../.. +DEFS= +INCPATH=-I${.CURDIR} -I${.CURDIR}/../libsa -I${.CURDIR}/../libbug \ + -I${.CURDIR}/../../include -I${S} -I${S}/lib/libsa +CFLAGS=-O0 ${INCPATH} ${DEFS} ${COPTS} +LDFLAGS=-N -Ttext ${STAGE2_RELOC} +CLEANFILES+=bootsd + +.include "${S}/arch/mvmeppc/stand/bugcrt/Makefile.inc" +.include "${S}/arch/mvmeppc/stand/libbug/Makefile.inc" +.include "${S}/arch/mvmeppc/stand/libsa/Makefile.inc" +.include "${S}/arch/mvmeppc/stand/libz/Makefile.inc" + +SRCS= boot.c version.c + +LIBS= ${LIBSA} ${LIBBUG} ${LIBZ} ${LIBGCC} + +OBJS= ${SRCS:N*.h:R:S/$/.o/g} + +BOOTS= bootsd +ALL= ${BOOTS} + +all: ${ALL} + +bootsd: ${OBJS} ${STAGE2} ${LIBS} + ${LD} ${LDFLAGS} -o $@ \ + ${STAGE2} ${OBJS} ${LIBS} + +install: + install -c -m 555 -g bin -o bin ${BOOTS} ${DESTDIR}${MDEC_DIR} + +.include <bsd.prog.mk> diff --git a/sys/arch/mvmeppc/stand/bootsd/README b/sys/arch/mvmeppc/stand/bootsd/README new file mode 100644 index 00000000000..47a7aab2813 --- /dev/null +++ b/sys/arch/mvmeppc/stand/bootsd/README @@ -0,0 +1,7 @@ +In short: + cd /usr/mdec + cp bootsd / + ./installboot -v /bootsd ./bootxx /dev/rsd0a + + (you will need to be single user to run installboot since it writes + to a raw disk device) diff --git a/sys/arch/mvmeppc/stand/bootsd/boot.c b/sys/arch/mvmeppc/stand/bootsd/boot.c new file mode 100644 index 00000000000..6feb4224273 --- /dev/null +++ b/sys/arch/mvmeppc/stand/bootsd/boot.c @@ -0,0 +1,94 @@ +/* $OpenBSD: boot.c,v 1.1 2001/06/26 21:57:59 smurph Exp $ */ +/* $NetBSD: boot.c,v 1.2 1995/09/23 03:42:52 gwr Exp $ */ + +/*- + * Copyright (c) 1982, 1986, 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. 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, Berkeley and its contributors. + * 4. 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. + * + * @(#)boot.c 8.1 (Berkeley) 6/10/93 + */ + +#include <sys/param.h> +#include <sys/reboot.h> + +#include <machine/prom.h> + +#include "stand.h" +#include "libsa.h" + +#define RB_NOSYM 0x400 +#define RB_MULTI 0x4000 +#define RB_EXTRA 0x8000 +#define RB_ASKKERN 0x0010 /* ask kernel name */ + +int debug; +int errno; +extern char *version; +char line[80]; + +int +main() +{ + char *cp, *file; + int io, flag, ret; + int ask = 0; + + bootdev_type = BUGDEV_DISK; + + printf("\n>> OpenBSD/mvme88k bootsd [%s]\n", version); + + ret = parse_args(&file, &flag); + if (flag & RB_ASKKERN) { + ask = 1; + } + for (;;) { + if (ask) { + printf("boot: "); + gets(line); + if (line[0]) { + bugargs.arg_start = line; + cp = line; + while (cp < (line + sizeof(line) -1) && *cp) + cp++; + bugargs.arg_end = cp; + ret = parse_args(&file, &flag); + } + } + if (ret) { + printf("boot: -q returning to MVME-Bug\n"); + break; + } + exec_mvme(file, flag); + printf("boot: %s: %s\n", file, strerror(errno)); + ask = 1; + } + return (0); +} diff --git a/sys/arch/mvmeppc/stand/bootsd/version.c b/sys/arch/mvmeppc/stand/bootsd/version.c new file mode 100644 index 00000000000..7162d459350 --- /dev/null +++ b/sys/arch/mvmeppc/stand/bootsd/version.c @@ -0,0 +1,8 @@ +/* $OpenBSD: version.c,v 1.1 2001/06/26 21:57:59 smurph Exp $ */ + +/* + * make a random change to this file when you want the bootblock + * revision to increase. like change this q to an x, or something. + */ + +char *version = "$Revision: 1.1 $"; diff --git a/sys/arch/mvmeppc/stand/bootst/Makefile b/sys/arch/mvmeppc/stand/bootst/Makefile new file mode 100644 index 00000000000..15b6465861c --- /dev/null +++ b/sys/arch/mvmeppc/stand/bootst/Makefile @@ -0,0 +1,38 @@ +# from: @(#)Makefile 8.1 (Berkeley) 6/10/93 +# $OpenBSD: Makefile,v 1.1 2001/06/26 21:58:00 smurph Exp $ + +SIZE?= size + +S= ${.CURDIR}/../../../.. +DEFS= -DSTANDALONE -DCOMPAT_NOLABEL +INCPATH=-I${.CURDIR} -I${.CURDIR}/../libsa -I${.CURDIR}/../libbug \ + -I${.CURDIR}/../../include -I${S} -I${S}/lib/libsa +CFLAGS=-O0 ${INCPATH} ${DEFS} ${COPTS} +LDFLAGS=-s -N -Ttext ${STAGE2_RELOC} +CLEANFILES+=stboot bootst bootst.bug + +#.include "${S}/arch/mvme88k/stand/wrtvid/Makefile.inc" +.include "${S}/arch/mvmeppc/stand/bugcrt/Makefile.inc" +.include "${S}/arch/mvmeppc/stand/libbug/Makefile.inc" +.include "${S}/arch/mvmeppc/stand/libsa/Makefile.inc" +.include "${S}/arch/mvmeppc/stand/libz/Makefile.inc" + +SRCS= boot.c version.c + +LIBS= ${LIBSA} ${LIBBUG} ${LIBZ} + +OBJS= ${SRCS:N*.h:R:S/$/.o/g} + +BOOTS= bootst +ALL= ${BOOTS} + +all: ${ALL} + +bootst: ${OBJS} ${SINGLE} ${LIBS} + ${LD} ${LDFLAGS} ${SINGLE} ${OBJS} ${LIBS} -o $@ + @${SIZE} $@ + +install: + install -c -m 555 -g bin -o bin ${BOOTS} ${DESTDIR}${MDEC_DIR} + +.include <bsd.prog.mk> diff --git a/sys/arch/mvmeppc/stand/bootst/boot.c b/sys/arch/mvmeppc/stand/bootst/boot.c new file mode 100644 index 00000000000..1db477b2abf --- /dev/null +++ b/sys/arch/mvmeppc/stand/bootst/boot.c @@ -0,0 +1,76 @@ +/* $OpenBSD: boot.c,v 1.1 2001/06/26 21:58:00 smurph Exp $ */ +/*- + * Changes Copyright (c) 1998 steve Murphree, Jr. + * Copyright (c) 1982, 1986, 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. 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, Berkeley and its contributors. + * 4. 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. + * + * @(#)boot.c 8.1 (Berkeley) 6/10/93 + */ + +#include <sys/param.h> +#include <sys/reboot.h> +#include <machine/prom.h> + +#include "stand.h" +#include "libsa.h" + +#define LOADADDR 0x10000 + +extern char *version; +extern int errno; + +int main() +{ + static char dnm[32] = "2"; + char line[80]; + char *cp, *filename; + int bflag = 0; + + bootdev_type = BUGDEV_TAPE; + + printf(">> OpenBSD/mvme88k tapeboot [%s]\n", version); + + *bugargs.arg_end = 0; /* ensure */ + parse_args(&filename, &bflag); + filename = dnm; /* override */ + + if (bflag & RB_ASKNAME) { + printf("tapeboot: segment? [%s] ", dnm); + gets(line); + if (line[0]) + filename = line; + } + + exec_mvme(filename, bflag); + + printf("tapeboot: %s: %s\n", filename, strerror(errno)); + return(0); +} diff --git a/sys/arch/mvmeppc/stand/bootst/version.c b/sys/arch/mvmeppc/stand/bootst/version.c new file mode 100644 index 00000000000..0ebfccf685d --- /dev/null +++ b/sys/arch/mvmeppc/stand/bootst/version.c @@ -0,0 +1,8 @@ +/* $OpenBSD: version.c,v 1.1 2001/06/26 21:58:00 smurph Exp $ */ + +/* + * make a random change to this file when you want the bootblock + * revision to increase. like change this x to an q, or something. + */ + +char *version = "$Revision: 1.1 $"; diff --git a/sys/arch/mvmeppc/stand/bootxx/Makefile b/sys/arch/mvmeppc/stand/bootxx/Makefile new file mode 100644 index 00000000000..1f5fdf5af01 --- /dev/null +++ b/sys/arch/mvmeppc/stand/bootxx/Makefile @@ -0,0 +1,33 @@ +# from: @(#)Makefile 8.1 (Berkeley) 6/10/93 +# $OpenBSD: Makefile,v 1.1 2001/06/26 21:58:01 smurph Exp $ + +S= ${.CURDIR}/../../../.. +DEFS=-DSTAGE2_RELOC=${STAGE2_RELOC} +INCPATH=-I${.CURDIR} -I${.CURDIR}/../libsa -I${.CURDIR}/../libbug \ + -I${.CURDIR}/../../include -I${S} -I${S}/lib/libsa +CFLAGS=-O0 ${INCPATH} ${DEFS} ${COPTS} +CLEANFILES+=bootxx + +.include "${S}/arch/mvmeppc/stand/bugcrt/Makefile.inc" +.include "${S}/arch/mvmeppc/stand/libbug/Makefile.inc" +.include "${S}/arch/mvmeppc/stand/libsa/Makefile.inc" +.include "${S}/arch/mvmeppc/stand/libz/Makefile.inc" + +SRCS= bootxx.c version.c + +LIBS= ${LIBSA} ${LIBBUG} ${LIBZ} ${LIBGCC} + +OBJS= ${SRCS:N*.h:R:S/$/.o/g} + +BOOTS= bootxx +ALL= ${BOOTS} + +all: ${ALL} + +bootxx: ${OBJS} ${STAGE1} ${LIBS} + ${LD} -X -N -Ttext ${STAGE1_RELOC} ${STAGE1} ${OBJS} ${LIBS} -o $@ + +install: + install -c -m 555 -g bin -o bin ${BOOTS} ${DESTDIR}${MDEC_DIR} + +.include <bsd.prog.mk> diff --git a/sys/arch/mvmeppc/stand/bootxx/bootxx.c b/sys/arch/mvmeppc/stand/bootxx/bootxx.c new file mode 100644 index 00000000000..451ae40de97 --- /dev/null +++ b/sys/arch/mvmeppc/stand/bootxx/bootxx.c @@ -0,0 +1,142 @@ +/* $OpenBSD: bootxx.c,v 1.1 2001/06/26 21:58:01 smurph Exp $ */ + +/* + * Copyright (c) 1994 Paul Kranenburg + * 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 Paul Kranenburg. + * 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. + */ + +/* + * This is a generic "first-stage" boot program. + * + * Note that this program has absolutely no filesystem knowledge! + * + * Instead, this uses a table of disk block numbers that are + * filled in by the installboot program such that this program + * can load the "second-stage" boot program. + */ + +#include <sys/param.h> +#include <sys/time.h> +#include <sys/exec.h> +#include <machine/prom.h> + +#include "stand.h" +#include "libsa.h" + +/* + * Boot device is derived from ROM provided information. + */ + +/* This determines the largest boot program we can load. */ +#define MAXBLOCKNUM 64 + +/* + * These three names are known by installboot. + * The block_table contains starting block numbers, + * in terms of 512-byte blocks. Each non-zero value + * will result in a read of block_size bytes. + */ +int block_size = 512; /* default */ +int block_count = MAXBLOCKNUM; /* length of table */ +daddr_t block_table[MAXBLOCKNUM] = { 0 }; + +extern char *version; + + +main() +{ + struct open_file f; + char *addr; + int n, error; + + bootdev_type = BUGDEV_DISK; + + printf("Boot: bug device: ctrl=%d, dev=%d\n", + bugargs.ctrl_lun, bugargs.dev_lun); + printf("\nbootxx: first level bootstrap program [%s]\n\n", version); + + f.f_flags = F_RAW; + if (devopen(&f, 0, &addr)) { + printf("bootxx: open failed\n"); + _rtt(); + } + + addr = (char*)STAGE2_RELOC; + error = copyboot(&f, addr); + f.f_dev->dv_close(&f); + if (!error) { + bugexec((void (*)())addr); + } + /* copyboot had a problem... */ + _rtt(); +} + +int +copyboot(fp, addr) + struct open_file *fp; + char *addr; +{ + int n, i, blknum; + struct exec *x; + + addr -= sizeof(struct exec); /* assume OMAGIC, verify below */ + x = (struct exec *)addr; + + if (!block_count) { + printf("bootxx: no data!?!\n"); + return -1; + } + + for (i = 0; i < block_count; i++) { + + if ((blknum = block_table[i]) == 0) + break; + +#ifdef DEBUG + printf("bootxx: read block # %d = %d\n", i, blknum); +#endif + if ((fp->f_dev->dv_strategy)(fp->f_devdata, F_READ, + blknum, block_size, addr, &n)) + { + printf("bootxx: read failed\n"); + return -1; + } + if (n != block_size) { + printf("bootxx: short read\n"); + return -1; + } + addr += block_size; + } + + if (N_GETMAGIC(*x) != OMAGIC) { + printf("bootxx: secondary bootstrap isn't in OMAGIC format\n"); + return(-1); + } + + return 0; +} diff --git a/sys/arch/mvmeppc/stand/bootxx/version.c b/sys/arch/mvmeppc/stand/bootxx/version.c new file mode 100644 index 00000000000..1dca3531fee --- /dev/null +++ b/sys/arch/mvmeppc/stand/bootxx/version.c @@ -0,0 +1,8 @@ +/* $OpenBSD: version.c,v 1.1 2001/06/26 21:58:01 smurph Exp $ */ + +/* + * make a random change to this file when you want the bootblock + * revision to increase. like change this y to an x, or something. + */ + +char *version = "$Revision: 1.1 $"; diff --git a/sys/arch/mvmeppc/stand/bugcrt/Makefile b/sys/arch/mvmeppc/stand/bugcrt/Makefile new file mode 100644 index 00000000000..4ebcfc372ae --- /dev/null +++ b/sys/arch/mvmeppc/stand/bugcrt/Makefile @@ -0,0 +1,38 @@ +# $OpenBSD: Makefile,v 1.1 2001/06/26 21:58:02 smurph Exp $ +# +# DO NOT OPTMIZE bugcrt (i.e. no "-O2") +# +S=${.CURDIR}/../../../.. + +CFLAGS=-I${.CURDIR}/../../include -I${.CURDIR}/../libbug -I${S}/lib/libsa \ + -fomit-frame-pointer -save-temps +STAGE1_CFLAGS=-DSTACK_ASM_OP="\".long ${STAGE1_RELOC}\"" -DSTAGE1 +STAGE2_CFLAGS=-DSTACK_ASM_OP="\".long ${STAGE2_RELOC}\"" +SINGLE_CFLAGS=-DSTACK_ASM_OP="\".long ${STAGE2_RELOC}\"" -DSTAGE1 +SRCS=crt.c +OBJS=stage1crt.o stage2crt.o singlecrt.o + +CLEANFILES+=a.out ${OBJS} *.i *.s + +all: ${OBJS} + +stage1crt.o: crt.c + ${CC} ${CFLAGS} ${STAGE1_CFLAGS} -c ${.CURDIR}/crt.c -o ${.TARGET} + ${LD} -x -r ${.TARGET} + mv a.out ${.TARGET} + +stage2crt.o: crt.c + ${CC} ${CFLAGS} ${STAGE2_CFLAGS} -c ${.CURDIR}/crt.c -o ${.TARGET} + ${LD} -x -r ${.TARGET} + mv a.out ${.TARGET} + +singlecrt.o: crt.c + ${CC} ${CFLAGS} ${SINGLE_CFLAGS} -c ${.CURDIR}/crt.c -o ${.TARGET} + ${LD} -x -r ${.TARGET} + mv a.out ${.TARGET} + +install: + +lint tags: + +.include <bsd.prog.mk> diff --git a/sys/arch/mvmeppc/stand/bugcrt/Makefile.inc b/sys/arch/mvmeppc/stand/bugcrt/Makefile.inc new file mode 100644 index 00000000000..38be2b62f90 --- /dev/null +++ b/sys/arch/mvmeppc/stand/bugcrt/Makefile.inc @@ -0,0 +1,24 @@ +# $OpenBSD: Makefile.inc,v 1.1 2001/06/26 21:58:02 smurph Exp $ + +BUG_CRT_DIR=${S}/arch/mvmeppc/stand/bugcrt + +BUGCRT_DIR!= cd ${BUG_CRT_DIR}; \ + printf "xxx:\n\techo \$${.OBJDIR}\n" | ${MAKE} -r -s -f - xxx + +STAGE1=${BUGCRT_DIR}/stage1crt.o +STAGE2=${BUGCRT_DIR}/stage2crt.o +SINGLE=${BUGCRT_DIR}/singlecrt.o + +$(STAGE1): .NOTMAIN __always_make_bugcrt + @echo making sure the stage1crt.o is up to date... + @(cd ${BUG_CRT_DIR}; ${MAKE} stage1crt.o) + +$(STAGE2): .NOTMAIN __always_make_bugcrt + @echo making sure the stage2crt.o is up to date... + @(cd ${BUG_CRT_DIR}; ${MAKE} stage2crt.o) + +$(SINGLE): .NOTMAIN __always_make_bugcrt + @echo making sure the singlecrt.o is up to date... + @(cd ${BUG_CRT_DIR}; ${MAKE} singlecrt.o) + +__always_make_bugcrt: .NOTMAIN diff --git a/sys/arch/mvmeppc/stand/bugcrt/bugcrt.c b/sys/arch/mvmeppc/stand/bugcrt/bugcrt.c new file mode 100644 index 00000000000..edb48124f98 --- /dev/null +++ b/sys/arch/mvmeppc/stand/bugcrt/bugcrt.c @@ -0,0 +1,126 @@ +/* $OpenBSD: bugcrt.c,v 1.1 2001/06/26 21:58:02 smurph Exp $ */ + +/* + * This is the startup file for single stage bootstraps or the first + * stage of a two stage bootstrap. It includes code to enable the + * SFU1. + */ + +#include <sys/types.h> +#include <machine/prom.h> + +struct mvmeprom_args bugargs = { 1}; /* not BSS */ + + asm (".text"); + /* pseudo reset vector */ + asm (STACK_ASM_OP); /* initial sp value */ + asm (".long _start"); /* initial ip value */ +start() +{ + register int dev_lun asm (MVMEPROM_REG_DEVLUN); + register int ctrl_lun asm (MVMEPROM_REG_CTRLLUN); + register int flags asm (MVMEPROM_REG_FLAGS); + register int ctrl_addr asm (MVMEPROM_REG_CTRLADDR); + register int entry asm (MVMEPROM_REG_ENTRY); + register int conf_blk asm (MVMEPROM_REG_CONFBLK); + register char *arg_start asm (MVMEPROM_REG_ARGSTART); + register char *arg_end asm (MVMEPROM_REG_ARGEND); + register char *nbarg_start asm (MVMEPROM_REG_NBARGSTART); + register char *nbarg_end asm (MVMEPROM_REG_NBARGEND); + extern int edata, end; + struct mvmeprom_brdid *id, *mvmeprom_brdid(); + +#ifdef STAGE1 + /* Do not use r10 to enable the SFU1. This wipes out + the netboot args. Not cool at all... r25 seems free. */ + asm("| enable SFU1"); + asm(" ldcr r25,cr1"); + asm(" xor r25,r25,0x8"); + asm(" stcr r25,cr1"); +#endif + + bugargs.dev_lun = dev_lun; + bugargs.ctrl_lun = ctrl_lun; + bugargs.flags = flags; + bugargs.ctrl_addr = ctrl_addr; + bugargs.entry = entry; + bugargs.conf_blk = conf_blk; + bugargs.arg_start = arg_start; + bugargs.arg_end = arg_end; + bugargs.nbarg_start = nbarg_start; + bugargs.nbarg_end = nbarg_end; + *bugargs.arg_end = 0; + + id = mvmeprom_brdid(); + bugargs.cputyp = id->model; + + /* + * Initialize PSR and CMMU to a known, stable state. + * This has to be done early for MVME197. + * Per EB162 mc88110 engineering bulletin. + */ + /* + if (bugargs.cputyp == 0x197) { + asm("| init MVME197"); + asm("| 1. PSR"); + asm("or.u r2,r0,0xA200"); + asm("or r2,r2,0x03E2"); + asm("stcr r2,cr1"); + asm("| 2. ICTL"); + asm("or r2,r0,r0"); + asm("or r2,r2,0x8000"); + asm("or r2,r2,0x0040"); + asm("stcr r2,cr26"); + asm("| 3. DCTL"); + asm("or r2,r0,r0"); + asm("or r2,r2,0x2000"); + asm("or r2,r2,0x0040"); + asm("stcr r2,cr41"); + asm("| 4. init cache"); + asm("or r2,r0,0x01"); + asm("stcr r2,cr25"); + asm("stcr r2,cr40"); + } + */ + memset(&edata, 0, ((int)&end - (int)&edata)); + + asm ("| main()"); + main(); + mvmeprom_return(); + /* NOTREACHED */ +} + +__main() +{ +} + +void +bugexec(addr) + +void (*addr)(); + +{ + register int dev_lun asm (MVMEPROM_REG_DEVLUN); + register int ctrl_lun asm (MVMEPROM_REG_CTRLLUN); + register int flags asm (MVMEPROM_REG_FLAGS); + register int ctrl_addr asm (MVMEPROM_REG_CTRLADDR); + register int entry asm (MVMEPROM_REG_ENTRY); + register int conf_blk asm (MVMEPROM_REG_CONFBLK); + register char *arg_start asm (MVMEPROM_REG_ARGSTART); + register char *arg_end asm (MVMEPROM_REG_ARGEND); + + dev_lun = bugargs.dev_lun; + ctrl_lun = bugargs.ctrl_lun; + flags = bugargs.flags; + ctrl_addr = bugargs.ctrl_addr; + entry = bugargs.entry; + conf_blk = bugargs.conf_blk; + arg_start = bugargs.arg_start; + arg_end = bugargs.arg_end; + + (*addr)(); + printf("bugexec: 0x%x returned!\n", addr); + + _rtt(); +} + diff --git a/sys/arch/mvmeppc/stand/bugcrt/crt.c b/sys/arch/mvmeppc/stand/bugcrt/crt.c new file mode 100644 index 00000000000..992a907a481 --- /dev/null +++ b/sys/arch/mvmeppc/stand/bugcrt/crt.c @@ -0,0 +1,125 @@ +/* $OpenBSD: crt.c,v 1.1 2001/06/26 21:58:02 smurph Exp $ */ + +#include <sys/types.h> +#include <machine/prom.h> + +struct mvmeprom_args bugargs = { 1}; /* not BSS */ + +/* pseudo reset vector */ +#if 0 +asm (".text"); +asm (STACK_ASM_OP); /* initial sp value */ +asm (".long _start"); /* initial ip value */ +#endif +_start() +{ + register int dev_lun asm (MVMEPROM_REG_DEVLUN); + register int ctrl_lun asm (MVMEPROM_REG_CTRLLUN); + register int flags asm (MVMEPROM_REG_SCSUPP); + register int ctrl_addr asm (MVMEPROM_REG_CTRLADDR); + register int entry asm (MVMEPROM_REG_ENTRY); + register int conf_blk asm (MVMEPROM_REG_IPA); + register char *arg_start asm (MVMEPROM_REG_ARGSTART); + register char *arg_end asm (MVMEPROM_REG_ARGEND); + register char *nbarg_start asm (MVMEPROM_REG_NBARGSTART); + register char *nbarg_end asm (MVMEPROM_REG_NBARGEND); + extern int edata, end; + struct mvmeprom_brdid *id, *mvmeprom_brdid(); + +#ifdef notyet + /* + * This code enables the SFU1 and is used for single stage + * bootstraps or the first stage of a two stage bootstrap. + * Do not use r10 to enable the SFU1. This wipes out + * the netboot args. Not cool at all... r25 seems free. + */ + asm("| enable SFU1"); + asm(" ldcr r25,cr1"); + asm(" clr r25,r25,1<3>"); /* bit 3 is SFU1D */ + asm(" stcr r25,cr1"); +#endif + bugargs.dev_lun = dev_lun; + bugargs.ctrl_lun = ctrl_lun; + bugargs.flags = flags; + bugargs.ctrl_addr = ctrl_addr; + bugargs.entry = entry; + bugargs.conf_blk = conf_blk; + bugargs.arg_start = arg_start; + bugargs.arg_end = arg_end; + bugargs.nbarg_start = nbarg_start; + bugargs.nbarg_end = nbarg_end; + *bugargs.arg_end = 0; + *bugargs.nbarg_end = 0; + + id = mvmeprom_brdid(); + bugargs.cputyp = id->model; + +#ifdef notyet /* STAGE1 */ + /* + * Initialize PSR and CMMU to a known, stable state. + * This has to be done early for MVME197. + * Per EB162 mc88110 engineering bulletin. + */ + if (bugargs.cputyp == 0x197) { + asm("| init MVME197"); + asm("| 1. PSR"); + asm("or.u r2,r0,0xA200"); + asm("or r2,r2,0x03E2"); + asm("stcr r2,cr1"); + asm("| 2. ICTL"); + asm("or r2,r0,r0"); + asm("or r2,r2,0x8000"); + asm("or r2,r2,0x0040"); + asm("stcr r2,cr26"); + asm("| 3. DCTL"); + asm("or r2,r0,r0"); + asm("or r2,r2,0x2000"); + asm("or r2,r2,0x0040"); + asm("stcr r2,cr41"); + asm("| 4. init cache"); + asm("or r2,r0,0x01"); + asm("stcr r2,cr25"); + asm("stcr r2,cr40"); + } +#endif + + memset(&edata, 0, ((int)&end - (int)&edata)); + + asm ("# main()"); + main(); + mvmeprom_return(); + /* NOTREACHED */ +} + +__main() +{ +} + +void +bugexec(addr) + void (*addr)(); +{ + register int dev_lun asm (MVMEPROM_REG_DEVLUN); + register int ctrl_lun asm (MVMEPROM_REG_CTRLLUN); + register int flags asm (MVMEPROM_REG_SCSUPP); + register int ctrl_addr asm (MVMEPROM_REG_CTRLADDR); + register int entry asm (MVMEPROM_REG_ENTRY); + register int conf_blk asm (MVMEPROM_REG_IPA); + register char *arg_start asm (MVMEPROM_REG_ARGSTART); + register char *arg_end asm (MVMEPROM_REG_ARGEND); + + dev_lun = bugargs.dev_lun; + ctrl_lun = bugargs.ctrl_lun; + flags = bugargs.flags; + ctrl_addr = bugargs.ctrl_addr; + entry = bugargs.entry; + conf_blk = bugargs.conf_blk; + arg_start = bugargs.arg_start; + arg_end = bugargs.arg_end; + + (*addr)(); + printf("bugexec: 0x%x returned!\n", addr); + + _rtt(); +} + diff --git a/sys/arch/mvmeppc/stand/bugcrt/sdcrt.c b/sys/arch/mvmeppc/stand/bugcrt/sdcrt.c new file mode 100644 index 00000000000..0476a421a59 --- /dev/null +++ b/sys/arch/mvmeppc/stand/bugcrt/sdcrt.c @@ -0,0 +1,87 @@ +/* $OpenBSD: sdcrt.c,v 1.1 2001/06/26 21:58:02 smurph Exp $ */ + +/* + * This is the startup file for the second stage bootstrap. (bootsd) + * It does *not* includes code to enable the SFU1. + */ + +#include <sys/types.h> +#include <machine/prom.h> + +struct mvmeprom_args bugargs = { 1 }; /* not BSS */ + + asm (".text"); + /* pseudo reset vector */ + asm (STACK_ASM_OP); /* initial sp value */ + asm (".long _start"); /* initial ip value */ +start() +{ + register int dev_lun asm (MVMEPROM_REG_DEVLUN); + register int ctrl_lun asm (MVMEPROM_REG_CTRLLUN); + register int flags asm (MVMEPROM_REG_FLAGS); + register int ctrl_addr asm (MVMEPROM_REG_CTRLADDR); + register int entry asm (MVMEPROM_REG_ENTRY); + register int conf_blk asm (MVMEPROM_REG_CONFBLK); + register char *arg_start asm (MVMEPROM_REG_ARGSTART); + register char *arg_end asm (MVMEPROM_REG_ARGEND); + register char *nbarg_start asm (MVMEPROM_REG_NBARGSTART); + register char *nbarg_end asm (MVMEPROM_REG_NBARGEND); + extern int edata, end; + struct mvmeprom_brdid *id, *mvmeprom_brdid(); + + bugargs.dev_lun = dev_lun; + bugargs.ctrl_lun = ctrl_lun; + bugargs.flags = flags; + bugargs.ctrl_addr = ctrl_addr; + bugargs.entry = entry; + bugargs.conf_blk = conf_blk; + bugargs.arg_start = arg_start; + bugargs.arg_end = arg_end; + bugargs.nbarg_start = nbarg_start; + bugargs.nbarg_end = nbarg_end; + *bugargs.arg_end = 0; + + memset(&edata, 0, ((int)&end - (int)&edata)); + + id = mvmeprom_brdid(); + bugargs.cputyp = id->model; + + main(); + mvmeprom_return(); + /* NOTREACHED */ +} + +__main() +{ +} + +void +bugexec(addr) + +void (*addr)(); + +{ + register int dev_lun asm (MVMEPROM_REG_DEVLUN); + register int ctrl_lun asm (MVMEPROM_REG_CTRLLUN); + register int flags asm (MVMEPROM_REG_FLAGS); + register int ctrl_addr asm (MVMEPROM_REG_CTRLADDR); + register int entry asm (MVMEPROM_REG_ENTRY); + register int conf_blk asm (MVMEPROM_REG_CONFBLK); + register char *arg_start asm (MVMEPROM_REG_ARGSTART); + register char *arg_end asm (MVMEPROM_REG_ARGEND); + + dev_lun = bugargs.dev_lun; + ctrl_lun = bugargs.ctrl_lun; + flags = bugargs.flags; + ctrl_addr = bugargs.ctrl_addr; + entry = bugargs.entry; + conf_blk = bugargs.conf_blk; + arg_start = bugargs.arg_start; + arg_end = bugargs.arg_end; + + (*addr)(); + printf("bugexec: 0x%x returned!\n", addr); + + _rtt(); +} + diff --git a/sys/arch/mvmeppc/stand/installboot/Makefile b/sys/arch/mvmeppc/stand/installboot/Makefile new file mode 100644 index 00000000000..d13f574cd03 --- /dev/null +++ b/sys/arch/mvmeppc/stand/installboot/Makefile @@ -0,0 +1,19 @@ +# $OpenBSD: Makefile,v 1.1 2001/06/26 21:58:03 smurph Exp $ + +.if ${MACHINE} == "mvmeppc" +PROG= installboot +MAN= installboot.8 +MANSUBDIR=/mvme88k + +BINDIR=/usr/mdec +DPADD=${LIBUTIL} +LDADD=-lutil +CFLAGS+=-O0 +# Need this to work in the miniroot +LDSTATIC=-static +.else +NOPROG= +.endif + +.include <bsd.prog.mk> + diff --git a/sys/arch/mvmeppc/stand/installboot/installboot.8 b/sys/arch/mvmeppc/stand/installboot/installboot.8 new file mode 100644 index 00000000000..38018126dda --- /dev/null +++ b/sys/arch/mvmeppc/stand/installboot/installboot.8 @@ -0,0 +1,65 @@ +.\" $OpenBSD: installboot.8,v 1.1 2001/06/26 21:58:03 smurph Exp $ +.\" +.Dd 31 May 1995 +.Dt INSTALLBOOT 8 mvme88k +.Os +.Sh NAME +.Nm installboot +.Nd install a bootstrap on a UFS disk +.Sh SYNOPSIS +.Nm installboot +.Op Fl n +.Op Fl v +.Ar bootsd +.Ar bootxx +.Ar rawdev +.Sh DESCRIPTION +.Nm installboot +is used to install a "first-stage" boot program into the boot area +of a UFS disk partition, and initialize the table of block numbers the +.Ar bootxx +program uses to load the second-stage boot program. +.Pp +The options are as follows: +.Bl -tag -width flag +.It Fl n +Do not actually write anything on the disk. +.It Fl v +Be verbose, printing out the block numbers that +.Ar bootxx +will use to load +.Ar bootsd . +.El +.Pp +The arguments are: +.Bl -tag -width bootsd +.It Ar bootsd +the name of the second-stage boot program in the file system +where the first-stage boot program is to be installed. +.It Ar bootxx +the name of the prototype file for the first stage boot program. +.It Ar rawdev +the name of the raw device in which the first-stage boot program +is to be installed. This should correspond to the block device +on which the file system containing +.Ar ufsboot +is mounted. +.El +.Sh EXAMPLE +.Bd -literal -offset +cd /usr/mdec +cp bootsd / +installboot -v /bootsd ./bootxx /dev/rsd0a +.Ed +.Sh BUGS +.Nm installboot +requires simultaneous access to the mounted file system and +the raw device, but that is not allowed with the kernel +.Nm securelevel +variable set to a value greater than zero (the default), so +.Nm installboot +only works in single-user mode (or insecure mode - see +.Xr init 8 ). +.Sh SEE ALSO +.Xr disklabel 8 , +.Xr init 8 diff --git a/sys/arch/mvmeppc/stand/installboot/installboot.c b/sys/arch/mvmeppc/stand/installboot/installboot.c new file mode 100644 index 00000000000..ad853175a69 --- /dev/null +++ b/sys/arch/mvmeppc/stand/installboot/installboot.c @@ -0,0 +1,474 @@ +/* $NetBSD: installboot.c,v 1.5 1995/11/17 23:23:50 gwr Exp $ */ + +/* + * Copyright (c) 1994 Paul Kranenburg + * 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 Paul Kranenburg. + * 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. + */ + +#include <sys/param.h> +#include <sys/mount.h> +#include <sys/time.h> +#include <sys/stat.h> +#include <ufs/ufs/dinode.h> +#include <ufs/ufs/dir.h> +#include <ufs/ffs/fs.h> +#include <err.h> +#include <a.out.h> +#include <fcntl.h> +#include <nlist.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <util.h> +#include <machine/disklabel.h> + +int verbose, nowrite, hflag; +char *boot, *proto, *dev; +char cdev[80]; + +struct nlist nl[] = { +#define X_BLOCK_SIZE 0 + {"_block_size"}, +#define X_BLOCK_COUNT 1 + {"_block_count"}, +#define X_BLOCK_TABLE 2 + {"_block_table"}, + {NULL} +}; + +int *block_size_p; /* block size var. in prototype image */ +int *block_count_p; /* block count var. in prototype image */ +daddr_t *block_table; /* block number array in prototype image */ +int maxblocknum; /* size of this array */ + + +char *loadprotoblocks __P((char *, long *)); +int loadblocknums __P((char *, int)); +static void devread __P((int, void *, daddr_t, size_t, char *)); +static void usage __P((void)); +int main __P((int, char *[])); +static void vid_to_disklabel __P((char *, char*)); + + +static void +usage() +{ + fprintf(stderr, + "usage: installboot [-n] [-v] [-h] <boot> <proto> <device>\n"); + exit(1); +} + +int +main(argc, argv) + int argc; + char *argv[]; +{ + int c; + int devfd; + char *protostore; + long protosize; + + while ((c = getopt(argc, argv, "vnh")) != -1) { + switch (c) { + case 'h': + /* Don't strip a.out header */ + hflag = 1; + break; + case 'n': + /* Do not actually write the bootblock to disk */ + nowrite = 1; + break; + case 'v': + /* Chat */ + verbose = 1; + break; + default: + usage(); + } + } + + if (argc - optind < 3) { + usage(); + } + + boot = argv[optind]; + proto = argv[optind + 1]; + dev = argv[optind + 2]; + strcpy(cdev, dev); + cdev[strlen(cdev)-1] = 'c'; + + if (verbose) { + printf("boot: %s\n", boot); + printf("proto: %s\n", proto); + printf("device: %s\n", dev); + printf("cdevice: %s\n", cdev); + } + + /* Insert VID into disklabel */ + vid_to_disklabel(cdev, proto); + + /* Load proto blocks into core */ + if ((protostore = loadprotoblocks(proto, &protosize)) == NULL) + exit(1); + + /* XXX - Paranoia: Make sure size is aligned! */ + if (protosize & (DEV_BSIZE - 1)) + err(1, "proto bootblock bad size=%d", protosize); + + /* Open and check raw disk device */ + if ((devfd = open(dev, O_RDONLY, 0)) < 0) + err(1, "open: %s", dev); + + /* Extract and load block numbers */ + if (loadblocknums(boot, devfd) != 0) + exit(1); + + (void)close(devfd); + + if (nowrite) + return 0; + + /* Write patched proto bootblocks into the superblock */ + if (protosize > SBSIZE - DEV_BSIZE) + errx(1, "proto bootblocks too big"); + + if ((devfd = open(cdev, O_RDWR, 0)) < 0) + err(1, "open: %s", dev); + + if (lseek(devfd, DEV_BSIZE, SEEK_SET) != DEV_BSIZE) + err(1, "lseek bootstrap"); + + /* Sync filesystems (to clean in-memory superblock?) */ + sync(); + + if (write(devfd, protostore, protosize) != protosize) + err(1, "write bootstrap"); + (void)close(devfd); + return 0; +} + +char * +loadprotoblocks(fname, size) + char *fname; + long *size; +{ + int fd; + size_t tdsize; /* text+data size */ + size_t bbsize; /* boot block size (block aligned) */ + char *bp; + struct nlist *nlp; + struct exec eh; + long off; + + fd = -1; + bp = NULL; + + /* Locate block number array in proto file */ + if (nlist(fname, nl) != 0) { + warnx("nlist: %s: symbols not found", fname); + return NULL; + } + /* Validate symbol types (global data). */ + for (nlp = nl; nlp->n_un.n_name; nlp++) { + if (nlp->n_type != (N_DATA | N_EXT)) { + warnx("nlist: %s: wrong type", nlp->n_un.n_name); + return NULL; + } + } + + if ((fd = open(fname, O_RDONLY)) < 0) { + warn("open: %s", fname); + return NULL; + } + if (read(fd, &eh, sizeof(eh)) != sizeof(eh)) { + warn("read: %s", fname); + goto bad; + } + if (N_GETMAGIC(eh) != OMAGIC) { + warn("bad magic: 0x%x", eh.a_midmag); + goto bad; + } + /* + * We have to include the exec header in the beginning of + * the buffer, and leave extra space at the end in case + * the actual write to disk wants to skip the header. + */ + tdsize = eh.a_text + eh.a_data; + bbsize = tdsize + sizeof(eh); + bbsize = roundup(bbsize, DEV_BSIZE); + + /* + * Allocate extra space here because the caller may copy + * the boot block starting at the end of the exec header. + * This prevents reading beyond the end of the buffer. + */ + if ((bp = calloc(bbsize + sizeof(eh), 1)) == NULL) { + warnx("malloc: %s: no memory", fname); + goto bad; + } + /* Copy the exec header and read the rest of the file. */ + memcpy(bp, &eh, sizeof(eh)); + if (read(fd, bp+sizeof(eh), tdsize) != tdsize) { + warn("read: %s", fname); + goto bad; + } + + *size = bbsize; /* aligned to DEV_BSIZE */ + + /* Calculate the symbols' locations within the proto file */ + off = N_DATOFF(eh) - N_DATADDR(eh) - (eh.a_entry - N_TXTADDR(eh)); + block_size_p = (int *) (bp + nl[X_BLOCK_SIZE ].n_value + off); + block_count_p = (int *) (bp + nl[X_BLOCK_COUNT].n_value + off); + block_table = (daddr_t *) (bp + nl[X_BLOCK_TABLE].n_value + off); + maxblocknum = *block_count_p; + + if (verbose) { + printf("%s: entry point %#x\n", fname, eh.a_entry); + printf("proto bootblock size %ld\n", *size); + printf("room for %d filesystem blocks at %#x\n", + maxblocknum, nl[X_BLOCK_TABLE].n_value); + } + + close(fd); + if (!hflag) + bp += sizeof(struct exec); + return bp; + + bad: + if (bp) + free(bp); + if (fd >= 0) + close(fd); + return NULL; +} + +static void +devread(fd, buf, blk, size, msg) + int fd; + void *buf; + daddr_t blk; + size_t size; + char *msg; +{ + if (lseek(fd, dbtob(blk), SEEK_SET) != dbtob(blk)) + err(1, "%s: devread: lseek", msg); + + if (read(fd, buf, size) != size) + err(1, "%s: devread: read", msg); +} + +static char sblock[SBSIZE]; + +int +loadblocknums(boot, devfd) +char *boot; +int devfd; +{ + int i, fd; + struct stat statbuf; + struct statfs statfsbuf; + struct fs *fs; + char *buf; + daddr_t blk, *ap; + struct dinode *ip; + int ndb; + + /* + * Open 2nd-level boot program and record the block numbers + * it occupies on the filesystem represented by `devfd'. + */ + + /* Make sure the (probably new) boot file is on disk. */ + sync(); sleep(1); + + if ((fd = open(boot, O_RDONLY)) < 0) + err(1, "open: %s", boot); + + if (fstatfs(fd, &statfsbuf) != 0) + err(1, "statfs: %s", boot); + + if (strncmp(statfsbuf.f_fstypename, "ffs", MFSNAMELEN) && + strncmp(statfsbuf.f_fstypename, "ufs", MFSNAMELEN) ) { + errx(1, "%s: must be on an FFS filesystem", boot); + } + + if (fsync(fd) != 0) + err(1, "fsync: %s", boot); + + if (fstat(fd, &statbuf) != 0) + err(1, "fstat: %s", boot); + + close(fd); + + /* Read superblock */ + devread(devfd, sblock, SBLOCK, SBSIZE, "superblock"); + fs = (struct fs *)sblock; + + /* Sanity-check super-block. */ + + if (fs->fs_magic != FS_MAGIC) + errx(1, "Bad magic number in superblock"); + + if (fs->fs_inopb <= 0) + err(1, "Bad inopb=%d in superblock", fs->fs_inopb); + + /* Read inode */ + if ((buf = malloc(fs->fs_bsize)) == NULL) + errx(1, "No memory for filesystem block"); + + blk = fsbtodb(fs, ino_to_fsba(fs, statbuf.st_ino)); + devread(devfd, buf, blk, fs->fs_bsize, "inode"); + ip = (struct dinode *)(buf) + ino_to_fsbo(fs, statbuf.st_ino); + + /* + * Have the inode. Figure out how many blocks we need. + */ + ndb = howmany(ip->di_size, fs->fs_bsize); + if (ndb > maxblocknum) + errx(1, "Too many blocks"); + *block_count_p = ndb; + *block_size_p = fs->fs_bsize; + if (verbose) + printf("Will load %d blocks of size %d each.\n", + ndb, fs->fs_bsize); + + /* + * Get the block numbers; we don't handle fragments + */ + ap = ip->di_db; + for (i = 0; i < NDADDR && *ap && ndb; i++, ap++, ndb--) { + blk = fsbtodb(fs, *ap); + if (verbose) + printf("%d: %d\n", i, blk); + block_table[i] = blk; + } + if (ndb == 0) + return 0; + + /* + * Just one level of indirections; there isn't much room + * for more in the 1st-level bootblocks anyway. + */ + blk = fsbtodb(fs, ip->di_ib[0]); + devread(devfd, buf, blk, fs->fs_bsize, "indirect block"); + ap = (daddr_t *)buf; + for (; i < NINDIR(fs) && *ap && ndb; i++, ap++, ndb--) { + blk = fsbtodb(fs, *ap); + if (verbose) + printf("%d: %d\n", i, blk); + block_table[i] = blk; + } + + return 0; +} + +static void +vid_to_disklabel(dkname, bootproto) +char *dkname; +char *bootproto; +{ + char *specname; + int exe_file, f; + struct cpu_disklabel *pcpul; + struct stat stat; + unsigned int exe_addr; + unsigned short exe_addr_u; + unsigned short exe_addr_l; + + pcpul = (struct cpu_disklabel *)malloc(sizeof(struct cpu_disklabel)); + bzero(pcpul, sizeof(struct cpu_disklabel)); + + if (verbose) + printf("modifying vid.\n"); + + exe_file = open(bootproto, O_RDONLY, 0444); + if (exe_file == -1) { + perror(bootproto); + exit(2); + } + + f = opendev(dkname, O_RDWR, OPENDEV_PART, &specname); + + if (lseek(f, 0, SEEK_SET) < 0 || + read(f, pcpul, sizeof(struct cpu_disklabel)) + < sizeof(struct cpu_disklabel)) + err(4, "%s", specname); + + + pcpul->version = 1; + strcpy(pcpul->vid_id, "M88K"); + + fstat(exe_file, &stat); + + /* size in 256 byte blocks round up after a.out header removed */ + + pcpul->vid_oss = 2; + pcpul->vid_osl = (((stat.st_size -0x20) +511) / 512) *2; + + lseek(exe_file, 0x14, SEEK_SET); + read(exe_file, &exe_addr, 4); + + /* check this, it may not work in both endian. */ + /* No, it doesn't. Use a big endian machine for now. SPM */ + + { + union { + struct s { + unsigned short s1; + unsigned short s2; + } s; + unsigned long l; + } a; + a.l = exe_addr; + pcpul->vid_osa_u = a.s.s1; + pcpul->vid_osa_l = a.s.s2; + + } + pcpul->vid_cas = 1; + pcpul->vid_cal = 1; + + /* do not want to write past end of structure, not null terminated */ + + strncpy(pcpul->vid_mot, "MOTOROLA", 8); + + pcpul->cfg_rec = 0x100; + pcpul->cfg_psm = 0x200; + + if (!nowrite) { + if (lseek(f, 0, SEEK_SET) < 0 || + write(f, pcpul, sizeof(struct cpu_disklabel)) + < sizeof(struct cpu_disklabel)) + err(4, "%s", specname); + } + free(pcpul); + + close(exe_file); + close(f); + +} diff --git a/sys/arch/mvmeppc/stand/libbug/Makefile b/sys/arch/mvmeppc/stand/libbug/Makefile new file mode 100644 index 00000000000..a360e63b233 --- /dev/null +++ b/sys/arch/mvmeppc/stand/libbug/Makefile @@ -0,0 +1,19 @@ +# $OpenBSD: Makefile,v 1.1 2001/06/26 21:58:03 smurph Exp $ + +LIB=bug + +NOPIC= +NOPROFILE= + +S=${.CURDIR}/../../../.. +DIR_SA=$S/lib/libsa + +CFLAGS+=-O2 -I${.CURDIR}/../../include -I${DIR_SA} + +SRCS= delay.c diskrd.c diskwr.c getbrdid.c inchr.c instat.c outln.c outch.c\ + outstr.c putchar.c return.c rtc_rd.c netrd.c netwr.c netfopen.c \ + netfread.c netctrl.c + +install: + +.include <bsd.lib.mk> diff --git a/sys/arch/mvmeppc/stand/libbug/Makefile.inc b/sys/arch/mvmeppc/stand/libbug/Makefile.inc new file mode 100644 index 00000000000..1d780fe931e --- /dev/null +++ b/sys/arch/mvmeppc/stand/libbug/Makefile.inc @@ -0,0 +1,14 @@ +# $OpenBSD: Makefile.inc,v 1.1 2001/06/26 21:58:04 smurph Exp $ + +LIB_BUG_DIR=${S}/arch/mvmeppc/stand/libbug + +LIBBUG_DIR!= cd ${LIB_BUG_DIR}; \ + printf "xxx:\n\techo \$${.OBJDIR}\n" | ${MAKE} -r -s -f - xxx + +LIBBUG=${LIBBUG_DIR}/libbug.a + +$(LIBBUG): .NOTMAIN __always_make_libbug + @echo making sure the libbug is up to date... + @(cd ${LIB_BUG_DIR}; ${MAKE}) + +__always_make_libbug: .NOTMAIN diff --git a/sys/arch/mvmeppc/stand/libbug/delay.c b/sys/arch/mvmeppc/stand/libbug/delay.c new file mode 100644 index 00000000000..7e101de2cc0 --- /dev/null +++ b/sys/arch/mvmeppc/stand/libbug/delay.c @@ -0,0 +1,15 @@ +/* + * bug routines -- assumes that the necessary sections of memory + * are preserved. + */ +#include <sys/types.h> +#include <machine/prom.h> + +/* BUG - timing routine */ +void +mvmeprom_delay(msec) + int msec; /* This is r3 */ +{ + asm volatile ("mr 3, %0" :: "r"(msec)); + MVMEPROM_CALL(MVMEPROM_DELAY); +} diff --git a/sys/arch/mvmeppc/stand/libbug/diskrd.c b/sys/arch/mvmeppc/stand/libbug/diskrd.c new file mode 100644 index 00000000000..3ff1de00e71 --- /dev/null +++ b/sys/arch/mvmeppc/stand/libbug/diskrd.c @@ -0,0 +1,19 @@ +/* + * bug routines -- assumes that the necessary sections of memory + * are preserved. + */ +#include <sys/types.h> +#include <machine/prom.h> + +/* returns 0: success, nonzero: error */ +int +mvmeprom_diskrd(arg) + struct mvmeprom_dskio *arg; +{ + int ret; + + asm volatile ("mr 3, %0" :: "r"(arg)); + MVMEPROM_CALL(MVMEPROM_NETRD); + asm volatile ("mr %0, 3" : "=r" (ret)); + return ((ret & 0x8)); +} diff --git a/sys/arch/mvmeppc/stand/libbug/diskwr.c b/sys/arch/mvmeppc/stand/libbug/diskwr.c new file mode 100644 index 00000000000..8b1290a222d --- /dev/null +++ b/sys/arch/mvmeppc/stand/libbug/diskwr.c @@ -0,0 +1,19 @@ +/* + * bug routines -- assumes that the necessary sections of memory + * are preserved. + */ +#include <sys/types.h> +#include <machine/prom.h> + +/* returns 0: success, nonzero: error */ +int +mvmeprom_diskwr(arg) + struct mvmeprom_dskio *arg; +{ + int ret; + + asm volatile ("mr 3, %0" :: "r"(arg)); + MVMEPROM_CALL(MVMEPROM_DSKWR); + asm volatile ("mr %0, 3" : "=r" (ret)); + return ((ret & 0x8)); +} diff --git a/sys/arch/mvmeppc/stand/libbug/getbrdid.c b/sys/arch/mvmeppc/stand/libbug/getbrdid.c new file mode 100644 index 00000000000..541bb2603aa --- /dev/null +++ b/sys/arch/mvmeppc/stand/libbug/getbrdid.c @@ -0,0 +1,17 @@ +/* + * bug routines -- assumes that the necessary sections of memory + * are preserved. + */ +#include <sys/types.h> +#include <machine/prom.h> + +/* BUG - query board routines */ +struct mvmeprom_brdid * +mvmeprom_brdid() +{ + struct mvmeprom_brdid *id; + + MVMEPROM_CALL(MVMEPROM_BRD_ID); + asm volatile ("mr %0, 3": "=r" (id):); + return (id); +} diff --git a/sys/arch/mvmeppc/stand/libbug/inchr.c b/sys/arch/mvmeppc/stand/libbug/inchr.c new file mode 100644 index 00000000000..c1fce2e7414 --- /dev/null +++ b/sys/arch/mvmeppc/stand/libbug/inchr.c @@ -0,0 +1,22 @@ +/* $OpenBSD: inchr.c,v 1.1 2001/06/26 21:58:04 smurph Exp $ */ + +/* + * bug routines -- assumes that the necessary sections of memory + * are preserved. + */ +#include <sys/types.h> +#include <machine/prom.h> + +#include "stand.h" +#include "libbug.h" + +/* returns 0 if no characters ready to read */ +int +getchar() +{ + int ret; + + MVMEPROM_CALL(MVMEPROM_INCHR); + asm volatile ("mr %0, 3" : "=r" (ret)); + return ret; +} diff --git a/sys/arch/mvmeppc/stand/libbug/instat.c b/sys/arch/mvmeppc/stand/libbug/instat.c new file mode 100644 index 00000000000..096abdedd99 --- /dev/null +++ b/sys/arch/mvmeppc/stand/libbug/instat.c @@ -0,0 +1,17 @@ +/* + * bug routines -- assumes that the necessary sections of memory + * are preserved. + */ +#include <sys/types.h> +#include <machine/prom.h> + +/* returns 0 if no characters ready to read */ +int +mvmeprom_instat() +{ + int ret; + + MVMEPROM_CALL(MVMEPROM_INSTAT); + asm volatile ("mr %0, 3" : "=r" (ret)); + return (!(ret & 0x4)); +} diff --git a/sys/arch/mvmeppc/stand/libbug/libbug.h b/sys/arch/mvmeppc/stand/libbug/libbug.h new file mode 100644 index 00000000000..c282cfaac9e --- /dev/null +++ b/sys/arch/mvmeppc/stand/libbug/libbug.h @@ -0,0 +1,29 @@ +/* $OpenBSD: libbug.h,v 1.1 2001/06/26 21:58:04 smurph Exp $ */ + +/* + * prototypes and such. note that get/put char are in stand.h + */ + +void mvmeprom_delay __P((int)); +int mvmeprom_diskrd __P((struct mvmeprom_dskio *)); +int mvmeprom_diskwr __P((struct mvmeprom_dskio *)); +struct mvmeprom_brdid *mvmeprom_getbrdid __P((void)); +int peekchar __P((void)); +void mvmeprom_outln __P((char *, char *)); +void mvmeprom_outstr __P((char *, char *)); +void mvmeprom_rtc_rd __P((struct mvmeprom_time *)); +int mvmeprom_netctrl __P((struct mvmeprom_netctrl *)); +int mvmeprom_netctrl_init __P((u_char, u_char)); +int mvmeprom_netctrl_hwa __P((u_char, u_char, void *, u_long *)); +int mvmeprom_netctrl_tx __P((u_char, u_char, void *, u_long *)); +int mvmeprom_netctrl_rx __P((u_char, u_char, void *, u_long *)); +int mvmeprom_netctrl_flush_rx __P((u_char, u_char)); +int mvmeprom_netctrl_reset __P((u_char, u_char)); + +/* + * bugcrt stuff + */ + +extern struct mvmeprom_args bugargs; + +void bugexec __P((void (*)())); diff --git a/sys/arch/mvmeppc/stand/libbug/netctrl.c b/sys/arch/mvmeppc/stand/libbug/netctrl.c new file mode 100644 index 00000000000..cf671f124a5 --- /dev/null +++ b/sys/arch/mvmeppc/stand/libbug/netctrl.c @@ -0,0 +1,129 @@ +/* + * bug routines -- assumes that the necessary sections of memory + * are preserved. + */ +#include <sys/types.h> +#include <machine/prom.h> + +/* returns 0: success, nonzero: error */ +int +mvmeprom_netctrl(arg) + struct mvmeprom_netctrl *arg; +{ + asm volatile ("mr 3, %0":: "r" (arg)); + MVMEPROM_CALL(MVMEPROM_NETCTRL); + return (arg->status); +} + +int +mvmeprom_netctrl_init(clun, dlun) +u_char clun; +u_char dlun; +{ + struct mvmeprom_netctrl niocall; + niocall.clun = clun; + niocall.dlun = dlun; + niocall.status = 0; + niocall.cmd = 0; /* init */ + niocall.addr = 0; + niocall.len = 0; + niocall.flags = 0; + mvmeprom_netctrl(&niocall); + return(niocall.status); +} + +int +mvmeprom_netctrl_hwa(clun, dlun, addr, len) +u_char clun; +u_char dlun; +void *addr; +u_long *len; +{ + struct mvmeprom_netctrl niocall; + niocall.clun = clun; + niocall.dlun = dlun; + niocall.status = 0; + niocall.cmd = 1; /* get hw address */ + niocall.addr = addr; + niocall.len = *len; + niocall.flags = 0; + mvmeprom_netctrl(&niocall); + *len = niocall.len; + return(niocall.status); +} + +int +mvmeprom_netctrl_tx(clun, dlun, addr, len) +u_char clun; +u_char dlun; +void *addr; +u_long *len; +{ + struct mvmeprom_netctrl niocall; + niocall.clun = clun; + niocall.dlun = dlun; + niocall.status = 0; + niocall.cmd = 2; /* transmit */ + niocall.addr = addr; + niocall.len = *len; + niocall.flags = 0; + mvmeprom_netctrl(&niocall); + *len = niocall.len; + return(niocall.status); +} + +int +mvmeprom_netctrl_rx(clun, dlun, addr, len) +u_char clun; +u_char dlun; +void *addr; +u_long *len; +{ + struct mvmeprom_netctrl niocall; + niocall.clun = clun; + niocall.dlun = dlun; + niocall.status = 0; + niocall.cmd = 3; /* receive */ + niocall.addr = addr; + niocall.len = *len; + niocall.flags = 0; + mvmeprom_netctrl(&niocall); + *len = niocall.len; + return(niocall.status); +} + +int +mvmeprom_netctrl_flush_rx(clun, dlun) +u_char clun; +u_char dlun; +{ + struct mvmeprom_netctrl niocall; + niocall.clun = clun; + niocall.dlun = dlun; + niocall.status = 0; + niocall.cmd = 4; /* reset */ + niocall.addr = 0; + niocall.len = 0; + niocall.flags = 0; + mvmeprom_netctrl(&niocall); + return(niocall.status); +} + +int +mvmeprom_netctrl_reset(clun, dlun) +u_char clun; +u_char dlun; +{ + struct mvmeprom_netctrl niocall; + niocall.clun = clun; + niocall.dlun = dlun; + niocall.status = 0; + niocall.cmd = 5; /* reset */ + niocall.addr = 0; + niocall.len = 0; + niocall.flags = 0; + mvmeprom_netctrl(&niocall); + return(niocall.status); +} + + diff --git a/sys/arch/mvmeppc/stand/libbug/netfopen.c b/sys/arch/mvmeppc/stand/libbug/netfopen.c new file mode 100644 index 00000000000..2ff21f39646 --- /dev/null +++ b/sys/arch/mvmeppc/stand/libbug/netfopen.c @@ -0,0 +1,16 @@ +/* + * bug routines -- assumes that the necessary sections of memory + * are preserved. + */ +#include <sys/types.h> +#include <machine/prom.h> + +/* returns 0: success, nonzero: error */ +int +mvmeprom_netfopen(arg) + struct mvmeprom_netfopen *arg; +{ + asm volatile ("mr 3, %0": : "r" (arg)); + MVMEPROM_CALL(MVMEPROM_NETFOPEN); + return (arg->status); +} diff --git a/sys/arch/mvmeppc/stand/libbug/netfread.c b/sys/arch/mvmeppc/stand/libbug/netfread.c new file mode 100644 index 00000000000..32b9108b2c9 --- /dev/null +++ b/sys/arch/mvmeppc/stand/libbug/netfread.c @@ -0,0 +1,16 @@ +/* + * bug routines -- assumes that the necessary sections of memory + * are preserved. + */ +#include <sys/types.h> +#include <machine/prom.h> + +/* returns 0: success, nonzero: error */ +int +mvmeprom_netfread(arg) + struct mvmeprom_netfread *arg; +{ + asm volatile ("mr 3, %0": : "r" (arg)); + MVMEPROM_CALL(MVMEPROM_NETFREAD); + return (arg->status); +} diff --git a/sys/arch/mvmeppc/stand/libbug/netrd.c b/sys/arch/mvmeppc/stand/libbug/netrd.c new file mode 100644 index 00000000000..b4fa0376dec --- /dev/null +++ b/sys/arch/mvmeppc/stand/libbug/netrd.c @@ -0,0 +1,16 @@ +/* + * bug routines -- assumes that the necessary sections of memory + * are preserved. + */ +#include <sys/types.h> +#include <machine/prom.h> + +/* returns 0: success, nonzero: error */ +int +mvmeprom_netrd(arg) + struct mvmeprom_netio *arg; +{ + asm volatile ("mr 3, %0": : "r" (arg)); + MVMEPROM_CALL(MVMEPROM_NETRD); + return (arg->status); +} diff --git a/sys/arch/mvmeppc/stand/libbug/netwr.c b/sys/arch/mvmeppc/stand/libbug/netwr.c new file mode 100644 index 00000000000..e96d888db18 --- /dev/null +++ b/sys/arch/mvmeppc/stand/libbug/netwr.c @@ -0,0 +1,16 @@ +/* + * bug routines -- assumes that the necessary sections of memory + * are preserved. + */ +#include <sys/types.h> +#include <machine/prom.h> + +/* returns 0: success, nonzero: error */ +int +mvmeprom_netwr(arg) + struct mvmeprom_netio *arg; +{ + asm volatile ("mr 3, %0": : "r" (arg)); + MVMEPROM_CALL(MVMEPROM_NETWR); + return (arg->status); +} diff --git a/sys/arch/mvmeppc/stand/libbug/outch.c b/sys/arch/mvmeppc/stand/libbug/outch.c new file mode 100644 index 00000000000..5d98a4e0065 --- /dev/null +++ b/sys/arch/mvmeppc/stand/libbug/outch.c @@ -0,0 +1,15 @@ +/* + * bug routines -- assumes that the necessary sections of memory + * are preserved. + */ +#include <sys/types.h> +#include <machine/prom.h> + +void +mvmeprom_outchr(a) + char a; +{ + asm volatile ("mr 3, %0" : :"r" (a)); + MVMEPROM_CALL(MVMEPROM_OUTCHR); +} + diff --git a/sys/arch/mvmeppc/stand/libbug/outln.c b/sys/arch/mvmeppc/stand/libbug/outln.c new file mode 100644 index 00000000000..dc4015a7762 --- /dev/null +++ b/sys/arch/mvmeppc/stand/libbug/outln.c @@ -0,0 +1,15 @@ +/* + * bug routines -- assumes that the necessary sections of memory + * are preserved. + */ +#include <sys/types.h> +#include <machine/prom.h> + +void +mvmeprom_outln(start, end) + char *start, *end; +{ + asm volatile ("mr 3, %0": : "r" (start)); + asm volatile ("mr 4, %0": : "r" (end)); + MVMEPROM_CALL(MVMEPROM_OUTLN); +} diff --git a/sys/arch/mvmeppc/stand/libbug/outstr.c b/sys/arch/mvmeppc/stand/libbug/outstr.c new file mode 100644 index 00000000000..5f317081ab0 --- /dev/null +++ b/sys/arch/mvmeppc/stand/libbug/outstr.c @@ -0,0 +1,15 @@ +/* + * bug routines -- assumes that the necessary sections of memory + * are preserved. + */ +#include <sys/types.h> +#include <machine/prom.h> + +void +mvmeprom_outstr(start, end) + char *start, *end; +{ + asm volatile ("mr 3, %0": : "r" (start)); + asm volatile ("mr 4, %0": : "r" (end)); + MVMEPROM_CALL(MVMEPROM_OUTSTR); +} diff --git a/sys/arch/mvmeppc/stand/libbug/putchar.c b/sys/arch/mvmeppc/stand/libbug/putchar.c new file mode 100644 index 00000000000..9a15bfb6b3f --- /dev/null +++ b/sys/arch/mvmeppc/stand/libbug/putchar.c @@ -0,0 +1,25 @@ +/* $OpenBSD: putchar.c,v 1.1 2001/06/26 21:58:05 smurph Exp $ */ + +/* + * putchar: easier to do this with outstr than to add more macros to + * handle byte passing on the stack + */ + +#include <sys/types.h> +#include <machine/prom.h> + +#include "stand.h" +#include "libbug.h" + +void +putchar(c) + int c; +{ + char ca; + ca = (char)c & 0xFF; + if (ca == '\n') + putchar('\r'); + + asm volatile ("mr 3, %0" :: "r" (ca)); + MVMEPROM_CALL(MVMEPROM_OUTCHR); +} diff --git a/sys/arch/mvmeppc/stand/libbug/return.c b/sys/arch/mvmeppc/stand/libbug/return.c new file mode 100644 index 00000000000..53fb5a3b1cc --- /dev/null +++ b/sys/arch/mvmeppc/stand/libbug/return.c @@ -0,0 +1,26 @@ +/* + * bug routines -- assumes that the necessary sections of memory + * are preserved. + */ +#include <sys/types.h> +#include <machine/prom.h> +#include "stand.h" +#include "libbug.h" + +/* BUG - return to bug routine */ +void +mvmeprom_return() +{ + MVMEPROM_CALL(MVMEPROM_RETURN); + /*NOTREACHED*/ +} + +/* BUG - return to bug routine */ +__dead void +_rtt() +{ + MVMEPROM_CALL(MVMEPROM_RETURN); + printf("_rtt: exit failed. spinning..."); + while (1) ; + /*NOTREACHED*/ +} diff --git a/sys/arch/mvmeppc/stand/libbug/rtc_rd.c b/sys/arch/mvmeppc/stand/libbug/rtc_rd.c new file mode 100644 index 00000000000..c1ee9f5a0da --- /dev/null +++ b/sys/arch/mvmeppc/stand/libbug/rtc_rd.c @@ -0,0 +1,14 @@ +/* + * bug routines -- assumes that the necessary sections of memory + * are preserved. + */ +#include <sys/types.h> +#include <machine/prom.h> + +void +mvmeprom_rtc_rd(ptime) + struct mvmeprom_time *ptime; +{ + asm volatile ("mr 3, %0": : "r" (ptime)); + MVMEPROM_CALL(MVMEPROM_RTC_RD); +} diff --git a/sys/arch/mvmeppc/stand/libsa/Makefile b/sys/arch/mvmeppc/stand/libsa/Makefile new file mode 100644 index 00000000000..3c8b70fa1ea --- /dev/null +++ b/sys/arch/mvmeppc/stand/libsa/Makefile @@ -0,0 +1,48 @@ +# $OpenBSD: Makefile,v 1.1 2001/06/26 21:58:06 smurph Exp $ + +LIB=sa + +CLEANFILES+=SRT0.o SRT1.o + +NOPIC=nopic +NOPROFILE=noprofile + +# Logically src/sys +S=${.CURDIR}/../../../.. +DIR_SA=$S/lib/libsa +DIR_KERN=$S/lib/libkern + +SRC_net= arp.c ether.c in_cksum.c net.c netif.c rpc.c nfs.c \ + rarp.c bootparam.c + +SRC_sa= alloc.c memcpy.c exit.c getfile.c gets.c globals.c \ + printf.c strerror.c memset.c memcmp.c strncpy.c strcmp.c strlen.c \ + close.c closeall.c dev.c disklabel.c dkcksum.c \ + lseek.c open.c nullfs.c read.c fstat.c \ + ufs.c cread.c + +SRC_kern= ashrdi3.c bzero.c strcpy.c + +SRC_mvme= exec_mvme.c + +SRC_here= bugdev.c cache.c clock.c conf.c parse_args.c rawfs.c tftpfs.c + +SRCS= ${SRC_net} ${SRC_sa} ${SRC_mvme} ${SRC_here} ${SRC_kern} + +# DBG= -DDEBUG -DNETIF_DEBUG -DNFS_DEBUG -DRPC_DEBUG \ +# -DNET_DEBUG -DRARP_DEBUG -DETHER_DEBUG + +#DEFS= -DCOMPAT_UFS +DEFS= -D__INTERNAL_LIBSA_CREAD +#-DNETIF_DEBUG +INCL= -I${.CURDIR} -I${.CURDIR}/../libbug -I${S}/lib/libsa -I${S} +COPTS= #-fno-defer-pop +CFLAGS+= ${XCFLAGS} ${COPTS} ${DEFS} ${DBG} ${INCL} -O2 + +.PATH: ${DIR_SA} ${DIR_KERN} + +all: libsa.a + +install: + +.include <bsd.lib.mk> diff --git a/sys/arch/mvmeppc/stand/libsa/Makefile.inc b/sys/arch/mvmeppc/stand/libsa/Makefile.inc new file mode 100644 index 00000000000..568e3b9e4d0 --- /dev/null +++ b/sys/arch/mvmeppc/stand/libsa/Makefile.inc @@ -0,0 +1,15 @@ +# $OpenBSD: Makefile.inc,v 1.1 2001/06/26 21:58:06 smurph Exp $ + +LIB_SA_DIR=${S}/arch/mvmeppc/stand/libsa + +LIBSA_DIR!= cd ${LIB_SA_DIR}; \ + printf "xxx:\n\techo \$${.OBJDIR}\n" | ${MAKE} -r -s -f - xxx + +LIBSA=${LIBSA_DIR}/libsa.a +SRTOBJ?= ${LIBSA_DIR}/SRT0.o + +$(LIBSA): .NOTMAIN __always_make_libsa + @echo making sure the libsa is up to date... + @(cd ${LIB_SA_DIR}; ${MAKE} "XCFLAGS=${CFLAGS}") + +__always_make_libsa: .NOTMAIN diff --git a/sys/arch/mvmeppc/stand/libsa/SRT0.S b/sys/arch/mvmeppc/stand/libsa/SRT0.S new file mode 100644 index 00000000000..82cf7c28ffd --- /dev/null +++ b/sys/arch/mvmeppc/stand/libsa/SRT0.S @@ -0,0 +1,90 @@ +; $OpenBSD: SRT0.S,v 1.1 2001/06/26 21:58:07 smurph Exp $ + +; Copyright (c) 1996 Nivas Madhur +; Copyright (c) 1995 Theo de Raadt +; +; 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 under OpenBSD by +; Theo de Raadt for Willowglen Singapore. +; 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. +; +; Copyright (c) 1995 Gordon W. Ross +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; 3. The name of the author may not be used to endorse or promote products +; derived from this software without specific prior written permission. +; 4. All advertising materials mentioning features or use of this software +; must display the following acknowledgement: +; This product includes software developed by Gordon Ross +; +; 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. + +; SRT0.S - Stand-alone Run-Time startup code, part 0 + .file "SRT0.S" + .text + .globl _stack +_stack: + .globl _start +_start: + .word __estack + .word _start + + align 8 + or.u r10, r0, hi16(_devlun) + st r2, r0, lo16(_devlun) + or.u r10, r0, hi16(_ctrlun) + st r3, r0, lo16(_ctrlun) + or.u r10, r0, hi16(_oparg) + st r8, r0, lo16(_oparg) + or.u r10, r0, hi16(_opargend) + st r9, r0, lo16(_opargend) +; enable SFU1 - 88k disables SFU1 on a reset + ldcr r10, cr1 + xor r10, r10, 0x8 + stcr r10, cr1 + +; Call the run-time startup C code, which will: +; call main & call exit - exit passes control back to +; to the Bug. + bsr __start + +; The end. diff --git a/sys/arch/mvmeppc/stand/libsa/SRT1.c b/sys/arch/mvmeppc/stand/libsa/SRT1.c new file mode 100644 index 00000000000..c7188ad3213 --- /dev/null +++ b/sys/arch/mvmeppc/stand/libsa/SRT1.c @@ -0,0 +1,124 @@ +/* $OpenBSD: SRT1.c,v 1.1 2001/06/26 21:58:07 smurph Exp $ */ + +/* + * Copyright (c) 1996 Nivas Madhur + * Copyright (c) 1995 Theo de Raadt + * + * 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 under OpenBSD by + * Theo de Raadt for Willowglen Singapore. + * 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. + * + * Copyright (c) 1995 Gordon W. Ross + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * 4. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Gordon Ross + * + * 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. + */ + +/* SRT1.c - Stand-alone Run-time startup code, part 1 */ + +#include <stdarg.h> +#include <sys/types.h> + +#include "config.h" + +extern char *edata, *end; + +int devlun = 0; +int ctrlun = 0; +int oparg = 0; +int opargend = 0; + +getvbr() +{ + asm volatile ("ldcr r2, cr7"); +} + +void +exit() +{ + /* + * Return to the Bug + */ + + asm volatile ("or r9, r0, 0x63; tb0 0, r0, 496"); + /* NOTREACHED */ + for(;;); /* keep compiler happy */ +} + +struct brdid brdid; +int cputyp; + +/* + * This is called by SRT0.S + * to do final prep for main + */ +_start() +{ + struct brdid *p; + + /* Clear BSS */ + + bzero(edata, end - edata); + + asm volatile("or r9, r0, 0x70\n + tb0 0, r0, 496\n + st r2, %0" : "=m" (p)); + + bcopy(p, &brdid, sizeof brdid); + cputyp = brdid.model; + + main(0); + exit(); +} + +/* + * Boot programs in C++ ? Not likely! + */ +__main() +{} diff --git a/sys/arch/mvmeppc/stand/libsa/bugdev.c b/sys/arch/mvmeppc/stand/libsa/bugdev.c new file mode 100644 index 00000000000..b3a8c8bce27 --- /dev/null +++ b/sys/arch/mvmeppc/stand/libsa/bugdev.c @@ -0,0 +1,609 @@ +/* $OpenBSD: bugdev.c,v 1.1 2001/06/26 21:58:07 smurph Exp $ */ + +/* + * Copyright (c) 1993 Paul Kranenburg + * 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 Paul Kranenburg. + * 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. + */ + +#include <sys/param.h> +#include <sys/disklabel.h> +#include <machine/prom.h> + +#include <stand.h> +#include <ufs.h> +#include "rawfs.h" +#include "tftpfs.h" + +#include "libsa.h" + +int errno; +int bootdev_type = BUGDEV_DISK; + +#if 1 +#define md_swap_long(x) ( (((x) >> 24) & 0xff) | (((x) >> 8 ) & 0xff00) | \ + (((x) << 8) & 0xff0000) | (((x) << 24) & 0xff000000)) +#else +#define md_swap_long(x) (x) +#endif + +struct bugdev_softc { + int fd; /* Prom file descriptor */ + u_int pnum; /* Partition number */ + u_int poff; /* Partition offset */ + u_int psize; /* Partition size */ + short clun; + short dlun; +} bugdev_softc[1]; + +extern struct fs_ops ufs_file_system; +extern struct fs_ops tftp_file_system; +extern struct fs_ops raw_file_system; + +struct fs_ops file_system[1]; + +struct mvmeprom_dskio tape_ioreq; + +#ifdef BUG_DEBUG +unsigned io = 0, mem = 0; +#define PCI_BASE 0x80000000 +#define CFC *(unsigned *)(PCI_BASE + 0xcfc) +#define CF8 *(unsigned *)(PCI_BASE + 0xcf8) +#define BUS_SHIFT 16 +#define DEVICE_SHIFT 11 +#define FNC_SHIFT 8 + +unsigned +bugpci_make_tag(bus, dev, fnc) + int bus, dev, fnc; +{ + return (bus << BUS_SHIFT) | (dev << DEVICE_SHIFT) | (fnc << FNC_SHIFT); +} + +static unsigned +bugpci_gen_config_reg(tag, offset) + unsigned tag; + int offset; +{ + unsigned reg; + + /* config mechanism #2, type 0 + /* standard cf8/cfc config */ + reg = 0x80000000 | tag | offset; + + return reg; +} + +/*#define DEBUG_CONFIG */ +unsigned +bugpci_conf_read(bus, dev, func, offset) + int bus, dev, func, offset; +{ + + unsigned data; + unsigned reg, tag, xx; + + if(offset & 3 || offset < 0 || offset >= 0x100) { + printf ("bugpci_conf_read: bad reg %x\n", offset); + return(~0); + } + + tag = bugpci_make_tag(bus, dev, func); + reg = bugpci_gen_config_reg(tag, offset); + reg = md_swap_long(reg); + /* if invalid tag, return -1 */ + if (reg == 0xffffffff) { + return 0xffffffff; + } + + CF8 = reg; + xx = CF8; + data = CFC; + data = md_swap_long(data); + + CF8 = 0; + + return(data); +} + +void +bugpci_conf_write(bus, dev, func, offset, data) + int bus, dev, func, offset; + unsigned data; +{ + unsigned reg, tag, xx; + + tag = bugpci_make_tag(bus, dev, func); + reg = bugpci_gen_config_reg(tag, offset); + reg = md_swap_long(reg); + + /* if invalid tag, return ??? */ + if (reg == 0xffffffff) { + return; + } + + CF8 = reg; + xx = CF8; + data = md_swap_long(data); + CFC = data; + CF8 = 0; + xx = CF8; +} +#endif + +static u_long +get_long(p) + const void *p; +{ + const unsigned char *cp = p; + + return cp[0] | (cp[1] << 8) | (cp[2] << 16) | (cp[3] << 24); +} + +/* + * Find a valid disklabel. + */ +static int +search_label(devp, off, buf, lp, off0) + void *devp; + u_long off; + char *buf; + struct disklabel *lp; + u_long off0; +{ + size_t read; + struct dos_partition *p; + int i; + u_long poff; + static int recursion; + + if (dsk_strategy(devp, F_READ, off, DEV_BSIZE, buf, &read) + || read != DEV_BSIZE) + return ERDLAB; + + if (buf[510] != 0x55 || buf[511] != 0xaa) + return ERDLAB; + + if (recursion++ <= 1) + off0 += off; + for (p = (struct dos_partition *)(buf + DOSPARTOFF), i = 4; + --i >= 0; p++) { + if (p->dp_typ == DOSPTYP_OPENBSD || + p->dp_typ == DOSPTYP_NETBSD) { + poff = get_long(&p->dp_start) + off0; + if (dsk_strategy(devp, F_READ, poff + LABELSECTOR, + DEV_BSIZE, buf, &read) == 0 + && read == DEV_BSIZE) { + if (!getdisklabel(buf, lp)) { + recursion--; + return 0; + } + } + if (dsk_strategy(devp, F_READ, off, DEV_BSIZE, buf, &read) + || read != DEV_BSIZE) { + recursion--; + return ERDLAB; + } + } else if (p->dp_typ == DOSPTYP_EXTEND) { + poff = get_long(&p->dp_start); + if (!search_label(devp, poff, buf, lp, off0)) { + recursion--; + return 0; + } + if (dsk_strategy(devp, F_READ, off, DEV_BSIZE, buf, &read) + || read != DEV_BSIZE) { + recursion--; + return ERDLAB; + } + } + } + recursion--; + return ERDLAB; +} + +int dsk_read_disklabel(devp) + void *devp; +{ + static char iobuf[MAXBSIZE]; + struct disklabel label; + int error = 0; + int i; + + register struct bugdev_softc *pp = (struct bugdev_softc *)devp; + +#ifdef DEBUG + printf("dsk_open:\n"); +#endif + /* First try to find a disklabel without MBR partitions */ + if (dsk_strategy(pp, F_READ, LABELSECTOR, DEV_BSIZE, iobuf, &i) != 0 + || i != DEV_BSIZE + || getdisklabel(iobuf, &label)) { + /* Else try MBR partitions */ + error = search_label(pp, 0, iobuf, &label, 0); + if (error && error != ERDLAB) + return (error); + } + if (error == ERDLAB) { + if (pp->pnum) + /* User specified a partition, but there is none */ + return (error); + /* No, label, just use complete disk */ + pp->poff = 0; + } else { + pp->poff = label.d_partitions[pp->pnum].p_offset; + pp->psize = label.d_partitions[pp->pnum].p_size; + } + return(0); +} + + +int +devopen(f, fname, file) + struct open_file *f; + const char *fname; + char **file; +{ + register struct bugdev_softc *pp = &bugdev_softc[0]; + int error; + char *dev, *cp; + + pp->clun = (short)bugargs.ctrl_lun; + pp->dlun = (short)bugargs.dev_lun; + pp->poff = 0; + pp->psize = 0; + pp->fd = 0; + pp->pnum = 0; + + f->f_devdata = (void *)pp; + + switch (bootdev_type) { + case BUGDEV_DISK: + dev = bugargs.arg_start; + /* + * Extract partition # from boot device string. + */ + for (cp = dev; *cp; cp++) /* void */; + while (*cp != '/' && cp > dev) { + if (*cp == ':') + pp->pnum = *(cp+1) - 'a'; + --cp; + } + + error = dsk_read_disklabel(pp); + if (error) + return(error); + + bcopy(&ufs_file_system, file_system, sizeof file_system[0]); + break; + + case BUGDEV_NET: + bcopy(&tftp_file_system, file_system, sizeof file_system[0]); + break; + + case BUGDEV_TAPE: + bcopy(&raw_file_system, file_system, sizeof file_system[0]); + break; + } + + f->f_dev = &devsw[bootdev_type]; + nfsys = 1; + *file = (char *)fname; + return (0); +} + +/* silly block scale factor */ +#define BUG_BLOCK_SIZE 256 +#define BUG_SCALE (512/BUG_BLOCK_SIZE) +int +dsk_strategy(devdata, func, dblk, size, buf, rsize) + void *devdata; + int func; + daddr_t dblk; + size_t size; + void *buf; + size_t *rsize; +{ + struct mvmeprom_dskio dio; + register struct bugdev_softc *pp = (struct bugdev_softc *)devdata; + daddr_t blk = dblk + pp->poff; + + twiddle(); + + dio.ctrl_lun = pp->clun; + dio.dev_lun = pp->dlun; + dio.status = 0; + dio.pbuffer = buf; + dio.blk_num = blk * BUG_SCALE; + dio.blk_cnt = size / BUG_BLOCK_SIZE; /* assumed size in bytes */ + dio.flag = 0; + dio.addr_mod = 0; +#ifdef DEBUG + printf("dsk_strategy: size=%d blk=%d buf=%x\n", size, blk, buf); + printf("ctrl %d dev %d\n", dio.ctrl_lun, dio.dev_lun); +#endif + mvmeprom_diskrd(&dio); + + *rsize = dio.blk_cnt * BUG_BLOCK_SIZE; +#ifdef DEBUG +printf("rsize %d status %x\n", *rsize, dio.status); +#endif + + if (dio.status) + return (EIO); + return (0); +} + +int +dsk_open(f) + struct open_file *f; +{ +#ifdef DEBUG + register struct bugdev_softc *pp = (struct bugdev_softc *)f->f_devdata; + printf("dsk_open:\n"); + printf("using mvmebug ctrl %d dev %d\n", + pp->clun, pp->dlun); +#endif + return (0); +} + +int +dsk_close(f) + struct open_file *f; +{ + return (EIO); +} + +int +dsk_ioctl(f, cmd, data) + struct open_file *f; + u_long cmd; + void *data; +{ + return (EIO); +} + +#define NFR_TIMEOUT 5 +/* netboot stuff */ +int +net_strategy(devdata, func, nblk, size, buf, rsize) + void *devdata; + int func; + daddr_t nblk; + size_t size; + void *buf; + size_t *rsize; +{ + int attempts = 0; + struct mvmeprom_netfread nfr; + register struct bugdev_softc *pp = (struct bugdev_softc *)devdata; + +retry: + + attempts+=1; + + nfr.clun = pp->clun; + nfr.dlun = pp->dlun; + nfr.status = 0; + nfr.addr = buf; + nfr.bytes = 0; + nfr.blk = nblk; + nfr.timeout = NFR_TIMEOUT; +#ifdef DEBUG + printf("net_strategy: size=%d blk=%d buf=%x\n", size, nblk, buf); + printf("ctrl %d dev %d\n", nfr.clun, nfr.dlun); +#endif + mvmeprom_netfread(&nfr); + +#ifdef BUG_DEBUG + io = bugpci_conf_read(0, 14, 0, 0x10) & ~0xf; + mem = bugpci_conf_read(0, 14, 0, 0x14) & ~0xf; + + printf(" IO @ %x\n", io); + printf("MEM @ %x\n", mem); + +#define PRINT_REG(regname, x) printf("%s = 0x%x\n", regname, md_swap_long(*(unsigned *)(io + x))) + + PRINT_REG("CSR0", 0x00); + PRINT_REG("CSR1", 0x08); + PRINT_REG("CSR2", 0x10); + PRINT_REG("CSR3", 0x18); + PRINT_REG("CSR4", 0x20); + PRINT_REG("CSR5", 0x28); + PRINT_REG("CSR6", 0x30); + PRINT_REG("CSR7", 0x38); + PRINT_REG("CSR8", 0x40); + PRINT_REG("CSR9", 0x48); + PRINT_REG("CSR10", 0x50); + PRINT_REG("CSR11", 0x58); + PRINT_REG("CSR12", 0x60); + PRINT_REG("CSR13", 0x68); + PRINT_REG("CSR14", 0x70); + PRINT_REG("CSR15", 0x78); +#endif + if (rsize) { + *rsize = nfr.bytes; + } +#ifdef DEBUG + printf("rsize %d status %x\n", *rsize, nfr.status); +#endif + + if (nfr.status) + if (attempts < 10) + goto retry; + else + return (EIO); + return (0); +} + +int +net_open(struct open_file *f, ...) +{ + va_list ap; + struct mvmeprom_netfopen nfo; + register struct bugdev_softc *pp = (struct bugdev_softc *)f->f_devdata; + char *filename; + short nfoerr = 0; + va_start(ap, f); + filename = va_arg(ap, char *); + va_end(ap); + +#ifdef DEBUG + printf("net_open: using mvmebug ctrl %d dev %d, filename: %s\n", pp->clun, pp->dlun, filename); +#endif + nfo.clun = pp->clun; + nfo.dlun = pp->dlun; + nfo.status = 0; + strcpy(nfo.filename, filename); + /* .NETFOPN syscall */ + mvmeprom_netfopen(&nfo); + +#ifdef DEBUG + if (nfo.status) { + nfoerr = nfo.status; + printf("net_open: ci err = 0x%x, cd err = 0x%x\n", ((nfoerr >> 8) & 0x0F), (nfoerr & 0x0F)); + } +#endif + return (nfo.status); +} + +int +net_close(f) + struct open_file *f; +{ + return (EIO); +} + +int +net_ioctl(f, cmd, data) + struct open_file *f; + u_long cmd; + void *data; +{ + return (EIO); +} + +int +tape_open(struct open_file *f, ...) +{ + va_list ap; + int error = 0; + int part; + struct mvmeprom_dskio *ti; + char *fname; /* partition number, i.e. "1" */ + + va_start(ap, f); + fname = va_arg(ap, char *); + va_end(ap); + + /* + * Set the tape segment number to the one indicated + * by the single digit fname passed in above. + */ + if ((fname[0] < '0') && (fname[0] > '9')) { + return ENOENT; + } + part = fname[0] - '0'; + fname = NULL; + + /* + * Setup our part of the saioreq. + * (determines what gets opened) + */ + ti = &tape_ioreq; + bzero((caddr_t)ti, sizeof(*ti)); + + ti->ctrl_lun = bugargs.ctrl_lun; + ti->dev_lun = bugargs.dev_lun; + ti->status = 0; + ti->pbuffer = NULL; + ti->blk_num = part; + ti->blk_cnt = 0; + ti->flag = 0; + ti->addr_mod = 0; + + f->f_devdata = ti; + + return (0); +} + +int +tape_close(f) + struct open_file *f; +{ + struct mvmeprom_dskio *ti; + + + ti = f->f_devdata; + f->f_devdata = NULL; + return 0; +} + +#define MVMEPROM_SCALE (512/MVMEPROM_BLOCK_SIZE) + +int +tape_strategy(devdata, flag, dblk, size, buf, rsize) + void *devdata; + int flag; + daddr_t dblk; + size_t size; + void *buf; + size_t *rsize; +{ + struct mvmeprom_dskio *ti; + int ret; + + ti = devdata; + + if (flag != F_READ) + return(EROFS); + + ti->status = 0; + ti->pbuffer = buf; + /* don't change block #, set in open */ + ti->blk_cnt = size / (512 / MVMEPROM_SCALE); + + ret = mvmeprom_diskrd(ti); + + if (ret != 0) + return (EIO); + + *rsize = (ti->blk_cnt / MVMEPROM_SCALE) * 512; + ti->flag |= IGNORE_FILENUM; /* ignore next time */ + + return (0); +} + +int +tape_ioctl(f, cmd, data) + struct open_file *f; + u_long cmd; + void *data; +{ + return EIO; +} + + diff --git a/sys/arch/mvmeppc/stand/libsa/cache.c b/sys/arch/mvmeppc/stand/libsa/cache.c new file mode 100644 index 00000000000..7c6f8b4de97 --- /dev/null +++ b/sys/arch/mvmeppc/stand/libsa/cache.c @@ -0,0 +1,23 @@ +/* $OpenBSD: cache.c,v 1.1 2001/06/26 21:58:07 smurph Exp $ */ +#define CACHELINESIZE 32 /* For now XXX */ + +void +syncicache(from, len) + void *from; + int len; +{ + int l = len; + void *p = from; + + do { + asm volatile ("dcbf %1,%0" :: "r"(p), "r"(0)); + p += CACHELINESIZE; + } while ((l -= CACHELINESIZE) > 0); + asm volatile ("sync"); + do { + asm volatile ("icbi %1,%0" :: "r"(from), "r"(0)); + from += CACHELINESIZE; + } while ((len -= CACHELINESIZE) > 0); + asm volatile ("isync"); +} + diff --git a/sys/arch/mvmeppc/stand/libsa/clock.c b/sys/arch/mvmeppc/stand/libsa/clock.c new file mode 100644 index 00000000000..c9ebce75fa9 --- /dev/null +++ b/sys/arch/mvmeppc/stand/libsa/clock.c @@ -0,0 +1,63 @@ + +#include <sys/types.h> +#include <machine/prom.h> + +#include "stand.h" +#include "libsa.h" + +/* + * BCD to decimal and decimal to BCD. + */ +#define FROMBCD(x) (((x) >> 4) * 10 + ((x) & 0xf)) +#define TOBCD(x) (((x) / 10 * 16) + ((x) % 10)) + +#define SECDAY (24 * 60 * 60) +#define SECYR (SECDAY * 365) +#define LEAPYEAR(y) (((y) & 3) == 0) +#define YEAR0 68 + + +/* + * This code is defunct after 2068. + * Will Unix still be here then?? + */ +const short dayyr[12] = +{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; + +static u_long +chiptotime(sec, min, hour, day, mon, year) + register int sec, min, hour, day, mon, year; +{ + register int days, yr; + + sec = FROMBCD(sec); + min = FROMBCD(min); + hour = FROMBCD(hour); + day = FROMBCD(day); + mon = FROMBCD(mon); + year = FROMBCD(year) + YEAR0; + if (year < 70) + year = 70; + + /* simple sanity checks */ + if (year < 70 || mon < 1 || mon > 12 || day < 1 || day > 31) + return (0); + days = 0; + for (yr = 70; yr < year; yr++) + days += LEAPYEAR(yr) ? 366 : 365; + days += dayyr[mon - 1] + day - 1; + if (LEAPYEAR(yr) && mon > 2) + days++; + /* now have days since Jan 1, 1970; the rest is easy... */ + return (days * SECDAY + hour * 3600 + min * 60 + sec); +} + +time_t +getsecs() +{ + struct mvmeprom_time m; + + mvmeprom_rtc_rd(&m); + return (chiptotime(m.sec_BCD, m.min_BCD, m.hour_BCD, m.day_BCD, + m.month_BCD, m.year_BCD)); +} diff --git a/sys/arch/mvmeppc/stand/libsa/conf.c b/sys/arch/mvmeppc/stand/libsa/conf.c new file mode 100644 index 00000000000..e238235cd86 --- /dev/null +++ b/sys/arch/mvmeppc/stand/libsa/conf.c @@ -0,0 +1,33 @@ +/* $OpenBSD: conf.c,v 1.1 2001/06/26 21:58:07 smurph Exp $ */ + +#include <sys/types.h> +#include <machine/prom.h> + +#include <stand.h> +#include <ufs.h> +#include "tftpfs.h" +#include "rawfs.h" +#include "libsa.h" + +struct fs_ops ufs_file_system[] = { + { ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat }, +}; + +struct fs_ops tftp_file_system[] = { + { tftpfs_open, tftpfs_close, tftpfs_read, tftpfs_write, tftpfs_seek, tftpfs_stat }, +}; + +struct fs_ops raw_file_system[] = { + { rawfs_open, rawfs_close, rawfs_read, rawfs_write, rawfs_seek, rawfs_stat }, +}; + +int nfsys = 1; /* devopen will choose the correct one. */ + +struct devsw devsw[] = { + { "dsk", dsk_strategy, dsk_open, dsk_close, dsk_ioctl }, + { "net", net_strategy, net_open, net_close, net_ioctl }, + { "tape", tape_strategy, tape_open, tape_close, tape_ioctl }, +}; + +int ndevs = (sizeof(devsw)/sizeof(devsw[0])); + diff --git a/sys/arch/mvmeppc/stand/libsa/exec_mvme.c b/sys/arch/mvmeppc/stand/libsa/exec_mvme.c new file mode 100644 index 00000000000..05b4269874d --- /dev/null +++ b/sys/arch/mvmeppc/stand/libsa/exec_mvme.c @@ -0,0 +1,260 @@ + +/*- + * Copyright (c) 1982, 1986, 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. 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, Berkeley and its contributors. + * 4. 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. + * + * @(#)boot.c 8.1 (Berkeley) 6/10/93 + */ + +#include <sys/param.h> +#include <sys/reboot.h> +#include <machine/prom.h> +#include <a.out.h> +#include <sys/exec_elf.h> + +#include "stand.h" +#include "libsa.h" + +#define RB_NOSYM 0x400 +#define RB_MULTI 0x4000 +#define RB_EXTRA 0x8000 +#define RB_ASKKERN 0x0010 /* ask kernel name */ + +vaddr_t ssym, esym; + +int +load_elf(fd, elf, entryp, esymp) + int fd; + Elf32_Ehdr *elf; + u_int32_t *entryp; + void **esymp; + +{ + Elf32_Shdr *shpp; + Elf32_Off off; + Elf32_Ehdr *elfp; + void *addr; + size_t size; + int n, havesyms, i, first = 1; + size_t sz; + + void *maxp = 0; /* correct type? */ + + /* + * Don't display load address for ELF; it's encoded in + * each section. + */ + + for (i = 0; i < elf->e_phnum; i++) { + Elf32_Phdr phdr; + (void)lseek(fd, elf->e_phoff + sizeof(phdr) * i, SEEK_SET); + if (read(fd, (void *)&phdr, sizeof(phdr)) != sizeof(phdr)) { + printf("read phdr: %s\n", strerror(errno)); + return (1); + } + if (phdr.p_type != PT_LOAD || + (phdr.p_flags & (PF_W|PF_X)) == 0) + continue; + + /* Read in segment. */ + printf("%s%lu@0x%lx", first ? "" : "+", phdr.p_filesz, + (u_long)phdr.p_vaddr); + (void)lseek(fd, phdr.p_offset, SEEK_SET); + maxp = maxp > (void *)(phdr.p_vaddr+ phdr.p_memsz) ? + maxp : (void *)(phdr.p_vaddr+ phdr.p_memsz); + if (read(fd, (void *)phdr.p_vaddr, phdr.p_filesz) != + phdr.p_filesz) { + printf("read segment: %s\n", strerror(errno)); + return (1); + } + syncicache((void *)phdr.p_vaddr, phdr.p_filesz); + + /* Zero BSS. */ + if (phdr.p_filesz < phdr.p_memsz) { + printf("+%lu@0x%lx", phdr.p_memsz - phdr.p_filesz, + (u_long)(phdr.p_vaddr + phdr.p_filesz)); + bzero((void *)(phdr.p_vaddr + phdr.p_filesz), + phdr.p_memsz - phdr.p_filesz); + } + first = 0; + } + +#if 1 + /* + * Copy the ELF and section headers. + */ + maxp = (void *)roundup((long)maxp, sizeof(long)); + (void *)ssym = elfp = maxp; /* mark the start of the symbol table */ + + maxp += sizeof(Elf_Ehdr); + + if (lseek(fd, elf->e_shoff, SEEK_SET) == -1) { + printf("lseek section headers: %s\n", strerror(errno)); + return 1; + } + sz = elf->e_shnum * sizeof(Elf_Shdr); + + shpp = maxp; + maxp += roundup(sz, sizeof(long)); + + if (read(fd, shpp, sz) != sz) { + printf("read section headers: %s\n", strerror(errno)); + return 1; + } + /* + * Now load the symbol sections themselves. Make sure the + * sections are aligned. Don't bother with string tables if + * there are no symbol sections. + */ + off = roundup((sizeof(Elf_Ehdr) + sz), sizeof(long)); + + for (havesyms = i = 0; i < elf->e_shnum; i++) + if (shpp[i].sh_type == SHT_SYMTAB) + havesyms = 1; + if (!havesyms) + goto no_syms; + + for (first = 1, i = 0; i < elf->e_shnum; i++) { + if (shpp[i].sh_type == SHT_SYMTAB || + shpp[i].sh_type == SHT_STRTAB) { + printf("%s%ld", first ? " [" : "+", + (u_long)shpp[i].sh_size); + if (lseek(fd, shpp[i].sh_offset, SEEK_SET) == -1) { + printf("lseek symbols: %s\n", strerror(errno)); + return 1; + } + if (read(fd, maxp, shpp[i].sh_size) != shpp[i].sh_size) { + printf("read symbols: %s\n", strerror(errno)); + return 1; + } + maxp += roundup(shpp[i].sh_size, sizeof(long)); + shpp[i].sh_offset = off; + off += roundup(shpp[i].sh_size, sizeof(long)); + first = 0; + } + } + if (first == 0) + printf("]"); + + /* + * Frob the copied ELF header to give information relative + * to elfp. + */ + elf->e_phoff = 0; + elf->e_shoff = sizeof(Elf_Ehdr); + elf->e_phentsize = 0; + elf->e_phnum = 0; + bcopy(elf, elfp, sizeof(*elf)); + +#endif +no_syms: + *esymp = (void *)esym = maxp; /* mark end of symbol table */ + *entryp = elf->e_entry; + printf(" \n"); + return (0); +} + +/*ARGSUSED*/ +void +exec_mvme(file, flag) +char *file; +int flag; +{ + char *loadaddr; + register int io; + Elf32_Ehdr hdr; + struct exec x; + int cc, magic; + void (*entry)(); + void *esym; + register char *cp; + register int *ip; + int n; + int bootdev; + int rval = 1; + char dummy[]="\0"; + + if (flag & RB_EXTRA) { + printf("exec_mvme: file=%s flag=0x%x cputyp=%x\n", file, flag, bugargs.cputyp); + } + + io = open(file, 0); + if (io < 0) + return; + + printf("Booting %s\n", file); + /* + * Read in the exec header, and validate it. + */ + if (read(io, &hdr, sizeof(hdr)) != sizeof(hdr)) { + printf("read header: %s\n", strerror(errno)); + goto shread; + } + + if (IS_ELF(hdr)) { + rval = load_elf(io, &hdr, &entry, &esym); + } else { + printf("unknown executable format\n"); + errno = EFTYPE; + goto closeout; + } + if (rval) + goto closeout; + + close(io); + + printf("Start @ 0x%x ...\n", (int)entry); + printf("Controler Address @ %x ...\n", bugargs.ctrl_addr); + if (flag & RB_HALT) mvmeprom_return(); + + bootdev = (bugargs.ctrl_lun << 8) | (bugargs.dev_lun & 0xFF); + +/* arguments to start + * r1 - stack provided by firmware/bootloader + * r3 - unused + * r4 - unused + * r5 - firmware pointer (NULL for PPC1bug) + * r6 - arg list + * r7 - arg list length + * r8 - end of symbol table + */ +/* r3 r4 r5 r6 r7 r8 */ + (*entry)(bugargs.ctrl_addr, bootdev, NULL, &dummy, 0, esym); + printf("exec: kernel returned!\n"); + return; + +shread: + printf("exec: short read\n"); + errno = EIO; +closeout: + close(io); + return; +} diff --git a/sys/arch/mvmeppc/stand/libsa/libsa.h b/sys/arch/mvmeppc/stand/libsa/libsa.h new file mode 100644 index 00000000000..d53d2f994f8 --- /dev/null +++ b/sys/arch/mvmeppc/stand/libsa/libsa.h @@ -0,0 +1,31 @@ +/* + * libsa prototypes + */ + +#include "libbug.h" + +/* bugdev.c */ +int dsk_open __P((struct open_file *, ...)); +int dsk_close __P((struct open_file *)); +int dsk_ioctl __P((struct open_file *, u_long, void *)); +int dsk_strategy __P((void *, int, daddr_t, size_t, void *, size_t *)); +int net_open __P((struct open_file *, ...)); +int net_close __P((struct open_file *)); +int net_ioctl __P((struct open_file *, u_long, void *)); +int net_strategy __P((void *, int, daddr_t, size_t, void *, size_t *)); +int tape_open __P((struct open_file *, ...)); +int tape_close __P((struct open_file *)); +int tape_ioctl __P((struct open_file *, u_long, void *)); +int tape_strategy __P((void *, int, daddr_t, size_t, void *, size_t *)); + +/* exec_mvme.c */ +void exec_mvme __P((char *, int)); + +/* parse_args.c */ +int parse_args __P((char **, int *)); + +#define BUGDEV_DISK 0 +#define BUGDEV_NET 1 +#define BUGDEV_TAPE 2 + +extern int bootdev_type; diff --git a/sys/arch/mvmeppc/stand/libsa/parse_args.c b/sys/arch/mvmeppc/stand/libsa/parse_args.c new file mode 100644 index 00000000000..86cb34bbf39 --- /dev/null +++ b/sys/arch/mvmeppc/stand/libsa/parse_args.c @@ -0,0 +1,121 @@ +/* $OpenBSD: parse_args.c,v 1.1 2001/06/26 21:58:07 smurph Exp $ */ + +/*- + * Copyright (c) 1995 Theo de Raadt + * + * 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 under OpenBSD by + * Theo de Raadt for Willowglen Singapore. + * 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. + * + */ + +#include <sys/param.h> +#include <sys/reboot.h> +#include <machine/prom.h> +#include <a.out.h> + +#include "stand.h" +#include "libsa.h" + +#define KERNEL_NAME "bsd" +#define RB_NOSYM 0x400 + +#define RB_AUTOBOOT 0 /* flags for system auto-booting itself */ + +#if 0 +#define RB_ASKNAME 0x0001 /* ask for file name to reboot from */ +#define RB_SINGLE 0x0002 /* reboot to single user only */ +#define RB_NOSYNC 0x0004 /* dont sync before reboot */ +#define RB_HALT 0x0008 /* don't reboot, just halt */ +#define RB_INITNAME 0x0010 /* name given for /etc/init (unused) */ +#define RB_DFLTROOT 0x0020 /* use compiled-in rootdev */ +#define RB_KDB 0x0040 /* give control to kernel debugger */ +#define RB_RDONLY 0x0080 /* mount root fs read-only */ +#define RB_DUMP 0x0100 /* dump kernel memory before reboot */ +#define RB_MINIROOT 0x0200 /* mini-root present in memory at boot time */ +#define RB_CONFIG 0x0400 /* change configured devices */ +#define RB_TIMEBAD 0x0800 /* don't call resettodr() in boot() */ +#define RB_POWERDOWN 0x1000 /* attempt to power down machine */ +#define RB_SERCONS 0x2000 /* use serial console if available */ +#endif + +struct flags { + char c; + short bit; +} bf[] = { + { 'a', RB_ASKNAME }, /* ask root */ + { 'b', RB_HALT }, + { 'c', RB_CONFIG }, + { 'd', RB_KDB }, + { 'e', 0x4000 }, /* spin slave cpus */ + { 'f', 0x0010 }, /* ask kernel name */ + { 'm', RB_MINIROOT }, + { 'r', RB_DFLTROOT }, + { 's', RB_SINGLE }, + { 'x', 0x8000 }, /* extra boot debug */ + { 'y', RB_NOSYM }, +}; + +int +parse_args(filep, flagp) + +char **filep; +int *flagp; + +{ + char *name = KERNEL_NAME, *ptr; + int i, howto = 0; + char c; + + if (bugargs.arg_start != bugargs.arg_end) { + ptr = bugargs.arg_start; + while (c = *ptr) { + while (c == ' ') + c = *++ptr; + if (c == '\0') + return (0); + if (c != '-') { + name = ptr; + while ((c = *++ptr) && c != ' ') + ; + if (c) + *ptr++ = 0; + continue; + } + while ((c = *++ptr) && c != ' ') { + if (c == 'q') + return (1); + for (i = 0; i < sizeof(bf)/sizeof(bf[0]); i++) + if (bf[i].c == c) { + howto |= bf[i].bit; + } + } + } + } + *flagp = howto; + *filep = name; + return (0); +} diff --git a/sys/arch/mvmeppc/stand/libsa/rawfs.c b/sys/arch/mvmeppc/stand/libsa/rawfs.c new file mode 100644 index 00000000000..3784175b92d --- /dev/null +++ b/sys/arch/mvmeppc/stand/libsa/rawfs.c @@ -0,0 +1,178 @@ +/* $OpenBSD: rawfs.c,v 1.1 2001/06/26 21:58:08 smurph Exp $ */ + +/* + * Copyright (c) 1995 Gordon W. Ross + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * 4. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Gordon W. Ross + * + * 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. + */ + +/* + * Raw file system - for stream devices like tapes. + * No random access, only sequential read allowed. + * This exists only to allow upper level code to be + * shielded from the fact that the device must be + * read only with whole block position and size. + */ + +#include <sys/param.h> +#include <stand.h> +#include <rawfs.h> + +#define RAWFS_BSIZE 512 + +/* + * In-core open file. + */ +struct cfile { + daddr_t fs_nextblk; /* block number to read next */ + int fs_len; /* amount left in f_buf */ + char * fs_ptr; /* read pointer into f_buf */ + char fs_buf[RAWFS_BSIZE]; +}; + +static int +rawfs_get_block __P((struct open_file *)); + +int rawfs_open(path, f) + char *path; + struct open_file *f; +{ + struct cfile *fs; + + /* + * The actual PROM driver has already been opened. + * Just allocate the I/O buffer, etc. + */ + fs = alloc(sizeof(struct cfile)); + fs->fs_nextblk = 0; + fs->fs_len = 0; + fs->fs_ptr = fs->fs_buf; + + f->f_fsdata = fs; + return (0); +} + +int rawfs_close(f) + struct open_file *f; +{ + struct cfile *fs; + + fs = (struct cfile *) f->f_fsdata; + f->f_fsdata = (void *)0; + + if (fs != (struct cfile *)0) + free(fs, sizeof(*fs)); + + return (0); +} + +int rawfs_read(f, start, size, resid) + struct open_file *f; + void *start; + u_int size; + u_int *resid; +{ + struct cfile *fs = (struct cfile *)f->f_fsdata; + char *addr = start; + int error = 0; + size_t csize; + + while (size != 0) { + + if (fs->fs_len == 0) + if ((error = rawfs_get_block(f)) != 0) + break; + + if (fs->fs_len <= 0) + break; /* EOF */ + + csize = size; + if (csize > fs->fs_len) + csize = fs->fs_len; + + bcopy(fs->fs_ptr, addr, csize); + fs->fs_ptr += csize; + fs->fs_len -= csize; + addr += csize; + size -= csize; + } + if (resid) + *resid = size; + return (error); +} + +int rawfs_write(f, start, size, resid) + struct open_file *f; + void *start; + size_t size; + size_t *resid; /* out */ +{ + return (EROFS); +} + +off_t rawfs_seek(f, offset, where) + struct open_file *f; + off_t offset; + int where; +{ + return (EFTYPE); +} + +int rawfs_stat(f, sb) + struct open_file *f; + struct stat *sb; +{ + return (EFTYPE); +} + + +/* + * Read a block from the underlying stream device + * (In our case, a tape drive.) + */ +static int +rawfs_get_block(f) + struct open_file *f; +{ + struct cfile *fs; + int error, len; + + fs = (struct cfile *)f->f_fsdata; + fs->fs_ptr = fs->fs_buf; + + twiddle(); + error = f->f_dev->dv_strategy(f->f_devdata, F_READ, + fs->fs_nextblk, RAWFS_BSIZE, fs->fs_buf, &len); + + if (!error) { + fs->fs_len = len; + fs->fs_nextblk += (RAWFS_BSIZE / DEV_BSIZE); + } + + return (error); +} + diff --git a/sys/arch/mvmeppc/stand/libsa/rawfs.h b/sys/arch/mvmeppc/stand/libsa/rawfs.h new file mode 100644 index 00000000000..cf29be5800b --- /dev/null +++ b/sys/arch/mvmeppc/stand/libsa/rawfs.h @@ -0,0 +1,15 @@ +/* $OpenBSD: rawfs.h,v 1.1 2001/06/26 21:58:08 smurph Exp $ */ + +/* + * Raw file system - for stream devices like tapes. + * No random access, only sequential read allowed. + */ + +int rawfs_open __P((char *path, struct open_file *f)); +int rawfs_close __P((struct open_file *f)); +int rawfs_read __P((struct open_file *f, void *buf, + u_int size, u_int *resid)); +int rawfs_write __P((struct open_file *f, void *buf, + u_int size, u_int *resid)); +off_t rawfs_seek __P((struct open_file *f, off_t offset, int where)); +int rawfs_stat __P((struct open_file *f, struct stat *sb)); diff --git a/sys/arch/mvmeppc/stand/libsa/tftpfs.c b/sys/arch/mvmeppc/stand/libsa/tftpfs.c new file mode 100644 index 00000000000..0b2e90759b1 --- /dev/null +++ b/sys/arch/mvmeppc/stand/libsa/tftpfs.c @@ -0,0 +1,291 @@ +/* $OpenBSD: tftpfs.c,v 1.1 2001/06/26 21:58:08 smurph Exp $ */ + +/*- + * Copyright (c) 2001 Steve Murphree, Jr. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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. + */ + +/* + * TFTP file system. + */ + +#include <sys/param.h> +#include <sys/time.h> +#include <sys/stat.h> +#include <ufs/ffs/fs.h> +#include <lib/libkern/libkern.h> + +#include "stand.h" + +/* + * In-core open file. + */ +struct tftp_file { + char filename[128]; + off_t f_seekp; /* seek pointer */ + char *f_buf; /* buffer for data block */ + off_t f_off; /* index into buffer for data block */ + daddr_t f_buf_blkno; /* block number of data block */ + size_t f_buf_size; +}; + +#define TFTP_BLOCK_SHIFT 9 +#define TFTP_BLOCK_SIZE (1<<TFTP_BLOCK_SHIFT) /* 512 by tftp convention */ +#define TFTP_BLOCK_NO(x) ((x >> TFTP_BLOCK_SHIFT) + 1) +#define TFTP_BLOCK_OFF(x) (x % TFTP_BLOCK_SIZE) + +static int read_inode __P((ino_t, struct open_file *)); +static int block_map __P((struct open_file *, daddr_t, daddr_t *)); +static int tftp_read_file __P((struct open_file *, char **, size_t *)); +#ifdef COMPAT_UFS +static void ffs_oldfscompat __P((struct fs *)); +#endif + +/* + * Read a portion of a file into an internal buffer. Return + * the location in the buffer and the amount in the buffer. + */ + +char tftp_buf[TFTP_BLOCK_SIZE]; /* static */ +struct tftp_file tftp_ctrl; + +static int +tftp_read_file(f, buf_p, size_p) + struct open_file *f; + char **buf_p; /* out */ + size_t *size_p; /* out */ +{ + register struct tftp_file *fp = (struct tftp_file *)f->f_fsdata; + long off; + register daddr_t file_block; + size_t block_size; + int i, rc; + + off = TFTP_BLOCK_OFF(fp->f_seekp); + file_block = TFTP_BLOCK_NO(fp->f_seekp); + block_size = TFTP_BLOCK_SIZE; + + if (file_block == fp->f_buf_blkno + 1) { + /* + * Normal, incremental block transfer. + */ + rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, + file_block, block_size, fp->f_buf, &fp->f_buf_size); + if (rc) + return (rc); + if (!(file_block % 4)) /* twiddle every 4 blocks */ + twiddle(); + fp->f_buf_blkno = file_block; + } else if (file_block > fp->f_buf_blkno + 1) { + /* + * Read ahead to the requested block; If we need + * those we skipped, see below. + */ + for (i = (fp->f_buf_blkno + 1); i <= file_block; i++) { + rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, + i, block_size, fp->f_buf, &fp->f_buf_size); + if (rc) + return (rc); + } + fp->f_buf_blkno = file_block; + } else if (file_block < fp->f_buf_blkno) { + /* + * Uh oh... We can't rewind. Reopen the file + * and start again. + */ + char filename[64]; + strcpy(filename, fp->filename); + tftpfs_close(f); + tftpfs_open(filename, f); + for (i = 1; i <= file_block; i++) { + rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, + i, block_size, fp->f_buf, &fp->f_buf_size); + if (rc) + return (rc); + } + fp->f_buf_blkno = file_block; + } + + /* + * Return address of byte in buffer corresponding to + * offset, and size of remainder of buffer after that + * byte. + */ + *buf_p = fp->f_buf + off; + *size_p = fp->f_buf_size - off; + + /* + * But truncate buffer at end of file. + */ + if (fp->f_buf_size > block_size){ + twiddle(); + return(EIO); + } + + + return (0); +} + +/* + * Open a file. + */ +int +tftpfs_open(path, f) + char *path; + struct open_file *f; +{ + struct tftp_file *fp; + int rc = 0; + + /* locate file system specific data structure and zero it.*/ + fp = &tftp_ctrl; + bzero(fp, sizeof(struct tftp_file)); + f->f_fsdata = (void *)fp; + fp->f_seekp = 0; + fp->f_buf = tftp_buf; + bzero(fp->f_buf, TFTP_BLOCK_SIZE); + fp->f_buf_size = 0; + + strcpy(fp->filename, path); + + if (f->f_dev->dv_open == NULL) { + panic("No device open()!"); + } + twiddle(); + rc = (f->f_dev->dv_open)(f, path); + return (rc); +} + +int +tftpfs_close(f) + struct open_file *f; +{ + register struct tftp_file *fp = (struct tftp_file *)f->f_fsdata; + + fp->f_buf = (void *)0; + f->f_fsdata = (void *)0; + (f->f_dev->dv_close)(f); + return (0); +} + +/* + * Copy a portion of a file into kernel memory. + * Cross block boundaries when necessary. + */ +int +tftpfs_read(f, start, size, resid) + struct open_file *f; + void *start; + size_t size; + size_t *resid; /* out */ +{ + register struct tftp_file *fp = (struct tftp_file *)f->f_fsdata; + register size_t csize; + char *buf; + size_t buf_size; + int rc = 0; + register char *addr = start; + + while (size != 0) { + rc = tftp_read_file(f, &buf, &buf_size); + if (rc) + break; + + csize = size; + if (csize > buf_size) + csize = buf_size; + + bcopy(buf, addr, csize); + + fp->f_seekp += csize; + addr += csize; + size -= csize; + } + if (resid) + *resid = size; + return (rc); +} + +/* + * Not implemented. + */ +int +tftpfs_write(f, start, size, resid) + struct open_file *f; + void *start; + size_t size; + size_t *resid; /* out */ +{ + + return (EROFS); +} + +/* + * We only see forward. We can't rewind. + */ +off_t +tftpfs_seek(f, offset, where) + struct open_file *f; + off_t offset; + int where; +{ + register struct tftp_file *fp = (struct tftp_file *)f->f_fsdata; + + switch (where) { + case SEEK_SET: + fp->f_seekp = offset; + break; + case SEEK_CUR: + fp->f_seekp += offset; + break; + case SEEK_END: + errno = EIO; + return (-1); + break; + default: + return (-1); + } + return (fp->f_seekp); +} + +int +tftpfs_stat(f, sb) + struct open_file *f; + struct stat *sb; +{ + return EIO; +} + +#ifndef NO_READDIR +int +tftpfs_readdir (struct open_file *f, char *name) +{ + return EIO; +} +#endif + diff --git a/sys/arch/mvmeppc/stand/libsa/tftpfs.h b/sys/arch/mvmeppc/stand/libsa/tftpfs.h new file mode 100644 index 00000000000..f8ea6c53c0a --- /dev/null +++ b/sys/arch/mvmeppc/stand/libsa/tftpfs.h @@ -0,0 +1,43 @@ +/* $OpenBSD: tftpfs.h,v 1.1 2001/06/26 21:58:08 smurph Exp $ */ + +/*- + * Copyright (c) 2001 Steve Murphree, Jr. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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. + */ + +int tftpfs_open __P((char *path, struct open_file *f)); +int tftpfs_close __P((struct open_file *f)); +int tftpfs_read __P((struct open_file *f, void *buf, + size_t size, size_t *resid)); +int tftpfs_write __P((struct open_file *f, void *buf, + size_t size, size_t *resid)); +off_t tftpfs_seek __P((struct open_file *f, off_t offset, int where)); +int tftpfs_stat __P((struct open_file *f, struct stat *sb)); +#ifndef NO_READDIR +int tftpfs_readdir __P((struct open_file *f, char *name)); +#endif diff --git a/sys/arch/mvmeppc/stand/libz/Makefile b/sys/arch/mvmeppc/stand/libz/Makefile new file mode 100644 index 00000000000..5dc7476587e --- /dev/null +++ b/sys/arch/mvmeppc/stand/libz/Makefile @@ -0,0 +1,8 @@ +# $OpenBSD: Makefile,v 1.1 2001/06/26 21:58:08 smurph Exp $ + +S=${.CURDIR}/../../../.. +ZDST=${.OBJDIR} + +.PATH: ${S}/lib/libz + +.include "${S}/lib/libz/Makefile" diff --git a/sys/arch/mvmeppc/stand/libz/Makefile.inc b/sys/arch/mvmeppc/stand/libz/Makefile.inc new file mode 100644 index 00000000000..c1d26bc509e --- /dev/null +++ b/sys/arch/mvmeppc/stand/libz/Makefile.inc @@ -0,0 +1,14 @@ +# $OpenBSD: Makefile.inc,v 1.1 2001/06/26 21:58:09 smurph Exp $ + +LIB_Z_DIR=${S}/arch/mvmeppc/stand/libz + +LIBZ_DIR!= cd ${LIB_Z_DIR}; \ + printf "xxx:\n\techo \$${.OBJDIR}\n" | ${MAKE} -r -s -f - xxx + +LIBZ=${LIBZ_DIR}/libz.a + +$(LIBZ): .NOTMAIN __always_make_libz + @echo making sure the libz is up to date... + @(cd ${LIB_Z_DIR}; ${MAKE} "XCFLAGS=${CFLAGS}") + +__always_make_libz: .NOTMAIN diff --git a/sys/arch/mvmeppc/stand/tftpboot/Makefile b/sys/arch/mvmeppc/stand/tftpboot/Makefile new file mode 100644 index 00000000000..7c248c806bf --- /dev/null +++ b/sys/arch/mvmeppc/stand/tftpboot/Makefile @@ -0,0 +1,45 @@ +# $OpenBSD: Makefile,v 1.1 2001/06/26 21:58:09 smurph Exp $ + +SIZE?= size +STRIP?= strip + +S= ${.CURDIR}/../../../.. +DEFS= -DSUN_BOOTPARAMS +#-DNETIF_DEBUG +INCPATH=-I${.CURDIR} -I${.CURDIR}/../libsa -I${.CURDIR}/../libbug \ + -I${S} -I${S}/lib/libsa +CFLAGS=-O2 ${DEFS} ${INCPATH} ${COPTS} +CLEANFILES+=tftpboot tftpboot.bin + +.include "${S}/arch/mvmeppc/stand/bugcrt/Makefile.inc" +.include "${S}/arch/mvmeppc/stand/libbug/Makefile.inc" +.include "${S}/arch/mvmeppc/stand/libsa/Makefile.inc" +.include "${S}/arch/mvmeppc/stand/libz/Makefile.inc" + +SRCS= boot.c version.c +#SRCS+= if_ie.c +#SRCS+= if_le.c +OBJS= ${SRCS:S/.c/.o/g} +LIBS= ${LIBSA} ${LIBBUG} ${LIBZ} ${LIBGCC} +LDFLAGS+= -s -X -N -Ttext ${STAGE1_RELOC} -e _start +#LDFLAGS+= -nostdlib -s -N -Ttext ${RELOC} + +all: tftpboot.bin + +tftpboot: ${OBJS} ${SINGLE} ${LIBS} + ${LD} ${LDFLAGS} \ + ${SINGLE} ${OBJS} ${LIBS} -o $@ +# @${SIZE} $@ + +tftpboot.bin: tftpboot + ${STRIP} tftpboot + dd ibs=96 skip=1 if=tftpboot of=$@ +# dd ibs=38 skip=1 if=tftpboot of=$@ + chown ${LIBOWN}.${LIBGRP} tftpboot.bin + chmod ${LIBMODE} tftpboot.bin + +install: + ${INSTALL} ${INSTALL_COPY} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ + tftpboot.bin ${DESTDIR}${MDEC_DIR}/tftpboot + +.include <bsd.prog.mk> diff --git a/sys/arch/mvmeppc/stand/tftpboot/boot.c b/sys/arch/mvmeppc/stand/tftpboot/boot.c new file mode 100644 index 00000000000..004be9af878 --- /dev/null +++ b/sys/arch/mvmeppc/stand/tftpboot/boot.c @@ -0,0 +1,120 @@ +/* $OpenBSD: boot.c,v 1.1 2001/06/26 21:58:10 smurph Exp $ */ +/*- + * Copyright (c) 1995 Theo de Raadt + * Copyright (c) 2001 Steve Murphree, Jr. + * 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 Theo de Raadt + * 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. + * + * Copyright (c) 1982, 1986, 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. 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, Berkeley and its contributors. + * 4. 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. + * + * @(#)boot.c 8.1 (Berkeley) 6/10/93 + */ + +#include <sys/param.h> +#include <sys/reboot.h> +#include <machine/prom.h> + +#include "stand.h" +#include "libsa.h" + + +/* + * Boot device is derived from ROM provided information. + */ +#define LOADADDR 0x10000 + +extern char *version; +char line[80]; + +main() +{ + char *cp, *file; + int ask = 0, howto, ret; + + /* cycle in the correct args */ + bugargs.arg_start = bugargs.nbarg_start; + bugargs.arg_end = bugargs.nbarg_end; + *bugargs.arg_end = 0; /* ensure */ + + bootdev_type = BUGDEV_NET; + + printf("\n>> OpenBSD/mvmeppc netboot [%s]\n", version); + + ret = parse_args(&file, &howto); + + for (;;) { + if (ask) { + printf("boot: "); + gets(line); + if (line[0]) { + bugargs.arg_start = line; + cp = line; + while (cp < (line + sizeof(line) - 1) && *cp) + cp++; + bugargs.arg_end = cp; + ret =parse_args(&file, &howto); + } + } + if (ret) { + printf("boot: -q returning to MVME-Bug\n"); + break; + } + exec_mvme(file, howto); + printf("boot: %s: %s\n", file, strerror(errno)); + ask = 1; + } +} diff --git a/sys/arch/mvmeppc/stand/tftpboot/version.c b/sys/arch/mvmeppc/stand/tftpboot/version.c new file mode 100644 index 00000000000..6d76885e63d --- /dev/null +++ b/sys/arch/mvmeppc/stand/tftpboot/version.c @@ -0,0 +1,8 @@ +/* $OpenBSD: version.c,v 1.1 2001/06/26 21:58:10 smurph Exp $ */ + +/* + * make a random change to this file when you want the bootblock + * revision to increase. like change this q to an x, or something. + */ + +char *version = "$Revision: 1.1 $"; |