Index: conf/Makefile.powerpc =================================================================== RCS file: Makefile.powerpc diff -N Makefile.powerpc --- /dev/null Tue Jun 5 21:44:00 2001 +++ Makefile.powerpc Tue Jun 5 21:04:24 2001 @@ -0,0 +1,348 @@ +# Makefile.powerpc -- with config changes. +# Copyright 1990 W. Jolitz +# from: @(#)Makefile.i386 7.1 5/10/91 +# $FreeBSD: src/sys/conf/Makefile.i386,v 1.214 2000/11/25 03:25:33 peter Exp $ +# +# Makefile for FreeBSD +# +# This makefile is constructed from a machine description: +# config machineid +# Most changes should be made in the machine description +# /sys/powerpc/conf/``machineid'' +# after which you should do +# config machineid +# Generic makefile changes should be made in +# /sys/powerpc/conf/Makefile.powerpc +# after which config should be rerun for all machines. +# + +# Which version of config(8) is required. +%VERSREQ= 500005 + +# Temporary stuff while we're still embryonic +NO_MODULES?= yes +CWARNFLAGS?= -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes \ + -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual \ + -ansi + +# Can be overridden by makeoptions or /etc/make.conf +KERNEL_KO?= kernel +KERNEL?= kernel +KODIR?= /boot/${KERNEL} +STD8X16FONT?= iso + +.if !defined(S) +.if exists(./@/.) +S= ./@ +.else +S= ../.. +.endif +.endif +M= ${MACHINE_ARCH} + +SIZE?= size +OBJCOPY?= objcopy + +COPTFLAGS?=-O +INCLUDES= -nostdinc -I- ${INCLMAGIC} -I. -I$S +# This hack is to allow kernel compiles to succeed on machines w/out srcdist +.if exists($S/../include) +INCLUDES+= -I$S/../include +.else +INCLUDES+= -I/home/benno/src/tmp/include +.endif + +# This hack lets us use the Intel ACPICA code without spamming a new +# include path into 100+ source files. +#INCLUDES+= -I$S/contrib/dev/acpica/Subsystem/Include + +# Don't know why I need to explicitly include -D__ELF__ here but I do +# otherwise linker sets don't work. +COPTS= ${INCLUDES} ${IDENT} -D_KERNEL -D__ELF__ -include opt_global.h +CFLAGS= ${COPTFLAGS} ${CWARNFLAGS} ${DEBUG} ${COPTS} + +# XXX LOCORE means "don't declare C stuff" not "for locore.s". +ASM_CFLAGS= -x assembler-with-cpp -DLOCORE ${CFLAGS} + +# Select the correct set of tools. Can't set OBJFORMAT here because it +# doesn't get exported into the environment, and if it were exported +# then it might break building of utilities. +FMT= -elf +CFLAGS+= ${FMT} + +DEFINED_PROF= ${PROF} +.if defined(PROF) +CFLAGS+= -malign-functions=4 +.if ${PROFLEVEL} >= 2 +IDENT+= -DGPROF4 -DGUPROF +PROF+= -mprofiler-epilogue +.endif +.endif + +# Put configuration-specific C flags last (except for ${PROF}) so that they +# can override the others. +CFLAGS+= ${CONF_CFLAGS} + +NORMAL_C= ${CC} -c ${CFLAGS} ${PROF} ${.IMPSRC} +NORMAL_C_C= ${CC} -c ${CFLAGS} ${PROF} ${.IMPSRC} +NORMAL_S= ${CC} -c ${ASM_CFLAGS} ${.IMPSRC} +PROFILE_C= ${CC} -c ${CFLAGS} ${.IMPSRC} + +NORMAL_M= perl5 $S/kern/makeobjops.pl -c $< ; \ + ${CC} -c ${CFLAGS} ${PROF} ${.PREFIX}.c + +GEN_CFILES= $S/$M/$M/genassym.c +# setdef0.c and setdef1.c are intentionally +# omitted from SYSTEM_CFILES. They include setdefs.h, a header which +# is generated from all of ${OBJS}. We don't want to have to compile +# everything just to do a make depend. +SYSTEM_CFILES= param.c vnode_if.c hints.c config.c +SYSTEM_SFILES= $S/$M/$M/locore.s +SYSTEM_DEP= Makefile ${SYSTEM_OBJS} +SYSTEM_OBJS= locore.o setdef0.o vnode_if.o ${OBJS} param.o hints.o config.o \ + setdef1.o hack.So +SYSTEM_LD= @${LD} ${FMT} -Bdynamic -T $S/conf/ldscript.$M \ + -export-dynamic -dynamic-linker /red/herring \ + -o ${.TARGET} -X ${SYSTEM_OBJS} vers.o +SYSTEM_LD_TAIL= @${OBJCOPY} --strip-symbol gcc2_compiled. ${.TARGET} ; \ + ${SIZE} ${.TARGET} ; chmod 755 ${.TARGET} +SYSTEM_DEP+= $S/conf/ldscript.$M + +%BEFORE_DEPEND + +%OBJS + +%FILES.c + +%FILES.s + +%FILES.m + +%CLEAN + +.PHONY: all modules + +all: ${KERNEL_KO} + +depend: kernel-depend +clean: kernel-clean +cleandepend: kernel-cleandepend +tags: kernel-tags +install install.debug: kernel-install +reinstall reinstall.debug: kernel-reinstall + +.if !defined(DEBUG) +FULLKERNEL= ${KERNEL_KO} +.else +FULLKERNEL= ${KERNEL_KO}.debug +${KERNEL_KO}: ${FULLKERNEL} + ${OBJCOPY} --strip-debug ${FULLKERNEL} ${KERNEL_KO} +.endif + +${FULLKERNEL}: ${SYSTEM_DEP} vers.o + @rm -f ${.TARGET} + @echo linking ${.TARGET} + ${SYSTEM_LD} + ${SYSTEM_LD_TAIL} + +.if !exists(.depend) +${SYSTEM_OBJS}: vnode_if.h ${BEFORE_DEPEND:M*.h} ${MFILES:T:S/.m$/.h/} +.endif + +.for mfile in ${MFILES} +${mfile:T:S/.m$/.h/}: ${mfile} + perl5 $S/kern/makeobjops.pl -h ${mfile} +.endfor + +kernel-clean: + rm -f *.o *.so *.So *.ko *.s eddep errs \ + ${FULLKERNEL} ${KERNEL_KO} linterrs makelinks param.c \ + setdef[01].c setdefs.h tags \ + vers.c vnode_if.c vnode_if.h \ + ${MFILES:T:S/.m$/.c/} ${MFILES:T:S/.m$/.h/} \ + ${CLEAN} + +#lint: /tmp param.c +# @lint -hbxn -DGENERIC -Dvolatile= ${COPTS} \ +# $S/$M/$M/Locore.c ${CFILES} param.c | \ +# grep -v 'struct/union .* never defined' | \ +# grep -v 'possible pointer alignment problem' + +locore.o: $S/$M/$M/locore.s assym.s + ${NORMAL_S} + +# This is a hack. BFD "optimizes" away dynamic mode if there are no +# dynamic references. We could probably do a '-Bforcedynamic' mode like +# in the a.out ld. For now, this works. +hack.So: Makefile + touch hack.c + ${CC} ${FMT} -shared -nostdlib hack.c -o hack.So + rm -f hack.c + +.ORDER: setdefs.h setdef0.c setdef1.c + +setdef0.o: setdef0.c setdefs.h + ${NORMAL_C} + +setdef1.o: setdef1.c setdefs.h + ${NORMAL_C} + +setdef0.c setdef1.c setdefs.h: Makefile ${OBJS} + @gensetdefs ${OBJS} + +# this rule stops ./assym.s in .depend from causing problems +./assym.s: assym.s + +assym.s: $S/kern/genassym.sh genassym.o + sh $S/kern/genassym.sh genassym.o > ${.TARGET} + +genassym.o: $S/$M/$M/genassym.c + ${CC} -c ${CFLAGS} $S/$M/$M/genassym.c + +${SYSTEM_OBJS} genassym.o vers.o: opt_global.h + +kernel-depend: assym.s param.c vnode_if.h ${BEFORE_DEPEND} \ + ${CFILES} ${SYSTEM_CFILES} ${GEN_CFILES} ${SFILES} \ + ${SYSTEM_SFILES} ${MFILES:T:S/.m$/.h/} + rm -f .newdep + mkdep -a -f .newdep ${CFLAGS} ${CFILES} ${SYSTEM_CFILES} ${GEN_CFILES} + env MKDEP_CPP="${CC} -E" \ + mkdep -a -f .newdep ${ASM_CFLAGS} ${SFILES} ${SYSTEM_SFILES} + rm -f .depend + mv -f .newdep .depend + +kernel-cleandepend: + rm -f .depend + +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 + +kernel-tags: + @[ -f .depend ] || { echo "you must make depend first"; exit 1; } + sh $S/conf/systags.sh + rm -f tags1 + sed -e 's, ../, ,' tags > tags1 + +kernel-install kernel-install.debug: +.if exists(${DESTDIR}/boot) + @if [ ! -f ${DESTDIR}/boot/device.hints ] ; then \ + echo "You must set up a ${DESTDIR}/boot/device.hints file first." ; \ + exit 1 ; \ + fi + @if [ x"`grep device.hints ${DESTDIR}/boot/defaults/loader.conf ${DESTDIR}/boot/loader.conf`" = "x" ]; then \ + echo "You must activate /boot/device.hints in loader.conf." ; \ + exit 1 ; \ + fi +.endif + @if [ ! -f ${KERNEL_KO}${.TARGET:S/kernel-install//} ] ; then \ + echo "You must build a kernel first." ; \ + exit 1 ; \ + fi +.if exists(${DESTDIR}${KODIR}) +.if exists(${DESTDIR}${KODIR}.old) + @-chflags -R noschg ${DESTDIR}${KODIR}.old + -rm -rf ${DESTDIR}${KODIR}.old +.endif + mv ${DESTDIR}${KODIR} ${DESTDIR}${KODIR}.old +.endif + mkdir -p ${DESTDIR}${KODIR} + @if [ -f ${DESTDIR}${KODIR}/${KERNEL_KO} ] ; then \ + chflags noschg ${DESTDIR}${KODIR}/${KERNEL_KO} ; \ + fi + install -c -m 555 -o root -g wheel -fschg \ + ${KERNEL_KO}${.TARGET:S/kernel-install//} ${DESTDIR}${KODIR} + +kernel-reinstall kernel-reinstall.debug: + @if [ -f ${DESTDIR}${KODIR}/${KERNEL_KO} ] ; then \ + chflags noschg ${DESTDIR}${KODIR}/${KERNEL_KO} ; \ + fi + install -c -m 555 -o root -g wheel -fschg \ + ${KERNEL_KO}${.TARGET:S/kernel-reinstall//} ${DESTDIR}${KODIR} + +.if !defined(MODULES_WITH_WORLD) && !defined(NO_MODULES) && exists($S/modules) +all: modules +depend: modules-depend +clean: modules-clean +cleandepend: modules-cleandepend +cleandir: modules-cleandir +tags: modules-tags +install install.debug: modules-install +reinstall reinstall.debug: modules-reinstall +.endif + +MKMODULESENV= MAKEOBJDIRPREFIX=${.OBJDIR}/modules KMODDIR=${KODIR} + +modules: + @mkdir -p ${.OBJDIR}/modules + cd $S/modules ; env ${MKMODULESENV} ${MAKE} obj ; \ + env ${MKMODULESENV} ${MAKE} all + +modules-depend: + @mkdir -p ${.OBJDIR}/modules + cd $S/modules ; env ${MKMODULESENV} ${MAKE} obj ; \ + env ${MKMODULESENV} ${MAKE} depend + +modules-clean: + cd $S/modules ; env ${MKMODULESENV} ${MAKE} clean + +modules-cleandepend: + cd $S/modules ; env ${MKMODULESENV} ${MAKE} cleandepend + +modules-cleandir: + cd $S/modules ; env ${MKMODULESENV} ${MAKE} cleandir + +modules-tags: + cd $S/modules ; env ${MKMODULESENV} ${MAKE} tags + +modules-install modules-install.debug: + cd $S/modules ; env ${MKMODULESENV} ${MAKE} install + +modules-reinstall modules-reinstall.debug: + cd $S/modules ; env ${MKMODULESENV} ${MAKE} install + +config.o: + ${NORMAL_C} + +param.c: $S/conf/param.c + -rm -f param.c + cp $S/conf/param.c . + +param.o: + ${NORMAL_C} + +vers.c: $S/conf/newvers.sh $S/sys/param.h ${SYSTEM_DEP} + sh $S/conf/newvers.sh ${KERN_IDENT} ${IDENT} + +# XXX strictly, everything depends on Makefile because changes to ${PROF} +# only appear there, but we don't handle that. +vers.o: + ${NORMAL_C} + +hints.o: hints.c + ${NORMAL_C} + +vnode_if.c: $S/kern/vnode_if.pl $S/kern/vnode_if.src + perl5 $S/kern/vnode_if.pl -c $S/kern/vnode_if.src + +vnode_if.h: $S/kern/vnode_if.pl $S/kern/vnode_if.src + perl5 $S/kern/vnode_if.pl -h $S/kern/vnode_if.src + +vnode_if.o: + ${NORMAL_C} + +# Commented out for now pending a better solution. +# How do we pick up compiler version specific flags?? +#.if exists($S/../share/mk) +#.include "$S/../share/mk/bsd.kern.mk" +#.else +.include +#.endif + +%RULES + +# DO NOT DELETE THIS LINE -- make depend uses it Index: conf/files.powerpc =================================================================== RCS file: files.powerpc diff -N files.powerpc --- /dev/null Tue Jun 5 21:44:00 2001 +++ files.powerpc Tue Jun 5 21:44:28 2001 @@ -0,0 +1,52 @@ +# This file tells config what files go into building a kernel, +# files marked standard are always included. +# +# $FreeBSD: src/sys/conf/files.alpha,v 1.61 2000/12/02 04:17:19 gallatin Exp $ +# +# The long compile-with and dependency lines are required because of +# limitations in config: backslash-newline doesn't work in strings, and +# dependency lines other than the first are silently ignored. +# +# +kern/subr_diskmbr.c standard + +powerpc/powerpc/atomic.s standard +powerpc/powerpc/autoconf.c standard +powerpc/powerpc/bcopy.c standard +powerpc/powerpc/clock.c standard +powerpc/powerpc/copyinstr.c standard +powerpc/powerpc/copystr.c standard +powerpc/powerpc/elf_machdep.c standard +powerpc/powerpc/fubyte.c standard +powerpc/powerpc/fuswintr.c standard +powerpc/powerpc/fuword.c standard +powerpc/powerpc/machdep.c standard +powerpc/powerpc/ofwmagic.s standard +powerpc/powerpc/ofw_machdep.c standard +powerpc/powerpc/pmap.c standard +powerpc/powerpc/procfs_machdep.c standard +powerpc/powerpc/subyte.c standard +powerpc/powerpc/suswintr.c standard +powerpc/powerpc/suword.c standard +powerpc/powerpc/syncicache.c standard +powerpc/powerpc/sys_machdep.c standard +powerpc/powerpc/swtch.s standard +powerpc/powerpc/trap.c standard +powerpc/powerpc/vm_machdep.c standard + +dev/ofw/openfirm.c standard +dev/ofw/ofw_console.c standard + +libkern/ashldi3.c standard +libkern/ashrdi3.c standard +libkern/bcmp.c standard +libkern/divdi3.c standard +libkern/ffs.c standard +libkern/lshrdi3.c standard +libkern/moddi3.c standard +libkern/qdivrem.c standard +libkern/ucmpdi2.c standard +libkern/udivdi3.c standard +libkern/umoddi3.c standard + +powerpc/powerpc/mp_machdep.c optional smp Index: conf/ldscript.powerpc =================================================================== RCS file: ldscript.powerpc diff -N ldscript.powerpc --- /dev/null Tue Jun 5 21:44:00 2001 +++ ldscript.powerpc Sun May 6 15:29:50 2001 @@ -0,0 +1,150 @@ +OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", + "elf32-powerpc") +OUTPUT_ARCH(powerpc) +ENTRY(start) +SEARCH_DIR(/usr/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +PROVIDE (__stack = 0); +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0x00100000 + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rela.text : + { *(.rela.text) *(.rela.gnu.linkonce.t*) } + .rela.data : + { *(.rela.data) *(.rela.gnu.linkonce.d*) } + .rela.rodata : + { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } + .rela.got : { *(.rela.got) } + .rela.got1 : { *(.rela.got1) } + .rela.got2 : { *(.rela.got2) } + .rela.ctors : { *(.rela.ctors) } + .rela.dtors : { *(.rela.dtors) } + .rela.init : { *(.rela.init) } + .rela.fini : { *(.rela.fini) } + .rela.bss : { *(.rela.bss) } + .rela.plt : { *(.rela.plt) } + .rela.sdata : { *(.rela.sdata) } + .rela.sbss : { *(.rela.sbss) } + .rela.sdata2 : { *(.rela.sdata2) } + .rela.sbss2 : { *(.rela.sbss2) } + .text : + { + *(.text) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.gnu.linkonce.t*) + } =0 + .init : { *(.init) } =0 + .fini : { *(.fini) } =0 + .rodata : { *(.rodata) *(.gnu.linkonce.r*) } + .rodata1 : { *(.rodata1) } + _etext = .; + PROVIDE (etext = .); + .sdata2 : { *(.sdata2) } + .sbss2 : { *(.sbss2) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. It would + be more correct to do this: + . = .; + The current expression does not correctly handle the case of a + text segment ending precisely at the end of a page; it causes the + data segment to skip a page. The above expression does not have + this problem, but it will currently (2/95) cause BFD to allocate + a single segment, combining both text and data, for this case. + This will prevent the text segment from being shared among + multiple executions of the program; I think that is more + important than losing a page of the virtual address space (note + that no actual memory is lost; the page which is skipped can not + be referenced). */ + . = .; + .data : + { + *(.data) + *(.gnu.linkonce.d*) + CONSTRUCTORS + } + .data1 : { *(.data1) } + .got1 : { *(.got1) } + .dynamic : { *(.dynamic) } + /* Put .ctors and .dtors next to the .got2 section, so that the pointers + get relocated with -mrelocatable. Also put in the .fixup pointers. + The current compiler no longer needs this, but keep it around for 2.7.2 */ + PROVIDE (_GOT2_START_ = .); + .got2 : { *(.got2) } + PROVIDE (__CTOR_LIST__ = .); + .ctors : { *(.ctors) } + PROVIDE (__CTOR_END__ = .); + PROVIDE (__DTOR_LIST__ = .); + .dtors : { *(.dtors) } + PROVIDE (__DTOR_END__ = .); + PROVIDE (_FIXUP_START_ = .); + .fixup : { *(.fixup) } + PROVIDE (_FIXUP_END_ = .); + PROVIDE (_GOT2_END_ = .); + PROVIDE (_GOT_START_ = .); + .got : { *(.got) } + .got.plt : { *(.got.plt) } + PROVIDE (_GOT_END_ = .); + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { *(.sdata) } + _edata = .; + PROVIDE (edata = .); + .sbss : + { + PROVIDE (__sbss_start = .); + *(.sbss) + *(.scommon) + *(.dynsbss) + PROVIDE (__sbss_end = .); + } + .plt : { *(.plt) } + .bss : + { + PROVIDE (__bss_start = .); + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); + /* These are needed for ELF backends which have not yet been + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* These must appear regardless of . */ +} Index: conf/options.powerpc =================================================================== RCS file: options.powerpc diff -N options.powerpc --- /dev/null Tue Jun 5 21:44:00 2001 +++ options.powerpc Sat Dec 16 14:20:36 2000 @@ -0,0 +1,7 @@ +# $FreeBSD: src/sys/conf/options.alpha,v 1.26 2000/12/02 04:17:19 gallatin Exp $ + +MPC750 opt_global.h +IPKDB opt_ipkdb.h + +SHOW_BUSYBUFS +PANIC_REBOOT_WAIT_TIME opt_panic.h Index: dev/ofw/ofw_console.c =================================================================== RCS file: ofw_console.c diff -N ofw_console.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ ofw_console.c Tue Jun 5 21:09:44 2001 @@ -0,0 +1,297 @@ +/* $FreeBSD */ + +/* + * Copyright (C) 2001 Benno Rice. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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 +#include +#include +#include +#include +#include +#include +#include + +#include + +#define OFW_POLL_HZ 50 + +static d_open_t ofw_dev_open; +static d_close_t ofw_dev_close; +static d_ioctl_t ofw_dev_ioctl; + +#define CDEV_MAJOR 97 + +static struct cdevsw ofw_cdevsw = { + /* open */ ofw_dev_open, + /* close */ ofw_dev_close, + /* read */ ttyread, + /* write */ ttywrite, + /* ioctl */ ofw_dev_ioctl, + /* poll */ ttypoll, + /* mmap */ nommap, + /* strategy */ nostrategy, + /* name */ "ofw", + /* major */ CDEV_MAJOR, + /* dump */ nodump, + /* psize */ nopsize, + /* flags */ 0, +}; + +static struct tty *ofw_tp = NULL; +static int polltime; +static struct callout_handle ofw_timeouthandle + = CALLOUT_HANDLE_INITIALIZER(&ofw_timeouthandle); + +static void ofw_tty_start(struct tty *); +static int ofw_tty_param(struct tty *, struct termios *); +static void ofw_tty_stop(struct tty *, int); +static void ofw_timeout(void *); + +static cn_probe_t ofw_cons_probe; +static cn_init_t ofw_cons_init; +static cn_getc_t ofw_cons_getc; +static cn_checkc_t ofw_cons_checkc; +static cn_putc_t ofw_cons_putc; + +CONS_DRIVER(ofw, ofw_cons_probe, ofw_cons_init, NULL, ofw_cons_getc, + ofw_cons_checkc, ofw_cons_putc, NULL); + +static int stdin; +static int stdout; + +static int +ofw_dev_open(dev_t dev, int flag, int mode, struct proc *p) +{ + struct tty *tp; + int unit; + int error, setuptimeout; + + error = 0; + setuptimeout = 0; + unit = minor(dev); + + tp = ofw_tp = dev->si_tty = ttymalloc(ofw_tp); + + tp->t_oproc = ofw_tty_start; + tp->t_param = ofw_tty_param; + tp->t_stop = ofw_tty_stop; + tp->t_dev = dev; + + if ((tp->t_state & TS_ISOPEN) == 0) { + tp->t_state |= TS_CARR_ON; + ttychars(tp); + tp->t_iflag = TTYDEF_IFLAG; + tp->t_oflag = TTYDEF_OFLAG; + tp->t_cflag = TTYDEF_CFLAG|CLOCAL; + tp->t_lflag = TTYDEF_LFLAG; + tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; + ttsetwater(tp); + + setuptimeout = 1; + } else if ((tp->t_state & TS_XCLUDE) && suser(p)) { + return (EBUSY); + } + + error = (*linesw[tp->t_line].l_open)(dev, tp); + + if (error == 0 && setuptimeout) { + polltime = hz / OFW_POLL_HZ; + if (polltime < 1) { + polltime = 1; + } + + ofw_timeouthandle = timeout(ofw_timeout, tp, polltime); + } + + return (error); +} + +static int +ofw_dev_close(dev_t dev, int flag, int mode, struct proc *p) +{ + int unit; + struct tty *tp; + + unit = minor(dev); + tp = ofw_tp; + + if (unit != 0) { + return (ENXIO); + } + + (*linesw[tp->t_line].l_close)(tp, flag); + ttyclose(tp); + + return (0); +} + +static int +ofw_dev_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) +{ + int unit; + struct tty *tp; + int error; + + unit = minor(dev); + if (unit != 0) { + return (ENXIO); + } + + error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); + if (error != ENOIOCTL) { + return (error); + } + + error = ttioctl(tp, cmd, data, flag); + if (error != ENOIOCTL) { + return (error); + } + + return (ENOTTY); +} + +static int +ofw_tty_param(struct tty *tp, struct termios *t) +{ + return (0); +} + +static void +ofw_tty_start(struct tty *tp) +{ + if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { + ttwwakeup(tp); + return; + } + + tp->t_state |= TS_BUSY; + while (tp->t_outq.c_cc != 0) { + ofw_cons_putc(tp->t_dev, getc(&tp->t_outq)); + } + tp->t_state &= ~TS_BUSY; + + ttwwakeup(tp); +} + +static void +ofw_tty_stop(struct tty *tp, int flag) +{ + if (tp->t_state & TS_BUSY) { + if ((tp->t_state & TS_TTSTOP) == 0) { + tp->t_state |= TS_FLUSH; + } + } +} + +static void +ofw_timeout(void *v) +{ + struct tty *tp; + int c; + + tp = (struct tty *)v; + + while ((c = ofw_cons_checkc(tp->t_dev)) != -1) { + if (tp->t_state & TS_ISOPEN) { + (*linesw[tp->t_line].l_rint)(c, tp); + } + } + + ofw_timeouthandle = timeout(ofw_timeout, tp, polltime); +} + +static void +ofw_cons_probe(struct consdev *cp) +{ + int chosen; + + if ((chosen = OF_finddevice("/chosen")) == -1) { + cp->cn_pri = CN_DEAD; + return; + } + + if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) == -1) { + cp->cn_pri = CN_DEAD; + return; + } + + if (OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) == -1) { + cp->cn_pri = CN_DEAD; + return; + } + + cp->cn_dev = makedev(CDEV_MAJOR, 0); + cp->cn_pri = CN_INTERNAL; + cp->cn_tp = ofw_tp; + make_dev(&ofw_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "ofwcons"); +} + +static void +ofw_cons_init(struct consdev *cp) +{ + return; +} + +static int +ofw_cons_getc(dev_t dev) +{ + unsigned char ch = '\0'; + int l; + + while ((l = OF_read(stdin, &ch, 1)) != 1) { + if (l != -2 && l != 0) { + return (-1); + } + } + + return (ch); +} + +static int +ofw_cons_checkc(dev_t dev) +{ + unsigned char ch; + + if (OF_read(stdin, &ch, 1) != 0) { + return (ch); + } + + return (-1); +} + +static void +ofw_cons_putc(dev_t dev, int c) +{ + char cbuf; + + if (c == '\n') { + cbuf = '\r'; + OF_write(stdout, &cbuf, 1); + } + + cbuf = c; + OF_write(stdout, &cbuf, 1); +} Index: dev/ofw/openfirm.c =================================================================== RCS file: openfirm.c diff -N openfirm.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ openfirm.c Tue Jun 5 21:20:55 2001 @@ -0,0 +1,786 @@ +/* $NetBSD: Locore.c,v 1.7 2000/08/20 07:04:59 tsubai 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. + */ +/* + * Copyright (C) 2000 Benno Rice. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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. + * + * $FreeBSD: src/sys/boot/ofw/libofw/openfirm.c,v 1.2 2000/11/10 06:39:54 benno Exp $ + */ + +#include + +#include + +#include + +static ihandle_t stdin; +static ihandle_t stdout; + +char *OF_buf; + +void ofbcopy(const void *, void *, size_t); + +/* Initialiaser */ + +void +OF_init(int (*openfirm)(void *)) +{ + phandle_t chosen; + + set_openfirm_callback(openfirm); + if ((chosen = OF_finddevice("/chosen")) == -1) + OF_exit(); + OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)); + OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)); +} + +void +OF_printf(const char *fmt, ...) +{ + va_list va; + char buf[1024]; + + va_start(va, fmt); + vsprintf(buf, fmt, va); + OF_write(stdout, buf, strlen(buf)); + va_end(va); +} + +/* + * Generic functions + */ + +/* Test to see if a service exists. */ +int +OF_test(char *name) +{ + static struct { + char *name; + int nargs; + int nreturns; + char *service; + int missing; + } args = { + "test", + 1, + 1, + }; + + args.service = name; + if (openfirmware(&args) == -1) + return -1; + return args.missing; +} + +/* Return firmware millisecond count. */ +int +OF_milliseconds() +{ + static struct { + char *name; + int nargs; + int nreturns; + int ms; + } args = { + "milliseconds", + 0, + 1, + }; + + openfirmware(&args); + return args.ms; +} + +/* + * Device tree functions + */ + +/* Return the next sibling of this node or 0. */ +phandle_t +OF_peer(phandle_t node) +{ + static struct { + char *name; + int nargs; + int nreturns; + phandle_t node; + phandle_t next; + } args = { + "peer", + 1, + 1, + }; + + args.node = node; + if (openfirmware(&args) == -1) + return -1; + return args.next; +} + +/* Return the first child of this node or 0. */ +phandle_t +OF_child(phandle_t node) +{ + static struct { + char *name; + int nargs; + int nreturns; + phandle_t node; + phandle_t child; + } args = { + "child", + 1, + 1, + }; + + args.node = node; + if (openfirmware(&args) == -1) + return -1; + return args.child; +} + +/* Return the parent of this node or 0. */ +phandle_t +OF_parent(phandle_t node) +{ + static struct { + char *name; + int nargs; + int nreturns; + phandle_t node; + phandle_t parent; + } args = { + "parent", + 1, + 1, + }; + + args.node = node; + if (openfirmware(&args) == -1) + return -1; + return args.parent; +} + +/* Return the package handle that corresponds to an instance handle. */ +phandle_t +OF_instance_to_package(ihandle_t instance) +{ + static struct { + char *name; + int nargs; + int nreturns; + ihandle_t instance; + phandle_t package; + } args = { + "instance-to-package", + 1, + 1, + }; + + args.instance = instance; + if (openfirmware(&args) == -1) + return -1; + return args.package; +} + +/* Get the length of a property of a package. */ +int +OF_getproplen(phandle_t package, char *propname) +{ + static struct { + char *name; + int nargs; + int nreturns; + phandle_t package; + char *propname; + int proplen; + } args = { + "getproplen", + 2, + 1, + }; + + args.package = package; + args.propname = propname; + if (openfirmware(&args) == -1) + return -1; + + return args.proplen; +} + +/* Get the value of a property of a package. */ +int +OF_getprop(phandle_t package, char *propname, void *buf, int buflen) +{ + static struct { + char *name; + int nargs; + int nreturns; + phandle_t package; + char *propname; + void *buf; + int buflen; + int size; + } args = { + "getprop", + 4, + 1, + }; + + args.package = package; + args.propname = propname; + args.buf = buf; + args.buflen = buflen; + if (openfirmware(&args) == -1) + return -1; + + return args.size; +} + +/* Get the next property of a package. */ +int +OF_nextprop(phandle_t package, char *previous, char *buf) +{ + static struct { + char *name; + int nargs; + int nreturns; + phandle_t package; + char *previous; + char *buf; + int flag; + } args = { + "nextprop", + 3, + 1, + }; + + args.package = package; + args.previous = previous; + args.buf = buf; + if (openfirmware(&args) == -1) + return -1; + return args.flag; +} + +/* Set the value of a property of a package. */ +/* XXX Has a bug on FirePower */ +int +OF_setprop(phandle_t package, char *propname, void *buf, int len) +{ + static struct { + char *name; + int nargs; + int nreturns; + phandle_t package; + char *propname; + void *buf; + int len; + int size; + } args = { + "setprop", + 4, + 1, + }; + + args.package = package; + args.propname = propname; + args.buf = buf; + args.len = len; + if (openfirmware(&args) == -1) + return -1; + return args.size; +} + +/* Convert a device specifier to a fully qualified pathname. */ +int +OF_canon(char *device, char *buf, int len) +{ + static struct { + char *name; + int nargs; + int nreturns; + char *device; + char *buf; + int len; + int size; + } args = { + "canon", + 3, + 1, + }; + + args.device = (char *)(uintptr_t *)device; + args.buf = buf; + args.len = len; + if (openfirmware(&args) == -1) + return -1; + return args.size; +} + +/* Return a package handle for the specified device. */ +phandle_t +OF_finddevice(char *device) +{ + static struct { + char *name; + int nargs; + int nreturns; + char *device; + phandle_t package; + } args = { + "finddevice", + 1, + 1, + }; + + args.device = (char *)(uintptr_t *)device; + if (openfirmware(&args) == -1) + return -1; + return args.package; +} + +/* Return the fully qualified pathname corresponding to an instance. */ +int +OF_instance_to_path(ihandle_t instance, char *buf, int len) +{ + static struct { + char *name; + int nargs; + int nreturns; + ihandle_t instance; + char *buf; + int len; + int size; + } args = { + "instance-to-path", + 3, + 1, + }; + + args.instance = instance; + args.buf = buf; + args.len = len; + if (openfirmware(&args) == -1) + return -1; + return(args.size); +} + +/* Return the fully qualified pathname corresponding to a package. */ +int +OF_package_to_path(phandle_t package, char *buf, int len) +{ + static struct { + char *name; + int nargs; + int nreturns; + phandle_t package; + char *buf; + int len; + int size; + } args = { + "package-to-path", + 3, + 1, + }; + + args.package = package; + args.buf = buf; + args.len = len; + if (openfirmware(&args) == -1) + return -1; + return(args.size); +} + +/* Call the method in the scope of a given instance. */ +int +OF_call_method(char *method, ihandle_t instance, int nargs, int nreturns, ...) +{ + va_list ap; + static struct { + char *name; + int nargs; + int nreturns; + char *method; + ihandle_t instance; + int args_n_results[12]; + } args = { + "call-method", + 2, + 1, + }; + int *ip, n; + + if (nargs > 6) + return -1; + + args.nargs = nargs + 2; + args.nreturns = nreturns + 1; + args.method = method; + args.instance = instance; + va_start(ap, nreturns); + for (ip = args.args_n_results + (n = nargs); --n >= 0;) + *--ip = va_arg(ap, int); + + if (openfirmware(&args) == -1) + return -1; + if (args.args_n_results[nargs]) + return args.args_n_results[nargs]; + for (ip = args.args_n_results + nargs + (n = args.nreturns); --n > 0;) + *va_arg(ap, int *) = *--ip; + va_end(ap); + return 0; +} + +/* + * Device I/O functions. + */ + +/* Open an instance for a device. */ +ihandle_t +OF_open(char *device) +{ + static struct { + char *name; + int nargs; + int nreturns; + char *device; + ihandle_t instance; + } args = { + "open", + 1, + 1, + }; + + args.device = device; + if (openfirmware(&args) == -1 || args.instance == 0) { + return -1; + } + return args.instance; +} + +/* Close an instance. */ +void +OF_close(ihandle_t instance) +{ + static struct { + char *name; + int nargs; + int nreturns; + ihandle_t instance; + } args = { + "close", + 1, + 0, + }; + + args.instance = instance; + openfirmware(&args); +} + +/* Read from an instance. */ +int +OF_read(ihandle_t instance, void *addr, int len) +{ + static struct { + char *name; + int nargs; + int nreturns; + ihandle_t instance; + void *addr; + int len; + int actual; + } args = { + "read", + 3, + 1, + }; + + args.instance = instance; + args.addr = addr; + args.len = len; + +#if defined(OPENFIRM_DEBUG) + printf("OF_read: called with instance=%08x, addr=%p, len=%d\n", + args.instance, args.addr, args.len); +#endif + + if (openfirmware(&args) == -1) + return -1; + +#if defined(OPENFIRM_DEBUG) + printf("OF_read: returning instance=%d, addr=%p, len=%d, actual=%d\n", + args.instance, args.addr, args.len, args.actual); +#endif + + return args.actual; +} + +/* Write to an instance. */ +int +OF_write(ihandle_t instance, void *addr, int len) +{ + static struct { + char *name; + int nargs; + int nreturns; + ihandle_t instance; + void *addr; + int len; + int actual; + } args = { + "write", + 3, + 1, + }; + + args.instance = instance; + args.addr = addr; + args.len = len; + if (openfirmware(&args) == -1) + return -1; + + return args.actual; +} + +/* Seek to a position. */ +int +OF_seek(ihandle_t instance, u_int64_t pos) +{ + static struct { + char *name; + int nargs; + int nreturns; + ihandle_t instance; + int poshi; + int poslo; + int status; + } args = { + "seek", + 3, + 1, + }; + + args.instance = instance; + args.poshi = (int)(pos >> 32); + args.poslo = (int)pos; + if (openfirmware(&args) == -1) + return -1; + return args.status; +} + +/* + * Memory functions. + */ + +/* Claim an area of memory. */ +void * +OF_claim(void *virt, u_int size, u_int align) +{ + static struct { + char *name; + int nargs; + int nreturns; + void *virt; + u_int size; + u_int align; + void *baseaddr; + } args = { + "claim", + 3, + 1, + }; + + args.virt = virt; + args.size = size; + args.align = align; + if (openfirmware(&args) == -1) + return (void *)-1; + return args.baseaddr; +} + +/* Release an area of memory. */ +void +OF_release(void *virt, u_int size) +{ + static struct { + char *name; + int nargs; + int nreturns; + void *virt; + u_int size; + } args = { + "release", + 2, + 0, + }; + + args.virt = virt; + args.size = size; + openfirmware(&args); +} + +/* + * Control transfer functions. + */ + +/* Reset the system and call "boot ". */ +void +OF_boot(char *bootspec) +{ + static struct { + char *name; + int nargs; + int nreturns; + char *bootspec; + } args = { + "boot", + 1, + 0, + }; + + args.bootspec = bootspec; + openfirmware(&args); + for (;;); /* just in case */ +} + +/* Suspend and drop back to the OpenFirmware interface. */ +void +OF_enter() +{ + static struct { + char *name; + int nargs; + int nreturns; + } args = { + "enter", + 0, + 0 + }; + + openfirmware(&args); + return; /* We may come back. */ +} + +/* Shut down and drop back to the OpenFirmware interface. */ +void +OF_exit() +{ + static struct { + char *name; + int nargs; + int nreturns; + } args = { + "exit", + 0, + 0 + }; + + openfirmware(&args); + for (;;); /* just in case */ +} + +/* Free bytes starting at , then call with . */ +#ifdef __notyet__ +void +OF_chain(void *virt, u_int size, void (*entry)(), void *arg, u_int len) +{ + static struct { + char *name; + int nargs; + int nreturns; + void *virt; + u_int size; + void (*entry)(); + void *arg; + u_int len; + } args = { + "chain", + 5, + 0, + }; + + args.virt = virt; + args.size = size; + args.entry = entry; + args.arg = arg; + args.len = len; + openfirmware(&args); +} +#else +void +OF_chain(void *virt, u_int size, + void (*entry)(void *, u_int, void *, void *, u_int), void *arg, u_int len) +{ + /* + * This is a REALLY dirty hack till the firmware gets this going + */ +#if 0 + OF_release(virt, size); +#endif + entry(0, 0, openfirmware, arg, len); +} +#endif + +void +ofbcopy(const void *src, void *dst, size_t len) +{ + const char *sp = src; + char *dp = dst; + + if (src == dst) + return; + + while (len-- > 0) + *dp++ = *sp++; +} Index: dev/ofw/openfirm.h =================================================================== RCS file: openfirm.h diff -N openfirm.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ openfirm.h Tue Jun 5 21:19:14 2001 @@ -0,0 +1,129 @@ +/* $NetBSD: openfirm.h,v 1.1 1998/05/15 10:16:00 tsubai Exp $ */ +/* $FreeBSD$ */ + +/* + * 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. + */ +/* + * Copyright (C) 2000 Benno Rice. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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. + * + * $FreeBSD: src/sys/boot/ofw/libofw/openfirm.h,v 1.2 2000/11/10 06:39:54 benno Exp $ + */ + +/* + * Prototypes for Openfirmware Interface Routines + */ + +#include +#include + +typedef int ihandle_t; +typedef int phandle_t; + +/* + * Stuff that is used by the OpenFirmware code. + */ +void set_openfirm_callback(int (*)(void *)); +int openfirmware(void *); + +/* + * This isn't actually an OpenFirmware function, but it seemed like the right + * place for it to go. + */ +void OF_init(int (*openfirm)(void *)); + +/* Generic functions */ +int OF_test(char *); +void OF_helloworld(void); +void OF_printf(const char *, ...); + +/* Device tree functions */ +phandle_t OF_peer(phandle_t); +phandle_t OF_child(phandle_t); +phandle_t OF_parent(phandle_t); +phandle_t OF_instance_to_package(ihandle_t); +int OF_getproplen(phandle_t, char *); +int OF_getprop(phandle_t, char *, void *, int); +int OF_nextprop(phandle_t, char *, char *); +int OF_setprop(phandle_t, char *, void *, int); +int OF_canon(char *, char *, int); +phandle_t OF_finddevice(char *); +int OF_instance_to_path(ihandle_t, char *, int); +int OF_package_to_path(phandle_t, char *, int); +int OF_call_method(char *, ihandle_t, int, int, ...); + +/* Device I/O functions */ +ihandle_t OF_open(char *); +void OF_close(ihandle_t); +int OF_read(ihandle_t, void *, int); +int OF_write(ihandle_t, void *, int); +int OF_seek(ihandle_t, u_quad_t); + +/* Memory functions */ +void *OF_claim(void *, u_int, u_int); +void OF_release(void *, u_int); + +/* Control transfer functions */ +void OF_boot(char *); +void OF_enter(void); +void OF_exit(void) __attribute__((noreturn)); +void OF_chain(void *, u_int, + void (*)(void *, u_int, void *, void *, u_int), void *, u_int); + +#if 0 +/* User interface functions */ +/* OF_interpret */ +void *OF_set_callback(void *); +void OF_set_symbol_lookup(void *, void *); +#endif + +/* Time function */ +int OF_milliseconds(void); Index: powerpc/conf/GENERIC =================================================================== RCS file: GENERIC diff -N GENERIC --- /dev/null Tue Jun 5 21:44:00 2001 +++ GENERIC Sat Jun 2 16:34:22 2001 @@ -0,0 +1,35 @@ +# +# GENERIC -- Generic kernel configuration file for FreeBSD/powerpc +# +# For more information on this file, please read the handbook section on +# Kernel Configuration Files: +# +# http://www.FreeBSD.org/handbook/kernelconfig-config.html +# +# The handbook is also available locally in /usr/share/doc/handbook +# if you've installed the doc distribution, otherwise always see the +# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# latest information. +# +# An exhaustive list of options and more detailed explanations of the +# device lines is also present in the ../../i386/conf/NOTES file. +# If you are in doubt as to the purpose or necessity of a line, check first +# in NOTES. Please note that this is the i386 NOTES, but it still contains +# valuable info for powerpc too. +# +# For hardware specific information check HARDWARE.TXT +# +# $FreeBSD: src/sys/powerpc/conf/GENERIC,v 1.102 2000/11/07 22:09:33 obrien Exp $ + +machine powerpc +cpu MPC750 +ident GENERIC +maxusers 32 + +#To statically compile in device wiring instead of /boot/device.hints +#hints "GENERIC.hints" + +#makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols + +options FFS +options COMPAT_43 Index: powerpc/include/atomic.h =================================================================== RCS file: /home/ncvs/src/sys/powerpc/include/atomic.h,v retrieving revision 1.2 diff -u -r1.2 atomic.h --- powerpc/include/atomic.h 2001/01/07 03:45:56 1.2 +++ powerpc/include/atomic.h 2001/06/04 12:57:09 @@ -217,7 +217,7 @@ #define atomic_set_long atomic_set_32 #define atomic_clear_long atomic_clear_32 -#define atomic_add_long atomic_add_32 +#define atomic_add_long(p, v) atomic_add_32((u_int32_t *)p, (u_int32_t)v) #define atomic_subtract_long atomic_subtract_32 #define atomic_readandclear_long atomic_readandclear_32 @@ -334,19 +334,21 @@ static __inline u_int32_t atomic_cmpset_32(volatile u_int32_t* p, u_int32_t cmpval, u_int32_t newval) { - u_int32_t ret; + u_int32_t ret; + ret = 0; + __asm __volatile ( - "1:\tlwarx %0, 0, %4\n\t" /* load old value */ - "cmplw 0, %2, %0\n\t" /* compare */ - "bne 2\n\t" /* exit if not equal */ - "mr %0, %3\n\t" /* value to store */ - "stwcx. %0, 0, %1\n\t" /* attempt to store */ - "bne- 1\n\t" /* spin if failed */ + "1:\tlwarx %0, 0, %3\n\t" /* load old value */ + "cmplw 0, %1, %0\n\t" /* compare */ + "bne 2f\n\t" /* exit if not equal */ + "mr %0, %2\n\t" /* value to store */ + "stwcx. %0, 0, %3\n\t" /* attempt to store */ + "bne- 1b\n\t" /* spin if failed */ "eieio\n" /* memory barrier */ "2:\t\n" - : "=&r" (ret), "=r" (*p) - : "r" (cmpval), "r" (newval), "r" (*p) + : "=r" (ret) + : "r" (cmpval), "r" (newval), "r" (p) : "memory"); return ret; @@ -416,7 +418,7 @@ atomic_cmpset_acq_ptr(volatile void *dst, void *exp, void *src) { - return (atomic_cmpset_acq_long((volatile u_int32_t *)dst, + return (atomic_cmpset_acq_32((volatile u_int32_t *)dst, (u_int32_t)exp, (u_int32_t)src)); } @@ -424,7 +426,7 @@ atomic_cmpset_rel_ptr(volatile void *dst, void *exp, void *src) { - return (atomic_cmpset_rel_long((volatile u_int32_t *)dst, + return (atomic_cmpset_rel_32((volatile u_int32_t *)dst, (u_int32_t)exp, (u_int32_t)src)); } @@ -432,33 +434,33 @@ atomic_load_acq_ptr(volatile void *p) { - return (void *)atomic_load_acq_long((volatile u_int32_t *)p); + return (void *)atomic_load_acq_32((volatile u_int32_t *)p); } static __inline void atomic_store_rel_ptr(volatile void *p, void *v) { - atomic_store_rel_long((volatile u_int32_t *)p, (u_int32_t)v); + atomic_store_rel_32((volatile u_int32_t *)p, (u_int32_t)v); } #define ATOMIC_PTR(NAME) \ static __inline void \ atomic_##NAME##_ptr(volatile void *p, uintptr_t v) \ { \ - atomic_##NAME##_long((volatile u_int32_t *)p, v); \ + atomic_##NAME##_32((volatile u_int32_t *)p, v); \ } \ \ static __inline void \ atomic_##NAME##_acq_ptr(volatile void *p, uintptr_t v) \ { \ - atomic_##NAME##_acq_long((volatile u_int32_t *)p, v); \ + atomic_##NAME##_acq_32((volatile u_int32_t *)p, v); \ } \ \ static __inline void \ atomic_##NAME##_rel_ptr(volatile void *p, uintptr_t v) \ { \ - atomic_##NAME##_rel_long((volatile u_int32_t *)p, v); \ + atomic_##NAME##_rel_32((volatile u_int32_t *)p, v); \ } ATOMIC_PTR(set) Index: powerpc/include/bat.h =================================================================== RCS file: bat.h diff -N bat.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ bat.h Tue Jun 5 19:39:54 2001 @@ -0,0 +1,172 @@ +/* $NetBSD: bat.h,v 1.2 1999/12/18 01:36:06 thorpej Exp $ */ +/* $FreeBSD$ */ + +/*- + * Copyright (c) 1999 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. + */ + +/* + * 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; +}; + +/* Lower BAT bits (all but PowerPC 601): */ +#define BAT_PBS 0xfffe0000 /* physical block start */ +#define BAT_W 0x00000040 /* 1 = write-through, 0 = write-back */ +#define BAT_I 0x00000020 /* cache inhibit */ +#define BAT_M 0x00000010 /* memory coherency enable */ +#define BAT_G 0x00000008 /* guarded region */ + +#define BAT_PP_NONE 0x00000000 /* no access permission */ +#define BAT_PP_RO_S 0x00000001 /* read-only (soft) */ +#define BAT_PP_RW 0x00000002 /* read/write */ +#define BAT_PP_RO 0x00000003 /* read-only */ + +/* Upper BAT bits (all but PowerPC 601): */ +#define BAT_EBS 0xfffe0000 /* effective block start */ +#define BAT_BL 0x00001ffc /* block length */ +#define BAT_Vs 0x00000002 /* valid in supervisor mode */ +#define BAT_Vu 0x00000001 /* valid in user mode */ + +#define BAT_V (BAT_Vs|BAT_Vu) + +/* Block Length encoding (all but PowerPC 601): */ +#define BAT_BL_128K 0x00000000 +#define BAT_BL_256K 0x00000004 +#define BAT_BL_512K 0x0000000c +#define BAT_BL_1M 0x0000001c +#define BAT_BL_2M 0x0000003c +#define BAT_BL_4M 0x0000007c +#define BAT_BL_8M 0x000000fc +#define BAT_BL_16M 0x000001fc +#define BAT_BL_32M 0x000003fc +#define BAT_BL_64M 0x000007fc +#define BAT_BL_128M 0x00000ffc +#define BAT_BL_256M 0x00001ffc + +#define BATU(va, len, v) \ + (((va) & BAT_EBS) | ((len) & BAT_BL) | ((v) & BAT_V)) + +#define BATL(pa, wimg, pp) \ + (((pa) & BAT_PBS) | (wimg) | (pp)) + + +/* Lower BAT bits (PowerPC 601): */ +#define BAT601_PBN 0xfffe0000 /* physical block number */ +#define BAT601_V 0x00000040 /* valid */ +#define BAT601_BSM 0x0000003f /* block size mask */ + +/* Upper BAT bits (PowerPC 601): */ +#define BAT601_BLPI 0xfffe0000 /* block logical page index */ +#define BAT601_W 0x00000040 /* 1 = write-through, 0 = write-back */ +#define BAT601_I 0x00000020 /* cache inhibit */ +#define BAT601_M 0x00000010 /* memory coherency enable */ +#define BAT601_Ks 0x00000008 /* key-supervisor */ +#define BAT601_Ku 0x00000004 /* key-user */ + +/* + * Permission bits on the PowerPC 601 are modified by the appropriate + * Key bit: + * + * Key PP Access + * 0 NONE read/write + * 0 RO_S read/write + * 0 RW read/write + * 0 RO read-only + * + * 1 NONE none + * 1 RO_S read-only + * 1 RW read/write + * 1 RO read-only + */ +#define BAT601_PP_NONE 0x00000000 /* no access permission */ +#define BAT601_PP_RO_S 0x00000001 /* read-only (soft) */ +#define BAT601_PP_RW 0x00000002 /* read/write */ +#define BAT601_PP_RO 0x00000003 /* read-only */ + +/* Block Size Mask encoding (PowerPC 601): */ +#define BAT601_BSM_128K 0x00000000 +#define BAT601_BSM_256K 0x00000001 +#define BAT601_BSM_512K 0x00000003 +#define BAT601_BSM_1M 0x00000007 +#define BAT601_BSM_2M 0x0000000f +#define BAT601_BSM_4M 0x0000001f +#define BAT601_BSM_8M 0x0000003f + +#define BATU601(va, wim, key, pp) \ + (((va) & BAT601_BLPI) | (wim) | (key) | (pp)) + +#define BATL601(pa, size, v) \ + (((pa) & BAT601_PBN) | (v) | (size)) + +#ifdef _KERNEL +extern struct bat battable[16]; +#endif + +#endif /* _MACHINE_BAT_H_ */ Index: powerpc/include/bootinfo.h =================================================================== RCS file: bootinfo.h diff -N bootinfo.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ bootinfo.h Thu Oct 19 23:14:01 2000 @@ -0,0 +1,86 @@ +/* $FreeBSD: src/sys/alpha/include/bootinfo.h,v 1.5 1999/08/28 00:38:40 peter Exp $ */ +/* + * Copyright (c) 1994, 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. + */ + +/* + * The boot program passes a pointer (in the boot environment virtual + * address address space; "BEVA") to a bootinfo to the kernel using + * the following convention: + * + * a0 contains first free page frame number + * a1 contains page number of current level 1 page table + * if a2 contains BOOTINFO_MAGIC and a4 is nonzero: + * a3 contains pointer (BEVA) to bootinfo + * a4 contains bootinfo version number + * if a2 contains BOOTINFO_MAGIC and a4 contains 0 (backward compat): + * a3 contains pointer (BEVA) to bootinfo version + * (u_long), then the bootinfo + */ + +#define BOOTINFO_MAGIC 0xdeadbeeffeedface + +struct bootinfo_v1 { + u_long ssym; /* 0: start of kernel sym table */ + u_long esym; /* 8: end of kernel sym table */ + char boot_flags[64]; /* 16: boot flags */ + char booted_kernel[64]; /* 80: name of booted kernel */ + void *hwrpb; /* 144: hwrpb pointer (BEVA) */ + u_long hwrpbsize; /* 152: size of hwrpb data */ + int (*cngetc) __P((void)); /* 160: console getc pointer */ + void (*cnputc) __P((int)); /* 168: console putc pointer */ + void (*cnpollc) __P((int)); /* 176: console pollc pointer */ + u_long pad[6]; /* 184: rsvd for future use */ + char *envp; /* 232: start of environment */ + u_long kernend; /* 240: end of kernel */ + u_long modptr; /* 248: FreeBSD module base */ + /* 256: total size */ +}; + +/* + * Kernel-internal structure used to hold important bits of boot + * information. NOT to be used by boot blocks. + * + * Note that not all of the fields from the bootinfo struct(s) + * passed by the boot blocks aren't here (because they're not currently + * used by the kernel!). Fields here which aren't supplied by the + * bootinfo structure passed by the boot blocks are supposed to be + * filled in at startup with sane contents. + */ +struct bootinfo_kernel { + u_long ssym; /* start of syms */ + u_long esym; /* end of syms */ + u_long modptr; /* FreeBSD module pointer */ + u_long kernend; /* "end of kernel" from boot code */ + char *envp; /* "end of kernel" from boot code */ + u_long hwrpb_phys; /* hwrpb physical address */ + u_long hwrpb_size; /* size of hwrpb data */ + char boot_flags[64]; /* boot flags */ + char booted_kernel[64]; /* name of booted kernel */ + char booted_dev[64]; /* name of booted device */ +}; + +extern struct bootinfo_kernel bootinfo; Index: powerpc/include/bus.h =================================================================== RCS file: bus.h diff -N bus.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ bus.h Tue Jun 5 19:34:52 2001 @@ -0,0 +1,800 @@ +/* $NetBSD: bus.h,v 1.9.4.1 2000/06/30 16:27:30 simonb Exp $ */ +/* $FreeBSD$ */ + +/*- + * 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 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. + */ + +#ifndef _MACPPC_BUS_H_ +#define _MACPPC_BUS_H_ + +#include + +/* + * Values for the macppc bus space tag, not to be used directly by MI code. + */ + +#define __BUS_SPACE_HAS_STREAM_METHODS + +#define MACPPC_BUS_ADDR_MASK 0xfffff000 +#define MACPPC_BUS_STRIDE_MASK 0x0000000f + +#define macppc_make_bus_space_tag(addr, stride) \ + (((addr) & MACPPC_BUS_ADDR_MASK) | (stride)) +#define __BA(t, h, o) ((void *)((h) + ((o) << ((t) & MACPPC_BUS_STRIDE_MASK)))) + +/* + * Bus address and size types + */ +typedef u_int32_t bus_addr_t; +typedef u_int32_t bus_size_t; + +/* + * Access methods for bus resources and address space. + */ +typedef u_int32_t bus_space_tag_t; +typedef u_int32_t bus_space_handle_t; + +/* + * 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_CACHEABLE 0x01 +#define BUS_SPACE_MAP_LINEAR 0x02 +#define BUS_SPACE_MAP_PREFETCHABLE 0x04 + +extern void *mapiodev(vm_offset_t, vm_size_t); + +static __inline int +bus_space_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size, int flags, + bus_space_handle_t *bshp) +{ + vm_offset_t base = t & MACPPC_BUS_ADDR_MASK; + int stride = t & MACPPC_BUS_STRIDE_MASK; + + *bshp = (bus_space_handle_t) + mapiodev(base + (addr << stride), size << stride); + return 0; +} + +/* + * 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, bsh, size) + +/* + * 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, bsh, offset, size, bshp) \ + ((*(bshp) = (bus_space_handle_t)__BA(t, bsh, offset)), 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 *addrp, + * bus_space_handle_t *bshp)); + * + * Allocate a region of bus space. + */ + +#if 0 +#define bus_space_alloc(t, rs, re, s, a, b, f, ap, hp) !!! unimplemented !!! +#endif + +/* + * 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. + */ +#if 0 +#define bus_space_free(t, h, s) !!! unimplemented !!! +#endif + +/* + * 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_1(t, h, o) (in8(__BA(t, h, o))) +#define bus_space_read_2(t, h, o) (in16rb(__BA(t, h, o))) +#define bus_space_read_4(t, h, o) (in32rb(__BA(t, h, o))) +#if 0 /* Cause a link error for bus_space_read_8 */ +#define bus_space_read_8(t, h, o) !!! unimplemented !!! +#endif + +#define bus_space_read_stream_1(t, h, o) (in8(__BA(t, h, o))) +#define bus_space_read_stream_2(t, h, o) (in16(__BA(t, h, o))) +#define bus_space_read_stream_4(t, h, o) (in32(__BA(t, h, o))) +#if 0 /* Cause a link error for bus_space_read_stream_8 */ +#define bus_space_read_8(t, h, o) !!! unimplemented !!! +#endif + +/* + * 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_1(t, h, o, a, c) do { \ + ins8(__BA(t, h, o), (a), (c)); \ + } while (0) + +#define bus_space_read_multi_2(t, h, o, a, c) do { \ + ins16rb(__BA(t, h, o), (a), (c)); \ + } while (0) + +#define bus_space_read_multi_4(t, h, o, a, c) do { \ + ins32rb(__BA(t, h, o), (a), (c)); \ + } while (0) + +#if 0 /* Cause a link error for bus_space_read_multi_8 */ +#define bus_space_read_multi_8 !!! unimplemented !!! +#endif + +#define bus_space_read_multi_stream_1(t, h, o, a, c) do { \ + ins8(__BA(t, h, o), (a), (c)); \ + } while (0) + +#define bus_space_read_multi_stream_2(t, h, o, a, c) do { \ + ins16(__BA(t, h, o), (a), (c)); \ + } while (0) + +#define bus_space_read_multi_stream_4(t, h, o, a, c) do { \ + ins32(__BA(t, h, o), (a), (c)); \ + } while (0) + +#if 0 /* Cause a link error for bus_space_read_multi_stream_8 */ +#define bus_space_read_multi_stream_8 !!! unimplemented !!! +#endif + +/* + * 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(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 = __BA(tag, bsh, offset); + + while (count--) + *addr++ = *s++; + __asm __volatile("eieio; sync"); +} + +static __inline void +bus_space_read_region_2(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 = __BA(tag, 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(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 = __BA(tag, bsh, offset); + + while (count--) + __asm __volatile("lwbrx %0, 0, %1" : + "=r"(*addr++) : "r"(s++)); + __asm __volatile("eieio; sync"); +} + +#if 0 /* Cause a link error for bus_space_read_region_8 */ +#define bus_space_read_region_8 !!! unimplemented !!! +#endif + +static __inline void +bus_space_read_region_stream_2(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 = __BA(tag, bsh, offset); + + while (count--) + *addr++ = *s++; + __asm __volatile("eieio; sync"); +} + +static __inline void +bus_space_read_region_stream_4(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 = __BA(tag, bsh, offset); + + while (count--) + *addr++ = *s++; + __asm __volatile("eieio; sync"); +} + +#if 0 /* Cause a link error */ +#define bus_space_read_region_stream_8 !!! unimplemented !!! +#endif + +/* + * 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_1(t, h, o, v) out8(__BA(t, h, o), (v)) +#define bus_space_write_2(t, h, o, v) out16rb(__BA(t, h, o), (v)) +#define bus_space_write_4(t, h, o, v) out32rb(__BA(t, h, o), (v)) + +#define bus_space_write_stream_1(t, h, o, v) out8(__BA(t, h, o), (v)) +#define bus_space_write_stream_2(t, h, o, v) out16(__BA(t, h, o), (v)) +#define bus_space_write_stream_4(t, h, o, v) out32(__BA(t, h, o), (v)) + +#if 0 /* Cause a link error for bus_space_write_8 */ +#define bus_space_write_8 !!! unimplemented !!! +#endif + +/* + * 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_1(t, h, o, a, c) do { \ + outsb(__BA(t, h, o), (a), (c)); \ + } while (0) + +#define bus_space_write_multi_2(t, h, o, a, c) do { \ + outsw(__BA(t, h, o), (a), (c)); \ + } while (0) + +#define bus_space_write_multi_4(t, h, o, a, c) do { \ + outsl(__BA(t, h, o), (a), (c)); \ + } while (0) + +#if 0 +#define bus_space_write_multi_8 !!! unimplemented !!! +#endif + +#define bus_space_write_multi_stream_2(t, h, o, a, c) do { \ + outsw(__BA(t, h, o), (a), (c)); \ + } while (0) + +#define bus_space_write_multi_stream_4(t, h, o, a, c) do { \ + outsl(__BA(t, h, o), (a), (c)); \ + } while (0) + +#if 0 +#define bus_space_write_multi_stream_8 !!! unimplemented !!! +#endif + +/* + * 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(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 = __BA(tag, bsh, offset); + + while (count--) + *d++ = *addr++; + __asm __volatile("eieio; sync"); +} + +static __inline void +bus_space_write_region_2(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 = __BA(tag, 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(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 = __BA(tag, bsh, offset); + + while (count--) + __asm __volatile("stwbrx %0, 0, %1" :: + "r"(*addr++), "r"(d++)); + __asm __volatile("eieio; sync"); +} + +#if 0 +#define bus_space_write_region_8 !!! bus_space_write_region_8 unimplemented !!! +#endif + +static __inline void +bus_space_write_region_stream_2(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 = __BA(tag, bsh, offset); + + while (count--) + *d++ = *addr++; + __asm __volatile("eieio; sync"); +} + +static __inline void +bus_space_write_region_stream_4(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 = __BA(tag, bsh, offset); + + while (count--) + *d++ = *addr++; + __asm __volatile("eieio; sync"); +} + +#if 0 +#define bus_space_write_region_stream_8 !!! unimplemented !!! +#endif + +/* + * 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(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 = __BA(tag, bsh, offset); + + while (count--) + *d = val; + __asm __volatile("eieio; sync"); +} + +static __inline void +bus_space_set_multi_2(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 = __BA(tag, 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(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 = __BA(tag, bsh, offset); + + while (count--) + __asm __volatile("stwbrx %0, 0, %1" :: + "r"(val), "r"(d)); + __asm __volatile("eieio; sync"); +} + +#if 0 +#define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!! +#endif + +static __inline void +bus_space_set_multi_stream_2(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 = __BA(tag, bsh, offset); + + while (count--) + *d = val; + __asm __volatile("eieio; sync"); +} + +static __inline void +bus_space_set_multi_stream_4(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 = __BA(tag, bsh, offset); + + while (count--) + *d = val; + __asm __volatile("eieio; sync"); +} + +#if 0 +#define bus_space_set_multi_stream_8 !!! unimplemented !!! +#endif + +/* + * 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(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 = __BA(tag, bsh, offset); + + while (count--) + *d++ = val; + __asm __volatile("eieio; sync"); +} + +static __inline void +bus_space_set_region_2(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 = __BA(tag, 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(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 = __BA(tag, bsh, offset); + + while (count--) + __asm __volatile("stwbrx %0, 0, %1" :: + "r"(val), "r"(d++)); + __asm __volatile("eieio; sync"); +} + +#if 0 +#define bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!! +#endif + +static __inline void +bus_space_set_region_stream_2(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 = __BA(tag, bsh, offset); + + while (count--) + *d++ = val; + __asm __volatile("eieio; sync"); +} + +static __inline void +bus_space_set_region_stream_4(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 = __BA(tag, bsh, offset); + + while (count--) + *d++ = val; + __asm __volatile("eieio; sync"); +} + +#if 0 +#define bus_space_set_region_stream_8 !!! unimplemented !!! +#endif + +/* + * 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. + */ + + /* XXX IMPLEMENT bus_space_copy_N() XXX */ + +/* + * 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)); + * + * Note: the macppc does not currently require barriers, but we must + * provide the flags to MI code. + */ + +#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_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 macppc_bus_dma_tag *bus_dma_tag_t; +typedef struct macppc_bus_dmamap *bus_dmamap_t; + +/* + * bus_dma_segment_t + * + * Describes a single contiguous DMA transaction. Values + * are suitable for programming into DMA registers. + */ +struct macppc_bus_dma_segment { + bus_addr_t ds_addr; /* DMA address */ + bus_size_t ds_len; /* length of transfer */ +}; +typedef struct macppc_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 macppc_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_addr_t, bus_size_t, int)); + + /* + * 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)); + vm_offset_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, l, ops) \ + (void)((t)->_dmamap_sync ? \ + (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (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 macppc_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 _MACPPC_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_addr_t, + bus_size_t, int)); + +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)); +vm_offset_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, + vm_offset_t low, vm_offset_t high)); +#endif /* _MACPPC_BUS_DMA_PRIVATE */ + +#endif /* _MACPPC_BUS_H_ */ Index: powerpc/include/clock.h =================================================================== RCS file: clock.h diff -N clock.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ clock.h Sun Jun 3 17:07:16 2001 @@ -0,0 +1,26 @@ +/* + * Kernel interface to machine-dependent clock driver. + * Garrett Wollman, September 1994. + * This file is in the public domain. + * + * $FreeBSD: src/sys/alpha/include/clock.h,v 1.6 2000/10/15 09:51:44 phk Exp $ + */ + +#ifndef _MACHINE_CLOCK_H_ +#define _MACHINE_CLOCK_H_ + +#ifdef _KERNEL + +extern int disable_rtc_set; +extern int wall_cmos_clock; +extern int adjkerntz; + +int sysbeep __P((int pitch, int period)); +int acquire_timer2 __P((int mode)); +int release_timer2 __P((void)); + +void decr_intr(struct clockframe *); + +#endif + +#endif /* !_MACHINE_CLOCK_H_ */ Index: powerpc/include/cpu.h =================================================================== RCS file: cpu.h diff -N cpu.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ cpu.h Tue Jun 5 19:32:58 2001 @@ -0,0 +1,97 @@ +/* $NetBSD: cpu.h,v 1.11 2000/05/26 21:19:53 thorpej Exp $ */ +/* $FreeBSD$ */ + +/* + * Copyright (C) 1995-1997 Wolfgang Solfrank. + * Copyright (C) 1995-1997 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 +#include +#include + +#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_number() 0 + +extern void delay __P((unsigned)); +#define DELAY(n) delay(n) + +extern int want_resched; +extern int astpending; + +#define need_proftick(p) ((p)->p_flag |= PS_OWEUPC, astpending = 1) + +extern char bootpath[]; + +#if defined(_KERNEL) || defined(_STANDALONE) +#define CACHELINESIZE 32 +#endif + +extern void __syncicache __P((void *, int)); + +/* + * CTL_MACHDEP definitions. + */ +#define CPU_CACHELINE 1 +#define CPU_MAXID 2 +#define CPU_CONSDEV 1 + +#define CTL_MACHDEP_NAMES { \ + { 0, 0 }, \ + { "cachelinesize", CTLTYPE_INT }, \ +} + +static __inline u_int64_t +get_cyclecount(void) +{ + u_int32_t upper, lower; + u_int64_t time; + + __asm __volatile( + "mftb %0\n" + "mftbu %1" + : "=r" (lower), "=r" (upper)); + + time = (u_int64_t)upper; + time = (time << 32) + lower; + return (time); +} + +#define cpu_getstack(p) ((p)->p_md.md_regs[1]) + +void savectx __P((struct pcb *)); + +#endif /* _MACHINE_CPU_H_ */ Index: powerpc/include/cpufunc.h =================================================================== RCS file: cpufunc.h diff -N cpufunc.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ cpufunc.h Wed May 30 20:26:38 2001 @@ -0,0 +1,127 @@ +/*- + * Copyright (c) 1998 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/alpha/include/cpufunc.h,v 1.9 2000/09/07 01:32:40 jasone Exp $ + */ + +#ifndef _MACHINE_CPUFUNC_H_ +#define _MACHINE_CPUFUNC_H_ + +#ifdef _KERNEL + +#include + +#ifdef __GNUC__ + +static __inline void +breakpoint(void) +{ + return; +} + +#endif + +/* + * Bogus interrupt manipulation + */ +static __inline void +disable_intr(void) +{ + u_int32_t msr; + + msr = 0; + __asm __volatile( + "mfmsr %0\n\t" + "rlwinm %0, %0, 0, 17, 15\n\t" + "mtmsr %0" + : "+r" (msr)); + + return; +} + +static __inline void +enable_intr(void) +{ + u_int32_t msr; + + msr = 0; + __asm __volatile( + "mfmsr %0\n\t" + "ori %0, %0, 0x8000\n\t" + "mtmsr %0" + : "+r" (msr)); + + return; +} + +static __inline u_int +save_intr(void) +{ + u_int msr; + + __asm __volatile("mfmsr %0" : "=r" (msr)); + + return msr; +} + +static __inline critical_t +critical_enter(void) +{ + return ((critical_t)save_intr()); +} + +static __inline void +restore_intr(u_int msr) +{ + __asm __volatile("mtmsr %0" : : "r" (msr)); + + return; +} + +static __inline void +critical_exit(critical_t msr) +{ + return (restore_intr((u_int)msr)); +} + +static __inline void +powerpc_mb(void) +{ + __asm __volatile("eieio;" : : : "memory"); +} + +static __inline void +*powerpc_get_globalp(void) +{ + void *ret; + + __asm __volatile("mfsprg %0, 0" : "=r" (ret)); + + return(ret); +} + +#endif /* _KERNEL */ + +#endif /* !_MACHINE_CPUFUNC_H_ */ Index: powerpc/include/db_machdep.h =================================================================== RCS file: db_machdep.h diff -N db_machdep.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ db_machdep.h Tue Jun 5 19:38:15 2001 @@ -0,0 +1,99 @@ +/* $OpenBSD: db_machdep.h,v 1.2 1997/03/21 00:48:48 niklas Exp $ */ +/* $NetBSD: db_machdep.h,v 1.4.22.1 2000/08/05 11:10:43 wiz Exp $ */ +/* $FreeBSD$ */ + +/* + * 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 + +#define DB_ELF_SYMBOLS +#define DB_ELFSIZE 32 + +typedef vm_offset_t db_addr_t; /* address - unsigned */ +typedef long 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) ((db_addr_t)(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 0x400 +#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) + +#define T_WATCHPOINT 0xeeee +#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_ */ Index: powerpc/include/elf.h =================================================================== RCS file: /home/ncvs/src/sys/powerpc/include/elf.h,v retrieving revision 1.1 diff -u -r1.1 elf.h --- powerpc/include/elf.h 2001/01/01 21:54:48 1.1 +++ powerpc/include/elf.h 2001/01/05 13:06:24 @@ -80,6 +80,9 @@ #define AT_COUNT 13 /* Count of defined aux entry types. */ +/* Used in John Polstra's testbed stuff. */ +#define AT_DEBUG 14 /* Debugging level. */ + /* * Relocation types. */ Index: powerpc/include/fpu.h =================================================================== RCS file: fpu.h diff -N fpu.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ fpu.h Tue Jun 5 19:40:06 2001 @@ -0,0 +1,70 @@ +/* $NetBSD: fpu.h,v 1.2 1999/12/07 15:14:56 danw Exp $ */ +/* $FreeBSD$ */ + +/*- + * 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 FPSCR_FX 0x80000000 +#define FPSCR_FEX 0x40000000 +#define FPSCR_VX 0x20000000 +#define FPSCR_OX 0x10000000 +#define FPSCR_UX 0x08000000 +#define FPSCR_ZX 0x04000000 +#define FPSCR_XX 0x02000000 +#define FPSCR_VXSNAN 0x01000000 +#define FPSCR_VXISI 0x00800000 +#define FPSCR_VXIDI 0x00400000 +#define FPSCR_VXZDZ 0x00200000 +#define FPSCR_VXIMZ 0x00100000 +#define FPSCR_VXVC 0x00080000 +#define FPSCR_FR 0x00040000 +#define FPSCR_FI 0x00020000 +#define FPSCR_FPRF 0x0001f000 +#define FPSCR_C 0x00010000 +#define FPSCR_FPCC 0x0000f000 +#define FPSCR_FL 0x00008000 +#define FPSCR_FG 0x00004000 +#define FPSCR_FE 0x00002000 +#define FPSCR_FU 0x00001000 +#define FPSCR_VXSOFT 0x00000400 +#define FPSCR_VXSQRT 0x00000200 +#define FPSCR_VXCVI 0x00000100 +#define FPSCR_VE 0x00000080 +#define FPSCR_OE 0x00000040 +#define FPSCR_UE 0x00000020 +#define FPSCR_ZE 0x00000010 +#define FPSCR_XE 0x00000008 +#define FPSCR_NI 0x00000004 +#define FPSCR_RN 0x00000003 + +#endif /* _MACHINE_FPU_H_ */ Index: powerpc/include/globaldata.h =================================================================== RCS file: globaldata.h diff -N globaldata.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ globaldata.h Sun Jun 3 18:57:53 2001 @@ -0,0 +1,75 @@ +/*- + * Copyright (c) 1999 Luoqi Chen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/alpha/include/globaldata.h,v 1.2 2000/11/15 21:58:01 jhb Exp $ + */ + +#ifndef _MACHINE_GLOBALDATA_H_ +#define _MACHINE_GLOBALDATA_H_ + +#ifdef _KERNEL + +#include + +/* + * This structure maps out the global data that needs to be kept on a + * per-cpu basis. genassym uses this to generate offsets for the assembler + * code, which also provides external symbols so that C can get at them as + * though they were really globals. This structure is pointed to by + * the per-cpu system value (see alpha_pal_rdval() and alpha_pal_wrval()). + * Inside the kernel, the globally reserved register t7 is used to + * point at the globaldata structure. + */ +struct globaldata { + struct proc *gd_curproc; /* current process */ + struct proc *gd_idleproc; /* idle process */ + struct proc *gd_fpcurproc; /* fp state owner */ + struct pcb *gd_curpcb; /* current pcb */ + struct timeval gd_switchtime; + int gd_switchticks; + u_int gd_cpuid; /* this cpu number */ + u_int gd_other_cpus; /* all other cpus */ + int gd_inside_intr; + u_int32_t gd_next_asn; /* next ASN to allocate */ + u_int32_t gd_current_asngen; /* ASN rollover check */ + u_int32_t gd_intr_nesting_level; /* interrupt recursion */ + + u_int gd_astpending; + SLIST_ENTRY(globaldata) gd_allcpu; + struct lock_list_entry *gd_spinlocks; +#ifdef KTR_PERCPU +#ifdef KTR + volatile int gd_ktr_idx; /* Index into trace table */ + char *gd_ktr_buf; + char gd_ktr_buf_data[KTR_SIZE]; +#endif +#endif +}; + +void globaldata_init(struct globaldata *pcpu, int cpuno, size_t sz); + +#endif /* _KERNEL */ + +#endif /* !_MACHINE_GLOBALDATA_H_ */ Index: powerpc/include/globals.h =================================================================== RCS file: globals.h diff -N globals.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ globals.h Wed May 30 20:26:54 2001 @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 1999 Luoqi Chen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/alpha/include/globals.h,v 1.4 2000/11/15 21:58:02 jhb Exp $ + */ + +#ifndef _MACHINE_GLOBALS_H_ +#define _MACHINE_GLOBALS_H_ + +#ifdef _KERNEL +#include +#include + +#define GLOBALP ((struct globaldata *) powerpc_get_globalp()) + +#define PCPU_GET(name) (GLOBALP->gd_##name) +#define PCPU_PTR(name) (&GLOBALP->gd_##name) +#define PCPU_SET(name,value) (GLOBALP->gd_##name = (value)) + +/* + * The following set of macros works for UP kernel as well, but for maximum + * performance we allow the global variables to be accessed directly. On the + * other hand, kernel modules should always use these macros to maintain + * portability between UP and SMP kernels. + */ +#define CURPROC PCPU_GET(curproc) +#define CURTHD PCPU_GET(curproc) /* temporary */ +#define curproc PCPU_GET(curproc) +#define idleproc PCPU_GET(idleproc) +#define curpcb PCPU_GET(curpcb) +#define fpcurproc PCPU_GET(fpcurproc) +#define switchtime PCPU_GET(switchtime) +#define switchticks PCPU_GET(switchticks) +#define witness_spin_check PCPU_GET(witness_spin_check) + +#endif /* _KERNEL */ + +#endif /* !_MACHINE_GLOBALS_H_ */ Index: powerpc/include/intr.h =================================================================== RCS file: intr.h diff -N intr.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ intr.h Tue Jun 5 19:33:16 2001 @@ -0,0 +1,163 @@ +/* $NetBSD: intr.h,v 1.6 2000/02/11 13:15:44 tsubai Exp $ */ +/* $FreeBSD$ */ + +/*- + * Copyright (c) 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles M. Hannum. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _MACPPC_INTR_H_ +#define _MACPPC_INTR_H_ + +/* Interrupt priority `levels'. */ +#define IPL_NONE 9 /* nothing */ +#define IPL_SOFTCLOCK 8 /* timeouts */ +#define IPL_SOFTNET 7 /* protocol stacks */ +#define IPL_BIO 6 /* block I/O */ +#define IPL_NET 5 /* network */ +#define IPL_SOFTSERIAL 4 /* serial */ +#define IPL_TTY 3 /* terminal */ +#define IPL_IMP 3 /* memory allocation */ +#define IPL_AUDIO 2 /* audio */ +#define IPL_CLOCK 1 /* clock */ +#define IPL_HIGH 1 /* everything */ +#define IPL_SERIAL 0 /* serial */ +#define NIPL 10 + +/* Interrupt sharing types. */ +#define IST_NONE 0 /* none */ +#define IST_PULSE 1 /* pulsed */ +#define IST_EDGE 2 /* edge-triggered */ +#define IST_LEVEL 3 /* level-triggered */ + +#ifndef LOCORE + +#if 0 +/* + * Interrupt handler chains. intr_establish() inserts a handler into + * the list. The handler is called with its (single) argument. + */ +struct intrhand { + int (*ih_fun) __P((void *)); + void *ih_arg; + u_long ih_count; + struct intrhand *ih_next; + int ih_level; + int ih_irq; +}; +#endif + +void setsoftclock __P((void)); +void clearsoftclock __P((void)); +void setsoftnet __P((void)); +void clearsoftnet __P((void)); + +void do_pending_int __P((void)); + +static __inline void softintr __P((int)); + +extern u_int cpl, ipending, tickspending; +extern int imask[]; + +/* Following code should be implemented with lwarx/stwcx to avoid + * the disable/enable. i need to read the manual once more.... */ +static __inline void +softintr(ipl) + int ipl; +{ + int msrsave; + + __asm__ volatile("mfmsr %0" : "=r"(msrsave)); + __asm__ volatile("mtmsr %0" :: "r"(msrsave & ~PSL_EE)); + ipending |= 1 << ipl; + __asm__ volatile("mtmsr %0" :: "r"(msrsave)); +} + +#define ICU_LEN 64 + +/* Soft interrupt masks. */ +#define SIR_CLOCK 28 +#define SIR_NET 29 +#define SIR_SERIAL 30 +#define SPL_CLOCK 31 + +#if 0 + +/* + * Hardware interrupt masks + */ + +#define splbio() splraise(imask[IPL_BIO]) +#define splnet() splraise(imask[IPL_NET]) +#define spltty() splraise(imask[IPL_TTY]) +#define splaudio() splraise(imask[IPL_AUDIO]) +#define splclock() splraise(imask[IPL_CLOCK]) +#define splstatclock() splclock() +#define splserial() splraise(imask[IPL_SERIAL]) + +#define spllpt() spltty() + +/* + * Software interrupt masks + * + * NOTE: splsoftclock() is used by hardclock() to lower the priority from + * clock to softclock before it calls softclock(). + */ +#define spllowersoftclock() spllower(imask[IPL_SOFTCLOCK]) +#define splsoftclock() splraise(imask[IPL_SOFTCLOCK]) +#define splsoftnet() splraise(imask[IPL_SOFTNET]) +#define splsoftserial() splraise(imask[IPL_SOFTSERIAL]) + +/* + * Miscellaneous + */ +#define splimp() splraise(imask[IPL_IMP]) +#define splhigh() splraise(imask[IPL_HIGH]) +#define spl0() spllower(0) + +#endif /* 0 */ + +#define setsoftclock() softintr(SIR_CLOCK) +#define setsoftnet() softintr(SIR_NET) +#define setsoftserial() softintr(SIR_SERIAL) + +#define CNT_IRQ0 0 +#define CNT_CLOCK 64 +#define CNT_SOFTCLOCK 65 +#define CNT_SOFTNET 66 +#define CNT_SOFTSERIAL 67 + +#endif /* !LOCORE */ + +#endif /* !_MACPPC_INTR_H_ */ Index: powerpc/include/ipl.h =================================================================== RCS file: ipl.h diff -N ipl.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ ipl.h Tue Jun 5 19:37:45 2001 @@ -0,0 +1,7 @@ +/* $FreeBSD$ */ + +/* + * An empty file now, + * Although in the times to come, + * More may be found here. + */ Index: powerpc/include/md_var.h =================================================================== RCS file: md_var.h diff -N md_var.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ md_var.h Fri Dec 15 17:21:31 2000 @@ -0,0 +1,80 @@ +/*- + * Copyright (c) 1998 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/alpha/include/md_var.h,v 1.15 2000/12/08 22:11:18 msmith Exp $ + */ + +#ifndef _MACHINE_MD_VAR_H_ +#define _MACHINE_MD_VAR_H_ + +/* + * Miscellaneous machine-dependent declarations. + */ + +extern char sigcode[]; +extern char esigcode[]; +extern int szsigcode; + +extern int Maxmem; +extern int busdma_swi_pending; + +struct fpreg; +struct proc; +struct reg; +struct cam_sim; +struct pcicfg; + +void busdma_swi __P((void)); +void cpu_halt __P((void)); +void cpu_reset __P((void)); +int is_physical_memory __P((vm_offset_t addr)); +void swi_vm __P((void *)); +int vm_page_zero_idle __P((void)); +int fill_regs __P((struct proc *, struct reg *)); +int set_regs __P((struct proc *, struct reg *)); +int fill_fpregs __P((struct proc *, struct fpreg *)); +int set_fpregs __P((struct proc *, struct fpreg *)); +#if 0 +void alpha_register_pci_scsi __P((int bus, int slot, struct cam_sim *sim)); +#ifdef _SYS_BUS_H_ +struct resource *alpha_platform_alloc_ide_intr(int chan); +int alpha_platform_release_ide_intr(int chan, struct resource *res); +int alpha_platform_setup_ide_intr(struct device *dev, + struct resource *res, + driver_intr_t *fn, void *arg, + void **cookiep); +int alpha_platform_teardown_ide_intr(struct device *dev, + struct resource *res, void *cookie); +int alpha_platform_pci_setup_intr(device_t dev, device_t child, + struct resource *irq, int flags, + driver_intr_t *intr, void *arg, + void **cookiep); +int alpha_platform_pci_teardown_intr(device_t dev, device_t child, + struct resource *irq, void *cookie); +int alpha_pci_route_interrupt(device_t bus, device_t dev, int pin); +#endif +#endif + +#endif /* !_MACHINE_MD_VAR_H_ */ Index: powerpc/include/mutex.h =================================================================== RCS file: mutex.h diff -N mutex.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ mutex.h Mon Jun 4 22:12:30 2001 @@ -0,0 +1,80 @@ +/*- + * Copyright (c) 1997 Berkeley Software Design, Inc. 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. Berkeley Software Design Inc's name may not be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN INC BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from BSDI $Id: mutex.h,v 2.7.2.35 2000/04/27 03:10:26 cp Exp $ + * $FreeBSD: src/sys/alpha/include/mutex.h,v 1.16 2000/11/15 19:45:10 jhb Exp $ + */ + +#ifndef _MACHINE_MUTEX_H_ +#define _MACHINE_MUTEX_H_ + +#ifndef LOCORE + +#ifdef _KERNEL + +#define mtx_intr_enable(mutex) do (mutex)->mtx_savecrit |= PSL_EE; while (0) + +/* + * Assembly macros (for internal use only) + *-------------------------------------------------------------------------- + */ + +#define _V(x) __STRING(x) + +#endif /* _KERNEL */ + +#else /* !LOCORE */ + +/* + * Simple assembly macros to get and release non-recursive spin locks + */ +#define MTX_ENTER(lck) \ + mfmsr r10; \ /* disable interrupts */ + rlwinm r0, r10, 0, 17, 15; \ + mtmsr r0; \ +1: li r11, MTX_LOCK; \ /* MTX_LOCK offset */ + lwarx r0, r11, lck; \ /* load current lock value */ + cmplwi r0, r1, MTX_UNOWNED; \ /* compare with unowned */ + beq 1; \ /* if owned, loop */ + lwz r0, PC_CURPROC(globalp); \ /* load curproc */ + stwcx. r0, r11, lck; \ /* attempt to store */ + beq 1; \ /* loop if failed */ + sync; \ /* sync */ + eieio; \ /* sync */ + stw r10, MTX_SAVEINTR(lck) /* save flags */ + +#define MTX_EXIT(lck) \ + sync; \ /* sync */ + eieio; \ /* sync */ + li r0, MTX_UNOWNED; \ /* load in unowned */ + stw r0, MTX_LOCK(lck); \ /* store to lock */ + lwz r0, MTX_SAVEINTR(lck); \ /* load saved flags */ + mtmsr r0 /* enable interrupts */ + +#endif /* !LOCORE */ + +#endif /* __MACHINE_MUTEX_H */ Index: powerpc/include/param.h =================================================================== RCS file: /home/ncvs/src/sys/powerpc/include/param.h,v retrieving revision 1.1 diff -u -r1.1 param.h --- powerpc/include/param.h 2001/01/02 00:06:45 1.1 +++ powerpc/include/param.h 2001/05/29 12:09:06 @@ -74,7 +74,9 @@ #endif #define MID_MACHINE MID_POWERPC +#if !defined(LOCORE) #include +#endif /* * OBJFORMAT_NAMES is a comma-separated list of the object formats @@ -158,18 +160,40 @@ /* * Mach derived conversion macros */ -#define trunc_page(x) ((x) & ~PAGE_MASK) +#define trunc_page(x) ((unsigned long)(x) & ~(PAGE_MASK)) #define round_page(x) (((x) + PAGE_MASK) & ~PAGE_MASK) #define trunc_4mpage(x) ((unsigned)(x) & ~PDRMASK) #define round_4mpage(x) ((((unsigned)(x)) + PDRMASK) & ~PDRMASK) -#define atop(x) ((unsigned)(x) >> PAGE_SHIFT) -#define ptoa(x) ((unsigned)(x) << PAGE_SHIFT) +#define atop(x) ((unsigned long)(x) >> PAGE_SHIFT) +#define ptoa(x) ((unsigned long)(x) << PAGE_SHIFT) #define powerpc_btop(x) ((unsigned)(x) >> PAGE_SHIFT) #define powerpc_ptob(x) ((unsigned)(x) << PAGE_SHIFT) #define pgtok(x) ((x) * (PAGE_SIZE / 1024)) + +/* XXX: NetBSD defines that we're using for the moment */ +#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)) +#define SEGMENT_LENGTH 0x10000000 +#define SEGMENT_MASK 0xf0000000 + +#if !defined(NPMAPS) +#define NPMAPS 32768 +#endif /* !defined(NPMAPS) */ + +#if !defined(MSGBUFSIZE) +#define MSGBUFSIZE PAGE_SIZE +#endif /* !defined(MSGBUFSIZE) */ + +/* + * XXX: Stop NetBSD msgbuf_paddr code from happening. + */ +#define MSGBUFADDR #endif /* !_MACHINE_PARAM_H_ */ #endif /* !_NO_NAMESPACE_POLLUTION */ Index: powerpc/include/pcb.h =================================================================== RCS file: pcb.h diff -N pcb.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ pcb.h Tue Jun 5 19:34:11 2001 @@ -0,0 +1,68 @@ +/* $NetBSD: pcb.h,v 1.4 2000/06/04 11:57:17 tsubai Exp $ */ +/* $FreeBSD$ */ + +/*- + * 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_ + +typedef int faultbuf[23]; + +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 fpscr; /* FPSCR stored as double for easier access */ + } pcb_fpu; /* Floating point processor */ +}; + +struct md_coredump { + struct trapframe frame; + struct fpu fpstate; +}; + +#ifdef _KERNEL + +#ifndef curpcb +extern struct pcb *curpcb; +#endif + +extern struct pmap *curpm; +extern struct proc *fpuproc; + +#endif +#endif /* _MACHINE_PCB_H_ */ Index: powerpc/include/pio.h =================================================================== RCS file: pio.h diff -N pio.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ pio.h Tue Jun 5 19:35:08 2001 @@ -0,0 +1,257 @@ +/* $NetBSD: pio.h,v 1.1 1998/05/15 10:15:54 tsubai Exp $ */ +/* $OpenBSD: pio.h,v 1.1 1997/10/13 10:53:47 pefo Exp $ */ +/* $FreeBSD$ */ + +/* + * 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. + */ + +static __inline void +__outb(volatile u_int8_t *a, u_int8_t v) +{ + *a = v; + __asm__ volatile("eieio; sync"); +} + +static __inline void +__outw(volatile u_int16_t *a, u_int16_t v) +{ + *a = v; + __asm__ volatile("eieio; sync"); +} + +static __inline void +__outl(volatile u_int32_t *a, u_int32_t v) +{ + *a = v; + __asm__ volatile("eieio; sync"); +} + +static __inline void +__outwrb(volatile u_int16_t *a, u_int16_t v) +{ + __asm__ volatile("sthbrx %0, 0, %1" :: "r"(v), "r"(a)); + __asm__ volatile("eieio; sync"); +} + +static __inline void +__outlrb(volatile u_int32_t *a, u_int32_t v) +{ + __asm__ volatile("stwbrx %0, 0, %1" :: "r"(v), "r"(a)); + __asm__ volatile("eieio; sync"); +} + +static __inline u_int8_t +__inb(volatile u_int8_t *a) +{ + u_int8_t _v_; + + _v_ = *a; + __asm__ volatile("eieio; sync"); + return _v_; +} + +static __inline u_int16_t +__inw(volatile u_int16_t *a) +{ + u_int16_t _v_; + + _v_ = *a; + __asm__ volatile("eieio; sync"); + return _v_; +} + +static __inline u_int32_t +__inl(volatile u_int32_t *a) +{ + u_int32_t _v_; + + _v_ = *a; + __asm__ volatile("eieio; sync"); + return _v_; +} + +static __inline u_int16_t +__inwrb(volatile u_int16_t *a) +{ + u_int16_t _v_; + + __asm__ volatile("lhbrx %0, 0, %1" : "=r"(_v_) : "r"(a)); + __asm__ volatile("eieio; sync"); + return _v_; +} + +static __inline u_int32_t +__inlrb(volatile u_int32_t *a) +{ + u_int32_t _v_; + + __asm__ volatile("lwbrx %0, 0, %1" : "=r"(_v_) : "r"(a)); + __asm__ volatile("eieio; sync"); + 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) + + +static __inline void +__outsb(volatile u_int8_t *a, const u_int8_t *s, size_t c) +{ + while (c--) + *a = *s++; + __asm__ volatile("eieio; sync"); +} + +static __inline void +__outsw(volatile u_int16_t *a, const u_int16_t *s, size_t c) +{ + while (c--) + *a = *s++; + __asm__ volatile("eieio; sync"); +} + +static __inline void +__outsl(volatile u_int32_t *a, const u_int32_t *s, size_t c) +{ + while (c--) + *a = *s++; + __asm__ volatile("eieio; sync"); +} + +static __inline void +__outswrb(volatile u_int16_t *a, const u_int16_t *s, size_t c) +{ + while (c--) + __asm__ volatile("sthbrx %0, 0, %1" :: "r"(*s++), "r"(a)); + __asm__ volatile("eieio; sync"); +} + +static __inline void +__outslrb(volatile u_int32_t *a, const u_int32_t *s, size_t c) +{ + while (c--) + __asm__ volatile("stwbrx %0, 0, %1" :: "r"(*s++), "r"(a)); + __asm__ volatile("eieio; sync"); +} + +static __inline void +__insb(volatile u_int8_t *a, u_int8_t *d, size_t c) +{ + while (c--) + *d++ = *a; + __asm__ volatile("eieio; sync"); +} + +static __inline void +__insw(volatile u_int16_t *a, u_int16_t *d, size_t c) +{ + while (c--) + *d++ = *a; + __asm__ volatile("eieio; sync"); +} + +static __inline void +__insl(volatile u_int32_t *a, u_int32_t *d, size_t c) +{ + while (c--) + *d++ = *a; + __asm__ volatile("eieio; sync"); +} + +static __inline void +__inswrb(volatile u_int16_t *a, u_int16_t *d, size_t c) +{ + while (c--) + __asm__ volatile("lhbrx %0, 0, %1" : "=r"(*d++) : "r"(a)); + __asm__ volatile("eieio; sync"); +} + +static __inline void +__inslrb(volatile u_int32_t *a, u_int32_t *d, size_t c) +{ + while (c--) + __asm__ volatile("lwbrx %0, 0, %1" : "=r"(*d++) : "r"(a)); + __asm__ volatile("eieio; sync"); +} + +#define outsb(a,s,c) (__outsb((volatile u_int8_t *)(a), s, c)) +#define outs8(a,s,c) outsb(a,s,c) +#define outsw(a,s,c) (__outsw((volatile u_int16_t *)(a), s, c)) +#define outs16(a,s,c) outsw(a,s,c) +#define outsl(a,s,c) (__outsl((volatile u_int32_t *)(a), s, c)) +#define outs32(a,s,c) outsl(a,s,c) +#define insb(a,d,c) (__insb((volatile u_int8_t *)(a), d, c)) +#define ins8(a,d,c) insb(a,d,c) +#define insw(a,d,c) (__insw((volatile u_int16_t *)(a), d, c)) +#define ins16(a,d,c) insw(a,d,c) +#define insl(a,d,c) (__insl((volatile u_int32_t *)(a), d, c)) +#define ins32(a,d,c) insl(a,d,c) + +#define outs8rb(a,s,c) outsb(a,s,c) +#define outswrb(a,s,c) (__outswrb((volatile u_int16_t *)(a), s, c)) +#define outs16rb(a,s,c) outswrb(a,s,c) +#define outslrb(a,s,c) (__outslrb((volatile u_int32_t *)(a), s, c)) +#define outs32rb(a,s,c) outslrb(a,s,c) +#define ins8rb(a,d,c) insb(a,d,c) +#define inswrb(a,d,c) (__inswrb((volatile u_int16_t *)(a), d, c)) +#define ins16rb(a,d,c) inswrb(a,d,c) +#define inslrb(a,d,c) (__inslrb((volatile u_int32_t *)(a), d, c)) +#define ins32rb(a,d,c) inslrb(a,d,c) + +#endif /*_MACHINE_PIO_H_*/ Index: powerpc/include/pmap.h =================================================================== RCS file: pmap.h diff -N pmap.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ pmap.h Tue Jun 5 19:34:26 2001 @@ -0,0 +1,134 @@ +/* $NetBSD: pmap.h,v 1.17 2000/03/30 16:18:24 jdolecek Exp $ */ +/* $FreeBSD$ */ + +/*- + * 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 + +/* + * 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 + +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 md_page { + int pv_list_count; + int pv_flags; + TAILQ_HEAD(,pv_entry) pv_list; +}; + +/* + * Pmap stuff + */ +struct pmap { + sr_t pm_sr[16]; /* segments used in this pmap */ + int pm_refs; /* ref count */ + struct pmap_statistics pm_stats; /* pmap statistics */ +}; + +typedef struct pmap *pmap_t; + +typedef struct pv_entry *pv_entry_t; + +#ifdef _KERNEL + +#define pmap_clear_modify(pg) (ptemodify((pg), PTE_CHG, 0)) +#define pmap_clear_reference(pg) (ptemodify((pg), PTE_REF, 0)) +#define pmap_is_modified(pg) (ptebits((pg), PTE_CHG)) +#define pmap_is_referenced(pg) (ptebits((pg), PTE_REF)) +#define pmap_unwire(pm, va) + +#define pmap_phys_address(x) (x) + +#define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count) + +extern pmap_t kernel_pmap; + +extern vm_offset_t avail_end; +extern vm_offset_t avail_start; +extern vm_offset_t phys_avail[]; +extern vm_offset_t virtual_avail; +extern vm_offset_t virtual_end; + +void pmap_bootstrap __P((u_int kernelstart, u_int kernelend)); +vm_offset_t pmap_steal_memory __P((vm_size_t)); +boolean_t ptemodify __P((struct vm_page *, u_int, u_int)); +int ptebits __P((struct vm_page *, int)); + +#if 0 +#define PMAP_NEED_PROCWR +void pmap_procwr __P((struct proc *, vaddr_t, size_t)); +#endif + +/* + * Alternate mapping hooks for pool pages. Avoids thrashing the TLB. + * + * Note: This won't work if we have more memory than can be direct-mapped + * VA==PA all at once. But pmap_copy_page() and pmap_zero_page() will have + * this problem, too. + */ +#define PMAP_MAP_POOLPAGE(pa) (pa) +#define PMAP_UNMAP_POOLPAGE(pa) (pa) + +#define vtophys(va) pmap_kextract(((vm_offset_t) (va))) + +extern pte_t PTmap[]; + +#define vtopte(x) (PTmap + powerpc_btop(x)) + +static __inline vm_offset_t +pmap_kextract(vm_offset_t va) +{ + /* XXX: coming soon... */ + return (0); +} + +#endif /* _KERNEL */ +#endif /* LOCORE */ + +#endif /* _MACHINE_PMAP_H_ */ Index: powerpc/include/powerpc.h =================================================================== RCS file: powerpc.h diff -N powerpc.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ powerpc.h Tue Jun 5 19:38:33 2001 @@ -0,0 +1,58 @@ +/* $NetBSD: powerpc.h,v 1.3 2000/06/01 00:49:59 matt Exp $ */ +/* $FreeBSD$ */ + +/* + * 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 + */ +void ppc_exit __P((void)); +void ppc_boot __P((char *bootspec)); + +int dk_match __P((char *name)); + +void ofrootfound __P((void)); + +extern int booted_partition; + +#endif /* _MACHINE_POWERPC_H_ */ Index: powerpc/include/proc.h =================================================================== RCS file: proc.h diff -N proc.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ proc.h Tue Jun 5 19:33:29 2001 @@ -0,0 +1,42 @@ +/* $NetBSD: proc.h,v 1.2 1997/04/16 22:57:48 thorpej Exp $ */ +/* $FreeBSD$ */ + +/*- + * 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-dependent part of the proc structure + */ +struct mdproc { + int md_regs[32]; +}; Index: powerpc/include/psl.h =================================================================== RCS file: psl.h diff -N psl.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ psl.h Tue Jun 5 19:33:07 2001 @@ -0,0 +1,83 @@ +/* $NetBSD: psl.h,v 1.4 2000/02/13 10:25:07 tsubai Exp $ */ +/* $FreeBSD$ */ + +/* + * 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_ + +/* + * Machine State Register (MSR) + * + * The PowerPC 601 does not implement the following bits: + * + * POW, ILE, BE, RI, LE[*] + * + * [*] Little-endian mode on the 601 is implemented in the HID0 register. + */ +#define PSL_POW 0x00040000 /* power management */ +#define PSL_ILE 0x00010000 /* interrupt endian mode (1 == le) */ +#define PSL_EE 0x00008000 /* external interrupt enable */ +#define PSL_PR 0x00004000 /* privilege mode (1 == user) */ +#define PSL_FP 0x00002000 /* floating point enable */ +#define PSL_ME 0x00001000 /* machine check enable */ +#define PSL_FE0 0x00000800 /* floating point interrupt mode 0 */ +#define PSL_SE 0x00000400 /* single-step trace enable */ +#define PSL_BE 0x00000200 /* branch trace enable */ +#define PSL_FE1 0x00000100 /* floating point interrupt mode 1 */ +#define PSL_IP 0x00000040 /* interrupt prefix */ +#define PSL_IR 0x00000020 /* instruction address relocation */ +#define PSL_DR 0x00000010 /* data address relocation */ +#define PSL_RI 0x00000002 /* recoverable interrupt */ +#define PSL_LE 0x00000001 /* endian mode (1 == le) */ + +#define PSL_601_MASK ~(PSL_POW|PSL_ILE|PSL_BE|PSL_RI|PSL_LE) + +/* + * Floating-point exception modes: + */ +#define PSL_FE_DIS 0 /* none */ +#define PSL_FE_NONREC PSL_FE1 /* imprecise non-recoverable */ +#define PSL_FE_REC PSL_FE0 /* imprecise recoverable */ +#define PSL_FE_PREC (PSL_FE0 | PSL_FE1) /* precise */ +#define PSL_FE_DFLT PSL_FE_DIS /* default == none */ + +/* + * 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) + +#endif /* _MACHINE_PSL_H_ */ Index: powerpc/include/pte.h =================================================================== RCS file: pte.h diff -N pte.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ pte.h Tue Jun 5 19:34:38 2001 @@ -0,0 +1,112 @@ +/* $NetBSD: pte.h,v 1.2 1998/08/31 14:43:40 tsubai Exp $ */ +/* $FreeBSD$ */ + +/*- + * 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_ + +/* + * Page Table Entries + */ +#ifndef LOCORE +#include + +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)); +#endif /* _KERNEL */ +#endif /* LOCORE */ +#endif /* _MACHINE_PTE_H_ */ Index: powerpc/include/ptrace.h =================================================================== RCS file: ptrace.h diff -N ptrace.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ ptrace.h Sat Jun 2 16:41:03 2001 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. 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. + * + * @(#)ptrace.h 8.1 (Berkeley) 6/11/93 + * $FreeBSD: src/sys/alpha/include/ptrace.h,v 1.4 1999/12/29 04:27:59 peter Exp $ + */ + +#ifndef _MACHINE_PTRACE_H_ +#define _MACHINE_PTRACE_H_ + +/* + * Machine dependent trace commands. + */ +#define PT_GETREGS (PT_FIRSTMACH + 1) +#define PT_SETREGS (PT_FIRSTMACH + 2) +#define PT_GETFPREGS (PT_FIRSTMACH + 3) +#define PT_SETFPREGS (PT_FIRSTMACH + 4) + +#define FIX_SSTEP(p) ptrace_clear_single_step(p) + +#ifdef _KERNEL +int ptrace_clear_single_step __P((struct proc *p)); +int ptrace_read_u_check __P((struct proc *p, vm_offset_t off, size_t len)); +#endif + +#endif + Index: powerpc/include/reg.h =================================================================== RCS file: reg.h diff -N reg.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ reg.h Tue Jun 5 19:35:46 2001 @@ -0,0 +1,27 @@ +/* $NetBSD: reg.h,v 1.4 2000/06/04 09:30:44 tsubai Exp $ */ +/* $FreeBSD$ */ + +#ifndef _POWERPC_REG_H_ +#define _POWERPC_REG_H_ + +struct reg { + register_t fixreg[32]; + register_t lr; + int cr; + int xer; + register_t ctr; + register_t pc; +}; + +struct fpreg { + double fpreg[32]; + double fpscr; +}; + +struct dbreg { + unsigned long junk; +}; + +void setregs(struct proc *, u_long, u_long, u_long); + +#endif /* _POWERPC_REG_H_ */ Index: powerpc/include/reloc.h =================================================================== RCS file: reloc.h diff -N reloc.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ reloc.h Thu Oct 19 23:14:12 2000 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 1998 John Birrell . + * 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 John Birrell. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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. + * + * $FreeBSD: src/sys/alpha/include/reloc.h,v 1.2 2000/05/01 20:17:49 peter Exp $ + */ Index: powerpc/include/resource.h =================================================================== RCS file: resource.h diff -N resource.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ resource.h Fri Dec 15 15:13:49 2000 @@ -0,0 +1,44 @@ +/* $FreeBSD: src/sys/alpha/include/resource.h,v 1.4 1999/10/14 21:38:28 dfr Exp $ */ +/* + * Copyright 1998 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that both the above copyright notice and this + * permission notice appear in all copies, that both the above + * copyright notice and this permission notice appear in all + * supporting documentation, and that the name of M.I.T. not be used + * in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. M.I.T. makes + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS + * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT + * SHALL M.I.T. 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_RESOURCE_H_ +#define _MACHINE_RESOURCE_H_ 1 + +/* + * Definitions of resource types for Intel Architecture machines + * with support for legacy ISA devices and drivers. + */ + +#define SYS_RES_IRQ 1 /* interrupt lines */ +#define SYS_RES_DRQ 2 /* isa dma lines */ +#define SYS_RES_MEMORY 3 /* i/o memory */ +#define SYS_RES_IOPORT 4 /* i/o ports */ + +#endif /* !_MACHINE_RESOURCE_H_ */ Index: powerpc/include/sigframe.h =================================================================== RCS file: sigframe.h diff -N sigframe.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ sigframe.h Sun Dec 17 22:12:13 2000 @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 1999 Marcel Moolenaar + * 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 + * in this position and unchanged. + * 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. + * + * $FreeBSD: src/sys/alpha/include/sigframe.h,v 1.1 1999/09/29 15:06:26 marcel Exp $ + */ + +#ifndef _MACHINE_SIGFRAME_H_ +#define _MACHINE_SIGFRAME_H_ 1 + +struct osigframe { + struct osigcontext sf_sc; + osiginfo_t sf_si; +}; + +struct sigframe { + unsigned long __spare__; + ucontext_t sf_uc; + siginfo_t sf_si; +}; + +#endif /* _MACHINE_SIGFRAME_H_ */ Index: powerpc/include/signal.h =================================================================== RCS file: signal.h diff -N signal.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ signal.h Tue Jun 5 19:32:20 2001 @@ -0,0 +1,70 @@ +/* $NetBSD: signal.h,v 1.4 1998/09/14 02:48:34 thorpej Exp $ */ +/* $FreeBSD$ */ + +/* + * 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_ + +#define MINSIGSTKSZ (512 * 4) + +typedef int sig_atomic_t; + +typedef unsigned int osigset_t; + +#if !defined(_ANSI_SOURCE) && !defined(_POSIX_C_SOURCE) && \ + !defined(_XOPEN_SOURCE) +#include + +#if defined(__LIBC12_SOURCE__) || defined(_KERNEL) +struct sigcontext13 { + int sc_onstack; /* saved onstack flag */ + int sc_mask; /* saved signal mask (old style) */ + struct trapframe sc_frame; /* saved registers */ +}; +#endif /* __LIBC12_SOURCE__ || _KERNEL */ + +struct osigcontext { + int sc_onstack; /* saved onstack flag */ + int __sc_mask13; /* saved signal mask (old style) */ + struct trapframe sc_frame; /* saved registers */ + sigset_t sc_mask; /* saved signal mask (new style) */ +}; + +struct sigcontext { + int sc_onstack; /* saved onstack flag */ + int __sc_mask13; /* saved signal mask (old style) */ + struct trapframe sc_frame; /* saved registers */ + sigset_t sc_mask; /* saved signal mask (new style) */ +}; + +#endif /* !_ANSI_SOURCE && !_POSIX_C_SOURCE && !_XOPEN_SOURCE */ +#endif /* !_MACHINE_SIGNAL_H_ */ Index: powerpc/include/smp.h =================================================================== RCS file: smp.h diff -N smp.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ smp.h Tue Jun 5 19:37:53 2001 @@ -0,0 +1,7 @@ +/* $FreeBSD$ */ + +/* + * An empty file now, + * Although in the times to come, + * More may be found here. + */ Index: powerpc/include/stdarg.h =================================================================== RCS file: stdarg.h diff -N stdarg.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ stdarg.h Tue Jun 5 19:32:38 2001 @@ -0,0 +1,123 @@ +/* $NetBSD: stdarg.h,v 1.5 2000/02/27 17:50:21 tsubai Exp $ */ +/* $FreeBSD$ */ + +/*- + * 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. + */ + +#ifndef _POWERPC_STDARG_H_ +#define _POWERPC_STDARG_H_ + +#include + +#if 0 +typedef struct { + char __gpr; /* GPR offset */ + char __fpr; /* FPR offset */ +/* char __pad[2]; */ + char *__stack; /* args passed on stack */ + char *__base; /* args passed by registers (r3-r10, f1-f8) */ +} va_list; +#endif + +typedef _BSD_VA_LIST_ va_list; + +#ifdef __lint__ + +#define va_start(ap, last) ((ap) = *(va_list *)0) +#define va_arg(ap, type) (*(type *)(void *)&(ap)) + +#else + +#define va_start(ap, last) \ + (__builtin_next_arg(last), \ + (ap).__stack = __va_stack_args, \ + (ap).__base = __va_reg_args, \ + (ap).__gpr = __va_first_gpr, \ + (ap).__fpr = __va_first_fpr) + +#define __va_first_gpr (__builtin_args_info(0)) +#define __va_first_fpr (__builtin_args_info(1) - 32 - 1) +#define __va_stack_args \ + ((char *)__builtin_saveregs() + \ + (__va_first_gpr >= 8 ? __va_first_gpr - 8 : 0) * sizeof(int)) +#define __va_reg_args \ + ((char *)__builtin_frame_address(0) + __builtin_args_info(4)) + +#define __INTEGER_TYPE_CLASS 1 +#define __REAL_TYPE_CLASS 8 +#define __RECORD_TYPE_CLASS 12 + +#define __va_longlong(type) \ + (__builtin_classify_type(*(type *)0) == __INTEGER_TYPE_CLASS && \ + sizeof(type) == 8) + +#define __va_double(type) \ + (__builtin_classify_type(*(type *)0) == __REAL_TYPE_CLASS) + +#define __va_struct(type) \ + (__builtin_classify_type(*(type *)0) >= __RECORD_TYPE_CLASS) + +#define __va_size(type) \ + ((sizeof(type) + sizeof(int) - 1) / sizeof(int) * sizeof(int)) + +#define __va_savedgpr(ap, type) \ + ((ap).__base + (ap).__gpr * sizeof(int) - sizeof(type)) + +#define __va_savedfpr(ap, type) \ + ((ap).__base + 8 * sizeof(int) + (ap).__fpr * sizeof(double) - \ + sizeof(type)) + +#define __va_stack(ap, type) \ + ((ap).__stack += __va_size(type) + \ + (__va_longlong(type) ? (int)(ap).__stack & 4 : 0), \ + (ap).__stack - sizeof(type)) + +#define __va_gpr(ap, type) \ + ((ap).__gpr += __va_size(type) / sizeof(int) + \ + (__va_longlong(type) ? (ap).__gpr & 1 : 0), \ + (ap).__gpr <= 8 ? __va_savedgpr(ap, type) : __va_stack(ap, type)) + +#define __va_fpr(ap, type) \ + ((ap).__fpr++, \ + (ap).__fpr <= 8 ? __va_savedfpr(ap, type) : __va_stack(ap, type)) + +#define va_arg(ap, type) \ + (*(type *)(__va_struct(type) ? (*(void **)__va_gpr(ap, void *)) : \ + __va_double(type) ? __va_fpr(ap, type) : \ + __va_gpr(ap, type))) + +#endif /* __lint__ */ + +#define va_end(ap) + +#if !defined(_ANSI_SOURCE) && \ + (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE) || \ + defined(_ISOC99_SOURCE) || (__STDC_VERSION__ - 0) >= 199901L) +#define va_copy(dest, src) \ + ((dest) = (src)) +#endif + +#endif /* _POWERPC_STDARG_H_ */ Index: powerpc/include/trap.h =================================================================== RCS file: trap.h diff -N trap.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ trap.h Tue Jun 5 19:40:22 2001 @@ -0,0 +1,92 @@ +/* $NetBSD: trap.h,v 1.3 2000/05/25 21:10:14 is Exp $ */ +/* $FreeBSD$ */ + +/* + * 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 _POWERPC_TRAP_H_ +#define _POWERPC_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) + +#ifndef LOCORE + +void trap(struct trapframe *); + +#endif /* !LOCORE */ + +#endif /* _POWERPC_TRAP_H_ */ Index: powerpc/include/types.h =================================================================== RCS file: /home/ncvs/src/sys/powerpc/include/types.h,v retrieving revision 1.2 diff -u -r1.2 types.h --- powerpc/include/types.h 2001/03/17 09:31:05 1.2 +++ powerpc/include/types.h 2001/04/24 10:05:25 @@ -65,4 +65,6 @@ /* Interrupt mask (spl, xxx_imask, etc) */ typedef __uint32_t intrmask_t; +typedef register_t critical_t; + #endif /* _MACHTYPES_H_ */ Index: powerpc/include/varargs.h =================================================================== RCS file: varargs.h diff -N varargs.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ varargs.h Tue Jun 5 19:32:47 2001 @@ -0,0 +1,50 @@ +/* $NetBSD: varargs.h,v 1.5 2000/02/27 17:50:22 tsubai Exp $ */ +/* $FreeBSD$ */ + +/*- + * 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. + */ + +#ifndef _POWERPC_VARARGS_H_ +#define _POWERPC_VARARGS_H_ + +#include + +#define va_alist __builtin_va_alist +#define va_dcl int __builtin_va_alist; ... + +#undef va_start + +#ifdef __lint__ +#define va_start(ap) ((ap) = *(va_list *)0) +#else +#define va_start(ap) \ + ((ap).__stack = __va_stack_args, \ + (ap).__base = __va_reg_args, \ + (ap).__gpr = __va_first_gpr, \ + (ap).__fpr = __va_first_fpr) +#endif + +#endif /* _POWERPC_VARARGS_H_ */ Index: powerpc/include/vmparam.h =================================================================== RCS file: vmparam.h diff -N vmparam.h --- /dev/null Tue Jun 5 21:44:00 2001 +++ vmparam.h Tue Jun 5 19:34:00 2001 @@ -0,0 +1,124 @@ +/* $NetBSD: vmparam.h,v 1.11 2000/02/11 19:25:16 thorpej Exp $ */ +/* $FreeBSD$ */ + +/*- + * 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 NBPG +#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 + +/* + * 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)0x7ffff000) +#define VM_MAX_ADDRESS VM_MAXUSER_ADDRESS +#define VM_MIN_KERNEL_ADDRESS ((vm_offset_t)(KERNEL_SR << ADDR_SR_SHFT)) +#define VM_MAX_KERNEL_ADDRESS (VM_MIN_KERNEL_ADDRESS + SEGMENT_LENGTH - 1) + +/* XXX max. amount of KVM to be used by buffers. */ +#ifndef VM_MAX_KERNEL_BUF +#define VM_MAX_KERNEL_BUF (SEGMENT_LENGTH * 7 / 10) +#endif + +#define VM_PHYS_SIZE (USRIOSIZE * NBPG) + +struct pmap_physseg { + struct pv_entry *pvent; + char *attrs; +}; + +#define VM_PHYSSEG_MAX 16 /* 1? */ +#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 + +#ifndef VM_INITIAL_PAGEIN +#define VM_INITIAL_PAGEIN 16 +#endif + +#ifndef SGROWSIZ +#define SGROWSIZ (128UL*1024) /* amount to grow stack */ +#endif + +#ifndef VM_KMEM_SIZE +#define VM_KMEM_SIZE (12 * 1024 * 1024) +#endif + +#endif /* _MACHINE_VMPARAM_H_ */ Index: powerpc/powerpc/atomic.s =================================================================== RCS file: /home/ncvs/src/sys/powerpc/powerpc/atomic.s,v retrieving revision 1.1 diff -u -r1.1 atomic.s --- powerpc/powerpc/atomic.s 2001/01/07 03:46:01 1.1 +++ powerpc/powerpc/atomic.s 2001/05/30 10:00:48 @@ -77,46 +77,60 @@ blr /* return */ ASENTRY(atomic_set_16) -0: lwarx 0, 0, 3 /* load old value */ + li 11, 3 /* mask to test for alignment */ + andc. 11, 3, 11 /* force address to be word-aligned */ +0: lwarx 12, 0, 11 /* load old value */ + bne 1f /* no realignment needed if it's aligned */ slwi 4, 4, 16 /* realign operand */ - or 0, 0, 4 /* calculate new value */ - stwcx. 0, 0, 3 /* attempt to store */ - bne- 0 /* loop if failed */ +1: or 12, 12, 4 /* calculate new value */ + stwcx. 12, 0, 11 /* attempt to store */ + bne- 0b /* loop if failed */ eieio /* synchronise */ sync blr /* return */ ASENTRY(atomic_clear_16) -0: lwarx 0, 0, 3 /* load old value */ + li 11, 3 /* mask to test for alignment */ + andc. 11, 3, 11 /* force address to be word-aligned */ +0: lwarx 12, 0, 11 /* load old value */ + bne 1f /* no realignment needed if it's aligned */ slwi 4, 4, 16 /* realign operand */ - andc 0, 0, 4 /* calculate new value */ - stwcx. 0, 0, 3 /* attempt to store */ - bne- 0 /* loop if failed */ +1: andc 12, 12, 4 /* calculate new value */ + stwcx. 12, 0, 11 /* attempt to store */ + bne- 0b /* loop if failed */ eieio /* synchronise */ sync blr /* return */ ASENTRY(atomic_add_16) -0: lwarx 0, 0, 3 /* load old value */ - srwi 0, 9, 16 /* realign */ - add 0, 4, 0 /* calculate new value */ - slwi 0, 0, 16 /* realign */ - clrlwi 9, 9, 16 /* clear old value */ - or 9, 9, 0 /* copy in new value */ - stwcx. 0, 0, 3 /* attempt to store */ - bne- 0 /* loop if failed */ + li 11, 3 /* mask to test for alignment */ + andc. 11, 3, 11 /* force address to be word-aligned */ +0: lwarx 12, 0, 11 /* load old value */ + bne 1f /* no realignment needed if it's aligned */ + srwi 12, 9, 16 /* realign */ +1: add 12, 4, 12 /* calculate new value */ + bne 2f /* no realignment needed if it's aligned */ + slwi 12, 12, 16 /* realign */ +2: clrlwi 9, 9, 16 /* clear old value */ + or 9, 9, 12 /* copy in new value */ + stwcx. 12, 0, 11 /* attempt to store */ + bne- 0b /* loop if failed */ eieio /* synchronise */ sync blr /* return */ ASENTRY(atomic_subtract_16) -0: lwarx 0, 0, 3 /* load old value */ - srwi 0, 9, 16 /* realign */ - subf 0, 4, 0 /* calculate new value */ - slwi 0, 0, 16 /* realign */ - clrlwi 9, 9, 16 /* clear old value */ - or 9, 9, 0 /* copy in new value */ - stwcx. 0, 0, 3 /* attempt to store */ + li 11, 3 /* mask to test for alignment */ + andc. 11, 3, 11 /* force address to be word-aligned */ +0: lwarx 12, 0, 11 /* load old value */ + bne 1f /* no realignment needed if it's aligned */ + srwi 12, 9, 16 /* realign */ +1: subf 12, 4, 12 /* calculate new value */ + bne 2f /* no realignment needed if it's aligned */ + slwi 12, 12, 16 /* realign */ +2: clrlwi 9, 9, 16 /* clear old value */ + or 9, 9, 12 /* copy in new value */ + stwcx. 12, 0, 11 /* attempt to store */ bne- 0 /* loop if failed */ eieio /* synchronise */ sync Index: powerpc/powerpc/autoconf.c =================================================================== RCS file: autoconf.c diff -N autoconf.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ autoconf.c Sun Jun 3 16:25:50 2001 @@ -0,0 +1,74 @@ +/*- + * Copyright (c) 1998 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/sys/alpha/alpha/autoconf.c,v 1.39 2000/10/20 07:57:54 jhb Exp $ + */ + +#include "opt_bootp.h" +#include "opt_nfs.h" +#include "opt_nfsroot.h" + +#include +#include +#include +#include +#include /* for BASE_SLICE, MAX_SLICES */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +static void configure __P((void *)); +SYSINIT(configure, SI_SUB_CONFIGURE, SI_ORDER_THIRD, configure, NULL) + +extern int nfs_diskless_valid; + +dev_t rootdev = NODEV; +dev_t dumpdev = NODEV; + +/* + * Determine i/o configuration for a machine. + */ +static void +configure(void *dummy) +{ +#if 0 /* XXX */ + cold = 0; +#endif +} Index: powerpc/powerpc/bcopy.c =================================================================== RCS file: bcopy.c diff -N bcopy.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ bcopy.c Sun Jun 3 16:35:16 2001 @@ -0,0 +1,151 @@ +/* $NetBSD: bcopy.c,v 1.2 1997/04/16 22:09:41 thorpej Exp $ */ +/* $FreeBSD$ */ + +/*- + * 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) +#if 0 +static char *sccsid = "from: @(#)bcopy.c 5.11 (Berkeley) 6/21/91"; +#else +static char *rcsid = "$NetBSD: bcopy.c,v 1.2 1997/04/16 22:09:41 thorpej Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +#include +#ifdef _KERNEL +#include +#else +#include +#endif + +/* + * 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. + */ +void * +memcpy(void *dst0, const void *src0, size_t length) +{ + char *dst; + const char *src; + size_t t; + + dst = dst0; + src = src0; + + 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 = *(const 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 = *(const word *)src); + t = length & wmask; + TLOOP(*--dst = *--src); + } +done: + return (dst0); +} + +void +bcopy(const void *src0, void *dst0, size_t length) +{ + memcpy(dst0, src0, length); +} Index: powerpc/powerpc/busdma_machdep.c =================================================================== RCS file: busdma_machdep.c diff -N busdma_machdep.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ busdma_machdep.c Tue Jun 5 19:31:24 2001 @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2001 Benno Rice. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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 busdma_swi_pending; + +void +busdma_swi(void) +{ + /* XXX: coming soon */ + return; +} Index: powerpc/powerpc/clock.c =================================================================== RCS file: clock.c diff -N clock.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ clock.c Tue Jun 5 21:02:49 2001 @@ -0,0 +1,228 @@ +/* $NetBSD: clock.c,v 1.9 2000/01/19 02:52:19 msaitoh Exp $ */ +/* $FreeBSD$ */ + +/* + * 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 +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#if 0 /* XXX */ +#include "adb.h" +#else +#define NADB 0 +#endif + +/* + * Initially we assume a processor with a bus frequency of 12.5 MHz. + */ +static u_long ns_per_tick = 80; +static long ticks_per_intr; +static volatile u_long lasttb; + +#define SECDAY 86400 +#define DIFF19041970 2082844800 + +#if NADB > 0 +extern int adb_read_date_time __P((int *)); +extern int adb_set_date_time __P((int)); +#endif + +static int clockinitted = 0; + +void +inittodr(time_t base) +{ + time_t deltat; + u_int rtc_time; + struct timespec ts; + + /* + * If we can't read from RTC, use the fs time. + */ +#if NADB > 0 + if (adb_read_date_time(&rtc_time) < 0) +#endif + { + ts.tv_sec = base; + ts.tv_nsec = 0; + tc_setclock(&ts); + return; + } + clockinitted = 1; + ts.tv_sec = rtc_time - DIFF19041970; + + deltat = ts.tv_sec - base; + if (deltat < 0) { + deltat = -deltat; + } + if (deltat < 2 * SECDAY) { + tc_setclock(&ts); + return; + } + + printf("WARNING: clock %s %d days", + ts.tv_sec < base ? "lost" : "gained", (int)(deltat / SECDAY)); + + printf(" -- CHECK AND RESET THE DATE!\n"); +} + +/* + * Similar to the above + */ +void +resettodr() +{ +#if NADB > 0 + u_int rtc_time; + + if (clockinitted) { + rtc_time = time.tv_sec + DIFF19041970; + adb_set_date_time(rtc_time); + } +#endif +} + +void +decr_intr(struct clockframe *frame) +{ + u_long tb; + long tick; + int nticks; + + /* + * Check whether we are initialized. + */ + if (!ticks_per_intr) + return; + + /* + * 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; + +#if 0 /* XXX */ + intrcnt[CNT_CLOCK]++; + { + int pri; + int msr; + + pri = splclock(); + if (pri & (1 << 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 | (1 << SIR_CLOCK); + while (--nticks > 0) + hardclock(frame); + frame->pri = pri; + hardclock(frame); + } + splx(pri); + } +#endif +} + +void +cpu_initclocks(void) +{ +} + +static __inline u_quad_t +mftb(void) +{ + 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; +} + +/* + * Wait for about n microseconds (at least!). + */ +void +delay(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)); +} + +/* + * Nothing to do. + */ +void +setstatclockrate(int arg) +{ + /* Do nothing */ +} Index: powerpc/powerpc/copyinstr.c =================================================================== RCS file: copyinstr.c diff -N copyinstr.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ copyinstr.c Tue Jun 5 19:15:01 2001 @@ -0,0 +1,68 @@ +/* $NetBSD: copyinstr.c,v 1.3 2000/02/19 23:29:16 chs Exp $ */ +/* $FreeBSD$ */ + +/*- + * 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. + */ +#include +#include +#include + +/* + * Emulate copyinstr. + */ +int +copyinstr(const void *udaddr, void *kaddr, size_t len, size_t *done) +{ + const u_char *up; + u_char *kp; + size_t l; + int c, rv; + + up = udaddr; + kp = kaddr; + + rv = ENAMETOOLONG; + for (l = 0; len-- > 0; l++) { + if ((c = fubyte(up++)) < 0) { + rv = EFAULT; + break; + } + if (!(*kp++ = c)) { + l++; + rv = 0; + break; + } + } + if (done != NULL) { + *done = l; + } + return rv; +} Index: powerpc/powerpc/copystr.c =================================================================== RCS file: copystr.c diff -N copystr.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ copystr.c Sun Jan 7 17:39:16 2001 @@ -0,0 +1,64 @@ +/* $NetBSD: copystr.c,v 1.3 2000/06/08 06:47:17 kleink 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. + */ +#include +#include +#include + +/* + * Emulate copyinstr. + */ +int +copystr(kfaddr, kdaddr, len, done) + const void *kfaddr; + void *kdaddr; + size_t len; + size_t *done; +{ + const u_char *kfp = kfaddr; + u_char *kdp = kdaddr; + size_t l; + int rv; + + rv = ENAMETOOLONG; + for (l = 0; len-- > 0; l++) { + if (!(*kdp++ = *kfp++)) { + l++; + rv = 0; + break; + } + } + if (done != NULL) { + *done = l; + } + return rv; +} Index: powerpc/powerpc/elf_machdep.c =================================================================== RCS file: elf_machdep.c diff -N elf_machdep.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ elf_machdep.c Tue Jun 5 19:15:14 2001 @@ -0,0 +1,113 @@ +/*- + * Copyright 1996-1998 John D. Polstra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR 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. + * + * $FreeBSD: src/sys/alpha/alpha/elf_machdep.c,v 1.7 1999/08/28 00:38:25 peter Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Process one elf relocation with addend. */ +int +elf_reloc(linker_file_t lf, const void *data, int type, const char *sym) +{ + Elf_Addr relocbase = (Elf_Addr) lf->address; + Elf_Addr *where; + Elf_Addr addr; + Elf_Addr addend; + Elf_Word rtype; + const Elf_Rel *rel; + const Elf_Rela *rela; + + switch (type) { + case ELF_RELOC_REL: + rel = (const Elf_Rel *)data; + where = (Elf_Addr *) (relocbase + rel->r_offset); + addend = *where; + rtype = ELF_R_TYPE(rel->r_info); + break; + case ELF_RELOC_RELA: + rela = (const Elf_Rela *)data; + where = (Elf_Addr *) (relocbase + rela->r_offset); + addend = rela->r_addend; + rtype = ELF_R_TYPE(rela->r_info); + break; + default: + panic("elf_reloc: unknown relocation mode %d\n", type); + } + + switch (rtype) { + + case R_PPC_NONE: + break; + + case R_PPC_GLOB_DAT: + addr = (Elf_Addr) + linker_file_lookup_symbol(lf, sym, 1); + if (addr == NULL) + return -1; + addr += addend; + if (*where != addr) + *where = addr; + break; + + case R_PPC_JMP_SLOT: + /* No point in lazy binding for kernel modules. */ + addr = (Elf_Addr) + linker_file_lookup_symbol(lf, sym, 1); + if (addr == NULL) + return -1; + if (*where != addr) + *where = addr; + break; + + case R_PPC_RELATIVE: + addr = relocbase + addend + *where; + if (*where != addr) + *where = addr; + break; + + case R_PPC_COPY: + /* + * There shouldn't be copy relocations in kernel + * objects. + */ + printf("kldload: unexpected R_COPY relocation\n"); + return -1; + + default: + printf("kldload: unexpected relocation type %d\n", + (int) rtype); + return -1; + } + return(0); +} Index: powerpc/powerpc/fubyte.c =================================================================== RCS file: fubyte.c diff -N fubyte.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ fubyte.c Tue Jun 5 19:18:29 2001 @@ -0,0 +1,50 @@ +/* $NetBSD: fubyte.c,v 1.2 2000/06/08 07:29:22 kleink Exp $ */ +/* $FreeBSD$ */ + +/*- + * Copyright (C) 1993 Wolfgang Solfrank. + * Copyright (C) 1993 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 + +/* + * Emulate fubyte. + */ +int +fubyte(const void *addr) +{ + unsigned char c; + + if (copyin(addr,&c,sizeof(c))) { + return -1; + } + + return c; +} Index: powerpc/powerpc/fuswintr.c =================================================================== RCS file: fuswintr.c diff -N fuswintr.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ fuswintr.c Tue Jun 5 19:23:50 2001 @@ -0,0 +1,47 @@ +/* $NetBSD: fuswintr.c,v 1.2 2000/06/08 07:29:54 kleink Exp $ */ +/* $FreeBSD$ */ + +/*- + * Copyright (C) 1994 Wolfgang Solfrank. + * Copyright (C) 1994 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 +#include + +/* + * Emulate fuswintr + * + * Simply return fault for all cases + */ +int +fuswintr(void *addr) +{ + return -1; +} Index: powerpc/powerpc/fuword.c =================================================================== RCS file: fuword.c diff -N fuword.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ fuword.c Tue Jun 5 19:18:54 2001 @@ -0,0 +1,50 @@ +/* $NetBSD: fubyte.c,v 1.2 2000/06/08 07:29:22 kleink Exp $ */ +/* $FreeBSD$ */ + +/*- + * Copyright (C) 1993 Wolfgang Solfrank. + * Copyright (C) 1993 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 + +/* + * Emulate fuword. + */ +long +fuword(const void *addr) +{ + long l; + + if (copyin(addr,&l,sizeof(l))) { + return -1; + } + + return l; +} Index: powerpc/powerpc/genassym.c =================================================================== RCS file: genassym.c diff -N genassym.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ genassym.c Fri May 4 19:33:42 2001 @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +ASSYM(GD_CURPROC, offsetof(struct globaldata, gd_curproc)); +ASSYM(GD_CURPCB, offsetof(struct globaldata, gd_curpcb)); +ASSYM(GD_SWITCHTIME, offsetof(struct globaldata, gd_switchtime)); +ASSYM(GD_ASTPENDING, offsetof(struct globaldata, gd_astpending)); + +ASSYM(MTX_LOCK, offsetof(struct mtx, mtx_lock)); +ASSYM(MTX_RECURSECNT, offsetof(struct mtx, mtx_recurse)); +ASSYM(MTX_SAVECRIT, offsetof(struct mtx, mtx_savecrit)); + +ASSYM(PM_KERNELSR, offsetof(struct pmap, pm_sr[KERNEL_SR])); +ASSYM(PM_USERSR, offsetof(struct pmap, pm_sr[USER_SR])); + +ASSYM(FRAMELEN, FRAMELEN); +ASSYM(FRAME_0, offsetof(struct trapframe, fixreg[0])); +ASSYM(FRAME_1, offsetof(struct trapframe, fixreg[1])); +ASSYM(FRAME_2, offsetof(struct trapframe, fixreg[2])); +ASSYM(FRAME_3, offsetof(struct trapframe, fixreg[3])); +ASSYM(FRAME_LR, offsetof(struct trapframe, lr)); +ASSYM(FRAME_CR, offsetof(struct trapframe, cr)); +ASSYM(FRAME_CTR, offsetof(struct trapframe, ctr)); +ASSYM(FRAME_XER, offsetof(struct trapframe, xer)); +ASSYM(FRAME_SRR0, offsetof(struct trapframe, srr0)); +ASSYM(FRAME_SRR1, offsetof(struct trapframe, srr1)); +ASSYM(FRAME_DAR, offsetof(struct trapframe, dar)); +ASSYM(FRAME_DSISR, offsetof(struct trapframe, dsisr)); +ASSYM(FRAME_EXC, offsetof(struct trapframe, exc)); + +ASSYM(SFRAMELEN, roundup(sizeof(struct switchframe), 16)); + +ASSYM(PCB_PMR, offsetof(struct pcb, pcb_pmreal)); +ASSYM(PCB_SP, offsetof(struct pcb, pcb_sp)); +ASSYM(PCB_SPL, offsetof(struct pcb, pcb_spl)); +ASSYM(PCB_FAULT, offsetof(struct pcb, pcb_onfault)); + +ASSYM(P_ADDR, offsetof(struct proc, p_addr)); Index: powerpc/powerpc/locore.s =================================================================== RCS file: locore.s diff -N locore.s --- /dev/null Tue Jun 5 21:44:00 2001 +++ locore.s Tue Jun 5 21:30:16 2001 @@ -0,0 +1,1373 @@ +/* $FreeBSD$ */ +/* $NetBSD: locore.S,v 1.24 2000/05/31 05:09:17 thorpej Exp $ */ + +/* + * Copyright (C) 2001 Benno Rice + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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. + */ +/* + * 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 "opt_ddb.h" +#include "opt_ipkdb.h" +#include "assym.s" + +#include + +#include +#include +#include +#include +#include + +/* + * Some instructions gas doesn't understand (yet?) + */ +#define bdneq bdnzf 2, + +/* + * Globals + */ + .data +GLOBAL(tmpstk) + .space 8208 +GLOBAL(esym) + .long 0 /* end of symbol table */ +GLOBAL(proc0paddr) + .long 0 /* proc0 p_addr */ +GLOBAL(PTmap) + .long 0 /* PTmap */ + +GLOBAL(intrnames) + .asciz "irq0", "irq1", "irq2", "irq3" + .asciz "irq4", "irq5", "irq6", "irq7" + .asciz "irq8", "irq9", "irq10", "irq11" + .asciz "irq12", "irq13", "irq14", "irq15" + .asciz "irq16", "irq17", "irq18", "irq19" + .asciz "irq20", "irq21", "irq22", "irq23" + .asciz "irq24", "irq25", "irq26", "irq27" + .asciz "irq28", "irq29", "irq30", "irq31" + .asciz "irq32", "irq33", "irq34", "irq35" + .asciz "irq36", "irq37", "irq38", "irq39" + .asciz "irq40", "irq41", "irq42", "irq43" + .asciz "irq44", "irq45", "irq46", "irq47" + .asciz "irq48", "irq49", "irq50", "irq51" + .asciz "irq52", "irq53", "irq54", "irq55" + .asciz "irq56", "irq57", "irq58", "irq59" + .asciz "irq60", "irq61", "irq62", "irq63" + .asciz "clock", "softclock", "softnet", "softserial" +GLOBAL(eintrnames) + .align 4 +GLOBAL(intrcnt) + .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + .long 0,0,0,0 +GLOBAL(eintrcnt) + +GLOBAL(ofmsr) + .long 0 /* msr used in Open Firmware */ + +GLOBAL(powersave) + .long 0 + +/* + * File-scope for locore.S + */ +idle_u: + .long 0 /* fake uarea during idle after exit */ +openfirmware_entry: + .long 0 /* openfirmware entry point */ +srsave: + .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + +/* + * This symbol is here for the benefit of kvm_mkdb, and is supposed to + * mark the start of kernel text. + */ + .text + .globl kernel_text +kernel_text: + +/* + * Startup entry. Note, this must be the first thing in the text + * segment! + */ + .text + .globl start +start: +#ifdef FIRMWORKSBUGS + mfmsr 0 + andi. 0,0,PSL_IR|PSL_DR + beq 1f + + bl ofwr_init +1: +#endif + li 8,0 + li 9,0x100 + mtctr 9 +1: + dcbf 0,8 + icbi 0,8 + addi 8,8,0x20 + bdnz 1b + sync + isync + + mtibatu 0,0 + mtibatu 1,0 + mtibatu 2,0 + mtibatu 3,0 + mtdbatu 0,0 + mtdbatu 1,0 + mtdbatu 2,0 + mtdbatu 3,0 + + li 9,0x12 + mtibatl 0,9 + mtdbatl 0,9 + li 9,0x1ffe + mtibatu 0,9 + mtdbatu 0,9 + isync + + lis 8,openfirmware_entry@ha + stw 5,openfirmware_entry@l(8) /* save client interface handler */ + mr 3,5 + + lis 1,tmpstk@ha + addi 1,1,tmpstk@l + addi 1,1,8192 + + mfmsr 0 + lis 9,ofmsr@ha + stw 0,ofmsr@l(9) + + bl OF_init + + lis 4,end@ha + addi 4,4,end@l + mr 5,4 + li 9,PAGE_MASK + add 4,4,9 + andc 4,4,9 + lis 9,OF_buf@ha + stw 4,OF_buf@l(9) + addi 4,4,PAGE_SIZE + lis 9,proc0paddr@ha + stw 4,proc0paddr@l(9) + addi 4,4,USPACE-FRAMELEN + mr 1,4 + xor 0,0,0 + stwu 0,-16(1) + + lis 3,kernel_text@ha + addi 3,3,kernel_text@l +#if 0 + mr 5,6 +#endif + + bl powerpc_init + bl mi_startup + b OF_exit + +#if 0 /* XXX: We may switch back to this in the future. */ +/* + * OpenFirmware entry point + */ +ENTRY(openfirmware) + mflr 0 /* save return address */ + stw 0,4(1) + stwu 1,-16(1) /* setup stack frame */ + + mfmsr 4 /* save msr */ + stw 4,8(1) + + lis 4,openfirmware_entry@ha /* get firmware entry point */ + lwz 4,openfirmware_entry@l(4) + mtlr 4 + + li 0,0 /* clear battable translations */ + mtdbatu 2,0 + mtdbatu 3,0 + mtibatu 2,0 + mtibatu 3,0 + + lis 4,ofmsr@ha /* Open Firmware msr */ + lwz 4,ofmsr@l(4) + mtmsr 4 + isync + + lis 4,srsave@ha /* save old SR */ + addi 4,4,srsave@l + li 5,0 +1: mfsrin 0,5 + stw 0,0(4) + addi 4,4,4 + addis 5,5,0x10000000@h + cmpwi 5,0 + bne 1b + + lis 4,ofw_pmap@ha /* load OFW SR */ + addi 4,4,ofw_pmap@l + lwz 0,PM_KERNELSR(4) + cmpwi 0,0 /* pm_sr[KERNEL_SR] == 0? */ + beq 2f /* then skip (not initialized yet) */ + li 5,0 +1: lwz 0,0(4) + mtsrin 0,5 + addi 4,4,4 + addis 5,5,0x10000000@h + cmpwi 5,0 + bne 1b +2: + blrl /* call Open Firmware */ + + mfmsr 4 + li 5,PSL_IR|PSL_DR + andc 4,4,5 + mtmsr 4 + isync + + lis 4,srsave@ha /* restore saved SR */ + addi 4,4,srsave@l + li 5,0 +1: lwz 0,0(4) + mtsrin 0,5 + addi 4,4,4 + addis 5,5,0x10000000@h + cmpwi 5,0 + bne 1b + + lwz 4,8(1) /* restore msr */ + mtmsr 4 + isync + + lwz 1,0(1) /* and return */ + lwz 0,4(1) + mtlr 0 + blr +#endif + +/* + * Switch to/from OpenFirmware real mode stack + * + * Note: has to be called as the very first thing in OpenFirmware interface + * routines. + * E.g.: + * int + * OF_xxx(arg1, arg2) + * type arg1, arg2; + * { + * static struct { + * char *name; + * int nargs; + * int nreturns; + * char *method; + * int arg1; + * int arg2; + * int ret; + * } args = { + * "xxx", + * 2, + * 1, + * }; + * + * ofw_stack(); + * args.arg1 = arg1; + * args.arg2 = arg2; + * if (openfirmware(&args) < 0) + * return -1; + * return args.ret; + * } + */ + + .local firmstk + .comm firmstk,PAGE_SIZE,8 + +ENTRY(ofw_stack) + mfmsr 8 /* turn off interrupts */ + andi. 0,8,~(PSL_EE|PSL_RI)@l + mtmsr 0 + stw 8,4(1) /* abuse return address slot */ + + lwz 5,0(1) /* get length of stack frame */ + subf 5,1,5 + + lis 7,firmstk+PAGE_SIZE-8@ha + addi 7,7,firmstk+PAGE_SIZE-8@l + lis 6,ofw_back@ha + addi 6,6,ofw_back@l + subf 4,5,7 /* make room for stack frame on + new stack */ + stw 6,-4(7) /* setup return pointer */ + stwu 1,-8(7) + + stw 7,-8(4) + + addi 3,1,8 + addi 1,4,-8 + subi 5,5,8 + + cmpw 3,4 + beqlr + + mr 0,5 + addi 5,5,-1 + cmpwi 0,0 + beqlr + +1: lwz 0,0(3) + stw 0,0(4) + addi 3,3,1 + addi 4,4,1 + mr 0,5 + addi 5,5,-1 + cmpwi 0,0 + bne 1b + blr + +ofw_back: + lwz 1,0(1) /* get callers original stack pointer */ + + lwz 0,4(1) /* get saved msr from abused slot */ + mtmsr 0 + + lwz 1,0(1) /* return */ + 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 + .align 4 +intstk: + .space INTSTK /* interrupt stack */ + +GLOBAL(intr_depth) + .long -1 /* in-use marker */ + +#define SPILLSTK 1024 /* 1K spill stack */ + + .comm 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 trapcode,trapsize +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 */ + mfsprg 1,0 + lwz 1,GD_CURPCB(1) + addi 1,1,USPACE /* stack is top of user struct */ +1: + bla s_trap +trapsize = .-trapcode + +/* + * For ALI: has to save DSISR and DAR + */ + .globl alitrap,alisize +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 */ + mfsprg 1,0 + lwz 1,GD_CURPCB(1) + addi 1,1,USPACE /* stack is top of user struct */ +1: + bla s_trap +alisize = .-alitrap + +/* + * Similar to the above for DSI + * Has to handle BAT spills + * and standard pagetable spills + */ + .globl dsitrap,dsisize +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 */ + + /* get batu */ + addis 31,31,battable@ha + lwz 30,battable@l(31) + mtcr 30 + bc 4,30,1f /* branch if supervisor valid is + false */ + /* get batl */ + lwz 31,battable+4@l(31) +/* 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 +dsisize = .-dsitrap + +/* + * Similar to the above for ISI + */ + .globl isitrap,isisize +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 */ + + /* get batu */ + addis 31,31,battable@ha + lwz 30,battable@l(31) + mtcr 30 + bc 4,30,1f /* branch if supervisor valid is + false */ + mtibatu 3,30 + + /* get batl */ + lwz 30,battable+4@l(31) + mtibatl 3,30 + + mtcr 29 /* restore CR */ + lmw 28,disisave(0) /* restore r28-r31 */ + rfi /* return to trapped code */ +1: + bla s_isitrap +isisize = .-isitrap + +/* + * This one for the external interrupt handler. + */ + .globl extint,extsize +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 +extsize = .-extint + +/* + * And this one for the decrementer interrupt handler. + */ + .globl decrint,decrsize +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 +decrsize = .-decrint + +/* + * Now the tlb software load for 603 processors: + * (Code essentially from the 603e User Manual, Chapter 5, but + * corrected a lot.) + */ +#define DMISS 976 +#define DCMP 977 +#define HASH1 978 +#define HASH2 979 +#define IMISS 980 +#define ICMP 981 +#define RPA 982 + + .globl tlbimiss,tlbimsize +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 */ + oris 2,2,0x8000000@h /* set srr<4> to flag prot violation */ + b 6f +5: /* not found anywhere */ + mfsrr1 3 + andi. 2,3,0xffff /* clean upper srr1 */ + oris 2,2,0x40000000@h /* set srr1<1> to flag pte not found */ +6: + mtctr 0 /* restore counter */ + mtsrr1 2 + mfmsr 0 + xoris 0,0,0x20000@h /* flip the msr bit */ + mtcrf 0x80,3 /* restore cr0 */ + mtmsr 0 /* now with native gprs */ + isync + ba EXC_ISI +tlbimsize = .-tlbimiss + + .globl tlbdlmiss,tlbdlmsize +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,0x40000000@h /* 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,0x20000@h /* flip the msr bit */ + mtcrf 0x80,3 /* restore cr0 */ + mtmsr 0 /* now with native gprs */ + isync + ba EXC_DSI +tlbdlmsize = .-tlbdlmiss + + .globl tlbdsmiss,tlbdsmsize +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,0xa000000@h /* 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,0x42000000@h /* 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,0x20000@h /* flip the msr bit */ + mtcrf 0x80,3 /* restore cr0 */ + mtmsr 0 /* now with native gprs */ + isync + ba EXC_DSI +tlbdsmsize = .-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 ddblow,ddbsize +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 +ddbsize = .-ddblow +#endif /* DDB */ + +#ifdef IPKDB +#define ipkdbsave 0xde0 /* primary save area for IPKDB */ +/* + * In case of IPKDB we want a separate trap catcher for it + */ + + .local ipkdbstk + .comm ipkdbstk,INTSTK,8 /* ipkdb stack */ + + .globl ipkdblow,ipkdbsize +ipkdblow: + mtsprg 1,1 /* save SP */ + stmw 28,ipkdbsave(0) /* free r28-r31 */ + mflr 28 /* save LR */ + mfcr 29 /* save CR */ + lis 1,ipkdbstk+INTSTK@ha /* get new SP */ + addi 1,1,ipkdbstk+INTSTK@l + bla ipkdbtrap +ipkdbsize = .-ipkdblow +#endif /* IPKDB */ + +/* + * 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; \ + andi. 2,2,~(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@l; \ + 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,curpm@ha; get real address of pmap */ \ +/* lwz 2,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 */ + mfsprg 1,0 + lwz 1,GD_CURPCB(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@h + ori 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)@l + mtmsr 7 + isync +/* Call C trap code: */ +trapagain: + addi 3,1,8 + bl 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,astpending@ha + lwz 4,astpending@l(3) + andi. 4,4,1 + beq 1f +#if 0 /* XXX */ + li 6,EXC_AST +#endif + stw 6,FRAME_EXC+8(1) + b trapagain +1: +#if 0 + FRAME_LEAVE(tempsave) +#endif + rfi + +/* + * Child comes here at the end of a fork. + * Mostly similar to the above. + */ + .globl fork_trampoline +fork_trampoline: + xor 3,3,3 +#if 0 /* XXX */ + bl lcsplx +#endif + 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 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,intr_depth@ha; \ + lwz 5,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)@h; \ + ori 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 extint_call +extintr: + INTRENTER +extint_call: + bl 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 */ + mfsprg 3,0 /* get globaldata */ + lwz 3,GD_CURPCB(3) /* get curpcb from globaldata */ + lwz 3,PCB_PMR(3) /* get pmap real address from curpcb */ + mtsr KERNEL_SR,3 + lis 3,astpending@ha /* Test AST pending */ + lwz 4,astpending@l(3) + andi. 4,4,1 + beq 1f +/* Setup for entry to realtrap: */ + lwz 3,0(1) /* get saved SP */ + mtsprg 1,3 +#if 0 /* XXX */ + li 6,EXC_AST +#endif + 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,intr_depth@ha /* adjust reentrancy count */ + lwz 31,intr_depth@l(30) + addi 31,31,-1 + stw 31,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,intr_depth@ha /* adjust reentrancy count */ + lwz 4,intr_depth@l(3) + addi 4,4,-1 + stw 4,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 decr_intr + b intr_exit + +#ifdef DDB +/* + * Deliberate entry to ddbtrap + */ + .globl ddb_trap +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 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 */ + +#ifdef IPKDB +/* + * Deliberate entry to ipkdbtrap + */ + .globl ipkdb_trap +ipkdb_trap: + mtsprg 1,1 + 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 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 _ipkdbfault +_ipkdbfault: + mfsrr0 3 + addi 3,3,4 + mtsrr0 3 + li 3,-1 + rfi + +/* + * int ipkdbfbyte(unsigned char *p) + */ + .globl ipkdbfbyte +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,ipkdbsr@ha + lwz 8,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 ipkdbsbyte +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,ipkdbsr@ha + lwz 8,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 /* IPKDB */ + +/* + * 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 setfault +setfault: + mflr 0 + mfcr 12 + mfsprg 4,0 + lwz 4,GD_CURPCB(4) + stw 3,PCB_FAULT(4) + stw 0,0(3) + stw 1,4(3) + stw 2,8(3) + stmw 12,12(3) + xor 3,3,3 + blr + +/* + * Signal "trampoline" code. + */ + .globl sigcode +sigcode: + b sys_exit +esigcode: + .data +GLOBAL(szsigcode) + .long esigcode-sigcode + .text + Index: powerpc/powerpc/machdep.c =================================================================== RCS file: machdep.c diff -N machdep.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ machdep.c Tue Jun 5 21:03:00 2001 @@ -0,0 +1,952 @@ +/* $NetBSD: machdep.c,v 1.74.2.1 2000/11/01 16:13:48 tv Exp $ */ +/* $FreeBSD$ */ + +/* + * 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. + */ +/* + * Copyright (C) 2001 Benno Rice + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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 "opt_ddb.h" +#include "opt_compat.h" +#include "opt_msgbuf.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int cold = 1; + +struct mtx sched_lock; +struct mtx Giant; + +struct user *proc0paddr; + +char machine[] = "powerpc"; +SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, ""); + +static char model[128]; +SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, model, 0, ""); + +char bootpath[256]; + +#ifdef DDB +/* start and end of kernel symbol table */ +void *ksym_start, *ksym_end; +#endif /* DDB */ + +static void cpu_startup(void *); +SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL) + +void powerpc_init(u_int, u_int, u_int, char *); + +int save_ofw_mapping(void); +int restore_ofw_mapping(void); + +void install_extint(void (*)(void)); + +void osendsig(sig_t, int, sigset_t *, u_long); + +struct msgbuf *msgbufp = 0; + +int bootverbose = 0, Maxmem = 0; +long dumplo; + +vm_offset_t phys_avail[10]; + +static int chosen; + +struct pmap ofw_pmap; +extern int ofmsr; + +struct bat battable[16]; + +static void identifycpu(void); + +static vm_offset_t buffer_sva, buffer_eva; +vm_offset_t clean_sva, clean_eva; +static vm_offset_t pager_sva, pager_eva; + +static void +powerpc_ofw_shutdown(void *junk, int howto) +{ + if (howto & RB_HALT) { + OF_exit(); + } +} + +static void +cpu_startup(void *dummy) +{ + unsigned int i; + caddr_t v; + vm_offset_t maxaddr; + vm_size_t size; + vm_offset_t firstaddr; + vm_offset_t minaddr; + + size = 0; + + /* + * Good {morning,afternoon,evening,night}. + */ + identifycpu(); + + /* startrtclock(); */ +#ifdef PERFMON + perfmon_init(); +#endif + printf("real memory = %ld (%ldK bytes)\n", ptoa(Maxmem), + ptoa(Maxmem) / 1024); + + /* + * Display any holes after the first chunk of extended memory. + */ + if (bootverbose) { + int indx; + + printf("Physical memory chunk(s):\n"); + for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) { + int size1 = phys_avail[indx + 1] - phys_avail[indx]; + + printf("0x%08x - 0x%08x, %d bytes (%d pages)\n", + phys_avail[indx], phys_avail[indx + 1] - 1, size1, + size1 / PAGE_SIZE); + } + } + + /* + * Calculate callout wheel size + */ + for (callwheelsize = 1, callwheelbits = 0; + callwheelsize < ncallout; + callwheelsize <<= 1, ++callwheelbits) + ; + callwheelmask = callwheelsize - 1; + + /* + * Allocate space for system data structures. + * The first available kernel virtual address is in "v". + * As pages of kernel virtual memory are allocated, "v" is incremented. + * As pages of memory are allocated and cleared, + * "firstaddr" is incremented. + * An index into the kernel page table corresponding to the + * virtual memory address maintained in "v" is kept in "mapaddr". + */ + + /* + * Make two passes. The first pass calculates how much memory is + * needed and allocates it. The second pass assigns virtual + * addresses to the various data structures. + */ + firstaddr = 0; +again: + v = (caddr_t)firstaddr; + +#define valloc(name, type, num) \ + (name) = (type *)v; v = (caddr_t)((name)+(num)) +#define valloclim(name, type, num, lim) \ + (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num))) + + valloc(callout, struct callout, ncallout); + valloc(callwheel, struct callout_tailq, callwheelsize); + + /* + * The nominal buffer size (and minimum KVA allocation) is BKVASIZE. + * For the first 64MB of ram nominally allocate sufficient buffers to + * cover 1/4 of our ram. Beyond the first 64MB allocate additional + * buffers to cover 1/20 of our ram over 64MB. + */ + + if (nbuf == 0) { + int factor = 4 * BKVASIZE / PAGE_SIZE; + + nbuf = 50; + if (Maxmem > 1024) + nbuf += min((Maxmem - 1024) / factor, 16384 / factor); + if (Maxmem > 16384) + nbuf += (Maxmem - 16384) * 2 / (factor * 5); + } + nswbuf = max(min(nbuf/4, 64), 16); + + valloc(swbuf, struct buf, nswbuf); + valloc(buf, struct buf, nbuf); + v = bufhashinit(v); + + /* + * End of first pass, size has been calculated so allocate memory + */ + if (firstaddr == 0) { + size = (vm_size_t)(v - firstaddr); + firstaddr = (vm_offset_t)kmem_alloc(kernel_map, + round_page(size)); + if (firstaddr == 0) + panic("startup: no room for tables"); + goto again; + } + + /* + * End of second pass, addresses have been assigned + */ + if ((vm_size_t)(v - firstaddr) != size) + panic("startup: table size inconsistency"); + + clean_map = kmem_suballoc(kernel_map, &clean_sva, &clean_eva, + (nbuf*BKVASIZE) + (nswbuf*MAXPHYS) + pager_map_size); + buffer_map = kmem_suballoc(clean_map, &buffer_sva, &buffer_eva, + (nbuf*BKVASIZE)); + pager_map = kmem_suballoc(clean_map, &pager_sva, &pager_eva, + (nswbuf*MAXPHYS) + pager_map_size); + pager_map->system_map = 1; + exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, + (16*(ARG_MAX+(PAGE_SIZE*3)))); + + /* + * XXX: Mbuf system machine-specific initializations should + * go here, if anywhere. + */ + + /* + * Initialize callouts + */ + SLIST_INIT(&callfree); + for (i = 0; i < ncallout; i++) { + callout_init(&callout[i], 0); + callout[i].c_flags = CALLOUT_LOCAL_ALLOC; + SLIST_INSERT_HEAD(&callfree, &callout[i], c_links.sle); + } + + for (i = 0; i < callwheelsize; i++) { + TAILQ_INIT(&callwheel[i]); + } + + mtx_init(&callout_lock, "callout", MTX_SPIN); + +#if defined(USERCONFIG) +#if defined(USERCONFIG_BOOT) + if (1) +#else + if (boothowto & RB_CONFIG) +#endif + { + userconfig(); + cninit(); /* the preferred console may have changed */ + } +#endif + + printf("avail memory = %ld (%ldK bytes)\n", ptoa(cnt.v_free_count), + ptoa(cnt.v_free_count) / 1024); + + /* + * Set up buffers, so they can be used to read disk labels. + */ + bufinit(); + vm_pager_bufferinit(); + EVENTHANDLER_REGISTER(shutdown_final, powerpc_ofw_shutdown, 0, + SHUTDOWN_PRI_LAST); + +#ifdef SMP + /* + * OK, enough kmem_alloc/malloc state should be up, lets get on with it! + */ + mp_start(); /* fire up the secondaries */ + mp_announce(); +#endif /* SMP */ +} + +void +identifycpu() +{ + int pvr, cpu; + + /* + * Find cpu type (Do it by OpenFirmware?) + */ + __asm ("mfpvr %0" : "=r"(pvr)); + cpu = pvr >> 16; + switch (cpu) { + case 1: + sprintf(model, "601"); + break; + case 3: + sprintf(model, "603"); + break; + case 4: + sprintf(model, "604"); + break; + case 5: + sprintf(model, "602"); + break; + case 6: + sprintf(model, "603e"); + break; + case 7: + sprintf(model, "603ev"); + break; + case 8: + sprintf(model, "750 (G3)"); + break; + case 9: + sprintf(model, "604ev"); + break; + case 12: + sprintf(model, "7400 (G4)"); + break; + case 20: + sprintf(model, "620"); + break; + default: + sprintf(model, "Version %x", cpu); + break; + } + sprintf(model + strlen(model), " (Revision %x)", pvr & 0xffff); + printf("CPU: PowerPC %s\n", model); +} + +extern char kernel_text[], _end[]; + +extern void *trapcode, *trapsize; +extern void *alitrap, *alisize; +extern void *dsitrap, *dsisize; +extern void *isitrap, *isisize; +extern void *decrint, *decrsize; +extern void *tlbimiss, *tlbimsize; +extern void *tlbdlmiss, *tlbdlmsize; +extern void *tlbdsmiss, *tlbdsmsize; + +#if 0 /* XXX: interrupt handler. We'll get to this later */ +extern void ext_intr(void); +#endif + +#ifdef DDB +extern ddblow, ddbsize; +#endif +#ifdef IPKDB +extern ipkdblow, ipkdbsize; +#endif + +static struct globaldata tmpglobal; + +void +powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args) +{ + int exc, scratch; + struct mem_region *allmem, *availmem, *mp; + struct globaldata *globalp; + + /* + * Set up BAT0 to only map the lowest 256 MB area + */ + battable[0].batl = BATL(0x00000000, BAT_M, BAT_PP_RW); + battable[0].batu = BATU(0x00000000, BAT_BL_256M, BAT_Vs); + + /* + * Map PCI memory space. + */ + battable[0x8].batl = BATL(0x80000000, BAT_I, BAT_PP_RW); + battable[0x8].batu = BATU(0x80000000, BAT_BL_256M, BAT_Vs); + + battable[0x9].batl = BATL(0x90000000, BAT_I, BAT_PP_RW); + battable[0x9].batu = BATU(0x90000000, BAT_BL_256M, BAT_Vs); + + battable[0xa].batl = BATL(0xa0000000, BAT_I, BAT_PP_RW); + battable[0xa].batu = BATU(0xa0000000, BAT_BL_256M, BAT_Vs); + + /* + * Map obio devices. + */ + battable[0xf].batl = BATL(0xf0000000, BAT_I, BAT_PP_RW); + battable[0xf].batu = BATU(0xf0000000, BAT_BL_256M, BAT_Vs); + + /* + * Now setup fixed bat registers + * + * Note that we still run in real mode, and the BAT + * registers were cleared above. + */ + /* BAT0 used for initial 256 MB segment */ + __asm __volatile ("mtibatl 0,%0; mtibatu 0,%1;" + "mtdbatl 0,%0; mtdbatu 0,%1;" + :: "r"(battable[0].batl), "r"(battable[0].batu)); + /* + * Set up battable to map all RAM regions. + * This is here because mem_regions() call needs bat0 set up. + */ + mem_regions(&allmem, &availmem); + for (mp = allmem; mp->size; mp++) { + vm_offset_t pa = mp->start & 0xf0000000; + vm_offset_t end = mp->start + mp->size; + + do { + u_int n = pa >> 28; + + battable[n].batl = BATL(pa, BAT_M, BAT_PP_RW); + battable[n].batu = BATU(pa, BAT_BL_256M, BAT_Vs); + pa += 0x10000000; + } while (pa < end); + } + + chosen = OF_finddevice("/chosen"); + save_ofw_mapping(); + + proc0.p_addr = proc0paddr; + bzero(proc0.p_addr, sizeof *proc0.p_addr); + + LIST_INIT(&proc0.p_contested); + +/* XXX: NetBSDism I _think_. Not sure yet. */ +#if 0 + curpm = curpcb->pcb_pmreal = curpcb->pcb_pm = kernel_pmap; +#endif + + /* + * Initialise some mutexes. + */ + mtx_init(&Giant, "Giant", MTX_DEF | MTX_RECURSE); + mtx_init(&sched_lock, "sched lock", MTX_SPIN | MTX_RECURSE); + mtx_init(&proc0.p_mtx, "process lock", MTX_DEF); + mtx_lock(&Giant); + + /* + * Initialise console. + */ + cninit(); + +#ifdef __notyet__ /* Needs some rethinking regarding real/virtual OFW */ + OF_set_callback(callback); +#endif + + /* + * 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; + case EXC_ALI: + bcopy(&alitrap, (void *)EXC_ALI, (size_t)&alisize); + break; + 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_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 defined(DDB) || defined(IPKDB) + case EXC_TRC: + case EXC_PGM: + case EXC_BPT: +#if defined(DDB) + bcopy(&ddblow, (void *)exc, (size_t)&ddbsize); +#else + bcopy(&ipkdblow, (void *)exc, (size_t)&ipkdbsize); +#endif + break; +#endif /* DDB || IPKDB */ + } + } + +#if 0 /* XXX: coming soon... */ + /* + * external interrupt handler install + */ + install_extint(ext_intr); + + __syncicache((void *)EXC_RST, EXC_LAST - EXC_RST + 0x100); +#endif + + /* + * Now enable translation (and machine checks/recoverable interrupts). + */ + __asm __volatile ("mfmsr %0; ori %0,%0,%1; mtmsr %0; isync" + : "=r"(scratch) : "K"(PSL_IR|PSL_DR|PSL_ME|PSL_RI)); + + + ofmsr &= ~PSL_IP; + + /* + * Parse arg string. + */ +#ifdef DDB + bcopy(args + strlen(args) + 1, &startsym, sizeof(startsym)); + bcopy(args + strlen(args) + 5, &endsym, sizeof(endsym)); + if (startsym == NULL || endsym == NULL) + startsym = endsym = NULL; +#endif + + strcpy(bootpath, args); + 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 'v': + boothowto |= RB_VERBOSE; + break; + } + } + } + +#ifdef DDB + ddb_init((int)((u_int)endsym - (u_int)startsym), startsym, endsym); +#endif +#ifdef IPKDB + /* + * Now trap to IPKDB + */ + ipkdb_init(); + if (boothowto & RB_KDB) + ipkdb_connect(0); +#endif + + /* + * Set the page size. + */ +#if 0 + vm_set_page_size(); +#endif + + /* + * Initialize pmap module. + */ + pmap_bootstrap(startkernel, endkernel); + + restore_ofw_mapping(); + + /* + * Setup the global data for the bootstrap cpu. + */ + globalp = (struct globaldata *) &tmpglobal; + + /* + * XXX: Pass 0 as CPU id. This is bad. We need to work out + * XXX: which CPU we are somehow. + */ + globaldata_init(globalp, 0, sizeof(struct globaldata)); + __asm("mtsprg 0,%0\n" :: "r" (globalp)); + + PCPU_GET(next_asn) = 1; /* 0 used for proc0 pmap */ + PCPU_SET(curproc, &proc0); + PCPU_SET(spinlocks, NULL); +} + +static int N_mapping; +static struct { + vm_offset_t va; + int len; + vm_offset_t pa; + int mode; +} ofw_mapping[256]; + +int +save_ofw_mapping() +{ + int mmui, mmu; + + OF_getprop(chosen, "mmu", &mmui, 4); + mmu = OF_instance_to_package(mmui); + + bzero(ofw_mapping, sizeof(ofw_mapping)); + + N_mapping = + OF_getprop(mmu, "translations", ofw_mapping, sizeof(ofw_mapping)); + N_mapping /= sizeof(ofw_mapping[0]); + + return 0; +} + +int +restore_ofw_mapping() +{ + int i; + struct vm_page pg; + + pmap_pinit(&ofw_pmap); + + ofw_pmap.pm_sr[KERNEL_SR] = KERNEL_SEGMENT; + + for (i = 0; i < N_mapping; i++) { + vm_offset_t pa = ofw_mapping[i].pa; + vm_offset_t va = ofw_mapping[i].va; + int size = ofw_mapping[i].len; + + if (va < 0x90000000) /* XXX */ + continue; + + while (size > 0) { + pg.phys_addr = pa; + pmap_enter(&ofw_pmap, va, &pg, VM_PROT_ALL, + VM_PROT_ALL); + pa += PAGE_SIZE; + va += PAGE_SIZE; + size -= PAGE_SIZE; + } + } + + return 0; +} + +void +bzero(void *buf, size_t len) +{ + caddr_t p; + + p = buf; + + while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) { + *p++ = 0; + len--; + } + + while (len >= sizeof(u_long) * 8) { + *(u_long*) p = 0; + *((u_long*) p + 1) = 0; + *((u_long*) p + 2) = 0; + *((u_long*) p + 3) = 0; + len -= sizeof(u_long) * 8; + *((u_long*) p + 4) = 0; + *((u_long*) p + 5) = 0; + *((u_long*) p + 6) = 0; + *((u_long*) p + 7) = 0; + p += sizeof(u_long) * 8; + } + + while (len >= sizeof(u_long)) { + *(u_long*) p = 0; + len -= sizeof(u_long); + p += sizeof(u_long); + } + + while (len) { + *p++ = 0; + len--; + } +} + +#if 0 +void +delay(unsigned n) +{ + u_long tb; + + do { + __asm __volatile("mftb %0" : "=r" (tb)); + } while (n > (int)(tb & 0xffffffff)); +} +#endif + +void +osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) +{ + /* XXX: To be done */ + return; +} + +void +sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) +{ + /* XXX: To be done */ + return; +} + +int +osigreturn(struct proc *p, struct osigreturn_args *uap) +{ + /* XXX: To be done */ + return(ENOSYS); +} + +int +sigreturn(struct proc *p, struct sigreturn_args *uap) +{ + /* XXX: To be done */ + return(ENOSYS); +} + +void +cpu_boot(int howto) +{ +} + +/* + * Shutdown the CPU as much as possible. + */ +void +cpu_halt(void) +{ + OF_exit(); +} + +/* + * Set set up registers on exec. + */ +void +setregs(struct proc *p, u_long entry, u_long stack, u_long ps_strings) +{ + struct trapframe *tf; + struct ps_strings arginfo; + + tf = trapframe(p); + + bzero(tf, sizeof *tf); + tf->fixreg[1] = -roundup(-stack + 8, 16); + + /* + * XXX Machine-independent code has already copied arguments and + * XXX environment to userland. Get them back here. + */ + (void)copyin((char *)PS_STRINGS, &arginfo, sizeof(arginfo)); + + /* + * Set up arguments for _start(): + * _start(argc, argv, envp, obj, cleanup, ps_strings); + * + * Notes: + * - obj and cleanup are the auxilliary and termination + * vectors. They are fixed up by ld.elf_so. + * - ps_strings is a NetBSD extention, and will be + * ignored by executables which are strictly + * compliant with the SVR4 ABI. + * + * XXX We have to set both regs and retval here due to different + * XXX calling convention in trap.c and init_main.c. + */ + tf->fixreg[3] = arginfo.ps_nargvstr; + tf->fixreg[4] = (register_t)arginfo.ps_argvstr; + tf->fixreg[5] = (register_t)arginfo.ps_envstr; + tf->fixreg[6] = 0; /* auxillary vector */ + tf->fixreg[7] = 0; /* termination vector */ + tf->fixreg[8] = (register_t)PS_STRINGS; /* NetBSD extension */ + + tf->srr0 = entry; + tf->srr1 = PSL_MBO | PSL_USERSET | PSL_FE_DFLT; + p->p_addr->u_pcb.pcb_flags = 0; +} + +extern void *extint, *extsize; +extern u_long extint_call; + +#if 0 +void +install_extint(void (*handler)(void)) +{ + u_long offset; + int omsr, msr; + + offset = (u_long)handler - (u_long)&extint_call; + +#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)); +} +#endif + +#if !defined(DDB) +void +Debugger(const char *msg) +{ + printf("Debugger(\"%s\") called.\n", msg); +} +#endif /* !defined(DDB) */ + +/* XXX: dummy {fill,set}_[fp]regs */ +int +fill_regs(struct proc *p, struct reg *regs) +{ + return (ENOSYS); +} + +int +fill_fpregs(struct proc *p, struct fpreg *fpregs) +{ + return (ENOSYS); +} + +int +set_regs(struct proc *p, struct reg *regs) +{ + return (ENOSYS); +} + +int +set_fpregs(struct proc *p, struct fpreg *fpregs) +{ + return (ENOSYS); +} + +int +ptrace_set_pc(struct proc *p, unsigned long addr) +{ + /* XXX: coming soon... */ + return (ENOSYS); +} + +int +ptrace_single_step(struct proc *p) +{ + /* XXX: coming soon... */ + return (ENOSYS); +} + +int +ptrace_write_u(struct proc *p, vm_offset_t off, long data) +{ + /* XXX: coming soon... */ + return (ENOSYS); +} + +int +ptrace_read_u_check(struct proc *p, vm_offset_t addr, size_t len) +{ + /* XXX: coming soon... */ + return (ENOSYS); +} + +int +ptrace_clear_single_step(struct proc *p) +{ + /* XXX: coming soon... */ + return (ENOSYS); +} + +/* + * Initialise a struct globaldata. + */ +void +globaldata_init(struct globaldata *globaldata, int cpuid, size_t sz) +{ + bzero(globaldata, sz); + globaldata->gd_cpuid = cpuid; + globaldata->gd_next_asn = 0; + globaldata->gd_current_asngen = 1; +} Index: powerpc/powerpc/mp_machdep.c =================================================================== RCS file: /home/ncvs/src/sys/powerpc/powerpc/mp_machdep.c,v retrieving revision 1.7 diff -u -r1.7 mp_machdep.c --- powerpc/powerpc/mp_machdep.c 2001/05/10 17:58:35 1.7 +++ powerpc/powerpc/mp_machdep.c 2001/06/03 08:34:25 @@ -48,28 +48,6 @@ int boot_cpu_id; -/* - * XXX: needs to move to machdep.c - * - * Initialise a struct globaldata. - */ -void -globaldata_init(struct globaldata *globaldata, int cpuno, size_t sz) -{ - - bzero(globaldata, sz); - globaldata->gd_idlepcbphys = vtophys((vm_offset_t) &globaldata->gd_idlepcb); - globaldata->gd_idlepcb.apcb_ksp = (u_int64_t) - ((caddr_t) globaldata + sz - sizeof(struct trapframe)); - globaldata->gd_idlepcb.apcb_ptbr = proc0.p_addr->u_pcb.pcb_hw.apcb_ptbr; - globaldata->gd_cpuno = cpuno; - globaldata->gd_other_cpus = all_cpus & ~(1 << cpuno); - globaldata->gd_next_asn = 0; - globaldata->gd_current_asngen = 1; - globaldata->gd_cpuid = cpuno; - globaldata_register(globaldata); -} - int cpu_mp_probe(void) { Index: powerpc/powerpc/ofw_machdep.c =================================================================== RCS file: ofw_machdep.c diff -N ofw_machdep.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ ofw_machdep.c Tue Jun 5 21:19:55 2001 @@ -0,0 +1,123 @@ +/* $NetBSD: ofw_machdep.c,v 1.5 2000/05/23 13:25:43 tsubai Exp $ */ +/* $FreeBSD$ */ + +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#define OFMEM_REGIONS 32 +static struct mem_region OFmem[OFMEM_REGIONS + 1], OFavail[OFMEM_REGIONS + 3]; + +extern long ofmsr; +static int (*ofwcall)(void *); + +/* + * This is called during powerpc_init, 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 +mem_regions(struct mem_region **memp, struct mem_region **availp) +{ + int phandle /*, i, j, cnt*/; + + /* + * Get memory. + */ + if ((phandle = OF_finddevice("/memory")) == -1 + || OF_getprop(phandle, "reg", + OFmem, sizeof OFmem[0] * OFMEM_REGIONS) + <= 0 + || OF_getprop(phandle, "available", + OFavail, sizeof OFavail[0] * OFMEM_REGIONS) + <= 0) + panic("no memory?"); + *memp = OFmem; + *availp = OFavail; +} + +void +set_openfirm_callback(int (*openfirm)(void *)) +{ + ofwcall = openfirm; +} + +int +openfirmware(void *args) +{ + long oldmsr; + int result; + + __asm( "\t" + "mfmsr %0\n\t" + "mtmsr %1\n\t" + "isync\n" + : "=r" (oldmsr) + : "r" (ofmsr) + ); + + result = ofwcall(args); + + __asm( "\t" + "mtmsr %0\n\t" + "isync\n" + : : "r" (oldmsr) + ); + + return (result); +} + +void +ppc_exit() +{ + OF_exit(); +} + +void +ppc_boot(str) + char *str; +{ + OF_boot(str); +} Index: powerpc/powerpc/ofwmagic.s =================================================================== RCS file: ofwmagic.s diff -N ofwmagic.s --- /dev/null Tue Jun 5 21:44:00 2001 +++ ofwmagic.s Sat Dec 16 19:31:59 2000 @@ -0,0 +1,74 @@ +/* $NetBSD: ofwmagic.S,v 1.2 1997/10/09 08:38:18 jtc Exp $ */ + +/*- + * Copyright (c) 1997 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. + */ + +/* + * Magic note section used by OpenFirmware. + */ + + .section ".note" + + # note header + + # length of name + .long 8 + + # note descriptor size + .long 20 + + # note type (IEEE 1275) + .long 0x1275 + + # name of owner + .asciz "PowerPC" + .balign 4 + + + # note descriptor + + # real mode (-1) or virtual mode (0) + .long 0 + + # real-base + .long -1 + # real-size + .long -1 + + # virt-base + .long -1 + # virt-size + .long -1 Index: powerpc/powerpc/pmap.c =================================================================== RCS file: pmap.c diff -N pmap.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ pmap.c Mon Jun 4 23:00:04 2001 @@ -0,0 +1,1718 @@ +/* $NetBSD: pmap.c,v 1.28 2000/03/26 20:42:36 kleink Exp $ */ +/* $FreeBSD$ */ + +/* + * 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. + */ +/* + * Copyright (C) 2001 Benno Rice. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +pte_t *ptable; +int ptab_cnt; +u_int ptab_mask; +#define HTABSIZE (ptab_cnt * 64) + +#define MINPV 2048 + +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 */ + +static struct pmap kernel_pmap_store; +pmap_t kernel_pmap; + +static int npgs; +static u_int nextavail; + +#ifndef MSGBUFADDR +extern vm_offset_t msgbuf_paddr; +#endif + +static struct mem_region *mem, *avail; + +vm_offset_t avail_start; +vm_offset_t avail_end; +vm_offset_t virtual_avail; +vm_offset_t virtual_end; + +vm_offset_t kernel_vm_end; + +static int pmap_pagedaemon_waken = 0; + +extern unsigned int Maxmem; + +#define ATTRSHFT 4 + +struct pv_entry *pv_table; + +static vm_zone_t pvzone; +static struct vm_zone pvzone_store; +static struct vm_object pvzone_obj; +static int pv_entry_count=0, pv_entry_max=0, pv_entry_high_water=0; +static struct pv_entry *pvinit; + +#if !defined(PMAP_SHPGPERPROC) +#define PMAP_SHPGPERPROC 200 +#endif + +struct pv_page; +struct pv_page_info { + LIST_ENTRY(pv_page) pgi_list; + struct pv_entry *pgi_freelist; + int pgi_nfree; +}; +#define NPVPPG ((PAGE_SIZE - sizeof(struct pv_page_info)) / sizeof(struct pv_entry)) +struct pv_page { + struct pv_page_info pvp_pgi; + struct pv_entry pvp_pv[NPVPPG]; +}; +LIST_HEAD(pv_page_list, pv_page) pv_page_freelist; +int pv_nfree; +int pv_pcnt; +static struct pv_entry *pmap_alloc_pv(void); +static void pmap_free_pv(struct pv_entry *); + +struct po_page; +struct po_page_info { + LIST_ENTRY(po_page) pgi_list; + vm_page_t pgi_page; + LIST_HEAD(po_freelist, pte_ovfl) pgi_freelist; + int pgi_nfree; +}; +#define NPOPPG ((PAGE_SIZE - sizeof(struct po_page_info)) / sizeof(struct pte_ovfl)) +struct po_page { + struct po_page_info pop_pgi; + struct pte_ovfl pop_po[NPOPPG]; +}; +LIST_HEAD(po_page_list, po_page) po_page_freelist; +int po_nfree; +int po_pcnt; +static struct pte_ovfl *poalloc(void); +static void pofree(struct pte_ovfl *, int); + +static u_int usedsr[NPMAPS / sizeof(u_int) / 8]; + +static int pmap_initialized; + +int pte_spill(vm_offset_t); + +/* + * These small routines may have to be replaced, + * if/when we support processors other that the 604. + */ +static __inline void +tlbie(vm_offset_t ea) +{ + __asm __volatile ("tlbie %0" :: "r"(ea)); +} + +static __inline void +tlbsync(void) +{ + __asm __volatile ("sync; tlbsync; sync"); +} + +static __inline void +tlbia(void) +{ + vm_offset_t i; + + __asm __volatile ("sync"); + for (i = 0; i < (vm_offset_t)0x00040000; i += 0x00001000) { + tlbie(i); + } + tlbsync(); +} + +static __inline int +ptesr(sr_t *sr, vm_offset_t addr) +{ + return sr[(u_int)addr >> ADDR_SR_SHFT]; +} + +static __inline int +pteidx(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(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); +} + +static __inline struct pv_entry * +pa_to_pv(vm_offset_t pa) +{ +#if 0 /* XXX */ + int bank, pg; + + bank = vm_physseg_find(atop(pa), &pg); + if (bank == -1) + return NULL; + return &vm_physmem[bank].pmseg.pvent[pg]; +#endif + return (NULL); +} + +static __inline char * +pa_to_attr(vm_offset_t pa) +{ +#if 0 /* XXX */ + int bank, pg; + + bank = vm_physseg_find(atop(pa), &pg); + if (bank == -1) + return NULL; + return &vm_physmem[bank].pmseg.attrs[pg]; +#endif + return (NULL); +} + +/* + * 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(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; + } + } + + /* + * Then try secondary hash. + */ + + 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(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; +} + +/* + * This is called during powerpc_init, before the system is really initialized. + */ +void +pmap_bootstrap(u_int kernelstart, u_int kernelend) +{ + struct mem_region *mp, *mp1; + int cnt, i; + u_int s, e, sz; + + /* + * Get memory. + */ + mem_regions(&mem, &avail); + for (mp = mem; mp->size; mp++) + Maxmem += btoc(mp->size); + + /* + * Count the number of available entries. + */ + for (cnt = 0, mp = avail; mp->size; mp++) { + cnt++; + } + + /* + * Page align all regions. + * Non-page aligned memory isn't very interesting to us. + * Also, sort the entries for ascending addresses. + */ + kernelstart &= ~PAGE_MASK; + kernelend = (kernelend + PAGE_MASK) & ~PAGE_MASK; + for (mp = avail; mp->size; mp++) { + s = mp->start; + e = mp->start + mp->size; + /* + * Check whether this region holds all of the kernel. + */ + if (s < kernelstart && e > kernelend) { + avail[cnt].start = kernelend; + avail[cnt++].size = e - kernelend; + e = kernelstart; + } + /* + * Look whether this regions starts within the kernel. + */ + if (s >= kernelstart && s < kernelend) { + if (e <= kernelend) + goto empty; + s = kernelend; + } + /* + * Now look whether this region ends within the kernel. + */ + if (e > kernelstart && e <= kernelend) { + if (s >= kernelstart) + goto empty; + e = kernelstart; + } + /* + * Now page align the start and size of the region. + */ + s = round_page(s); + e = trunc_page(e); + if (e < s) { + e = s; + } + sz = e - s; + /* + * Check whether some memory is left here. + */ + if (sz == 0) { + empty: + bcopy(mp + 1, mp, + (cnt - (mp - avail)) * sizeof *mp); + cnt--; + mp--; + continue; + } + + /* + * Do an insertion sort. + */ + npgs += btoc(sz); + + for (mp1 = avail; mp1 < mp; mp1++) { + if (s < mp1->start) { + break; + } + } + + if (mp1 < mp) { + bcopy(mp1, mp1 + 1, (char *)mp - (char *)mp1); + mp1->start = s; + mp1->size = sz; + } else { + mp->start = s; + mp->size = sz; + } + } + +#ifdef HTABENTS + ptab_cnt = HTABENTS; +#else + ptab_cnt = (Maxmem + 1) / 2; + + /* The minimum is 1024 PTEGs. */ + if (ptab_cnt < 1024) { + ptab_cnt = 1024; + } + + /* Round up to power of 2. */ + __asm ("cntlzw %0,%1" : "=r"(i) : "r"(ptab_cnt - 1)); + ptab_cnt = 1 << (32 - i); +#endif + + /* + * Find suitably aligned memory for HTAB. + */ + for (mp = avail; mp->size; mp++) { + s = roundup(mp->start, HTABSIZE) - mp->start; + + 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 (s != 0) { + bcopy(mp, mp + 1, + (cnt - (mp - avail)) * sizeof *mp); + mp++->size = s; + cnt++; + } + + mp->start += s + HTABSIZE; + mp->size -= s + HTABSIZE; + break; + } + + if (!mp->size) { + panic("not enough memory?"); + } + + npgs -= btoc(HTABSIZE); + bzero((void *)ptable, HTABSIZE); + ptab_mask = ptab_cnt - 1; + + /* + * We cannot do pmap_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?"); + } + + npgs -= btoc(sz); + 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); + } + +#ifndef MSGBUFADDR + /* + * allow for msgbuf + */ + sz = round_page(MSGBUFSIZE); + mp = NULL; + + for (mp1 = avail; mp1->size; mp1++) { + if (mp1->size >= sz) { + mp = mp1; + } + } + + if (mp == NULL) { + panic("not enough memory?"); + } + + npgs -= btoc(sz); + msgbuf_paddr = mp->start + mp->size - sz; + mp->size -= sz; + + if (mp->size <= 0) { + bcopy(mp + 1, mp, (cnt - (mp - avail)) * sizeof *mp); + } +#endif + + /* + * Initialize kernel pmap and hardware. + */ + kernel_pmap = &kernel_pmap_store; + + { + int batu, batl; + + batu = 0x80001ffe; + batl = 0x80000012; + + __asm ("mtdbatu 1,%0; mtdbatl 1,%1" :: "r" (batu), "r" (batl)); + } + + +#if NPMAPS >= KERNEL_SEGMENT / 16 + usedsr[KERNEL_SEGMENT / 16 / (sizeof usedsr[0] * 8)] + |= 1 << ((KERNEL_SEGMENT / 16) % (sizeof usedsr[0] * 8)); +#endif + +#if 0 /* XXX */ + for (i = 0; i < 16; i++) { + kernel_pmap->pm_sr[i] = EMPTY_SEGMENT; + __asm __volatile ("mtsrin %0,%1" + :: "r"(EMPTY_SEGMENT), "r"(i << ADDR_SR_SHFT)); + } +#endif + + for (i = 0; i < 16; i++) { + int j; + + __asm __volatile ("mfsrin %0,%1" + : "=r" (j) + : "r" (i << ADDR_SR_SHFT)); + + kernel_pmap->pm_sr[i] = j; + } + + kernel_pmap->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(); + + nextavail = avail->start; + avail_start = avail->start; + for (mp = avail, i = 0; mp->size; mp++) { + avail_end = mp->start + mp->size; + phys_avail[i++] = mp->start; + phys_avail[i++] = mp->start + mp->size; + } + + virtual_avail = VM_MIN_KERNEL_ADDRESS; + virtual_end = VM_MAX_KERNEL_ADDRESS; +} + +/* + * Initialize anything else for pmap handling. + * Called during vm_init(). + */ +void +pmap_init(vm_offset_t phys_start, vm_offset_t phys_end) +{ + int initial_pvs; + + /* + * init the pv free list + */ + initial_pvs = vm_page_array_size; + if (initial_pvs < MINPV) { + initial_pvs = MINPV; + } + pvzone = &pvzone_store; + pvinit = (struct pv_entry *) kmem_alloc(kernel_map, + initial_pvs * sizeof(struct pv_entry)); + zbootinit(pvzone, "PV ENTRY", sizeof(struct pv_entry), pvinit, + vm_page_array_size); + + pmap_initialized = TRUE; +} + +/* + * Initialize a preallocated and zeroed pmap structure. + */ +void +pmap_pinit(struct pmap *pm) +{ + int i, j; + + /* + * Allocate some segment registers for this pmap. + */ + 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; + pm->pm_sr[0] = (i * sizeof usedsr[0] * 8 + j) * 16; + for (i = 1; i < 16; i++) { + pm->pm_sr[i] = pm->pm_sr[i - 1] + 1; + } + return; + } + } + panic("out of segments"); +} + +void +pmap_pinit2(pmap_t pmap) +{ + /* + * Nothing to be done. + */ + return; +} + +/* + * Add a reference to the given pmap. + */ +void +pmap_reference(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(struct pmap *pm) +{ + if (--pm->pm_refs == 0) { + pmap_release(pm); + free((caddr_t)pm, M_VMPGDATA); + } +} + +/* + * Release any resources held by the given physical map. + * Called when a pmap initialized by pmap_pinit is being released. + */ +void +pmap_release(struct pmap *pm) +{ + int i, j; + + 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; + usedsr[i] &= ~(1 << j); +} + +/* + * 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(struct pmap *dst_pmap, struct pmap *src_pmap, vm_offset_t dst_addr, + vm_size_t len, vm_offset_t src_addr) +{ + return; +} + +/* + * 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(void) +{ + return; +} + +/* + * Fill the given physical page with zeroes. + */ +void +pmap_zero_page(vm_offset_t pa) +{ +#if 0 + bzero((caddr_t)pa, PAGE_SIZE); +#else + int i; + + for (i = PAGE_SIZE/CACHELINESIZE; i > 0; i--) { + __asm __volatile ("dcbz 0,%0" :: "r"(pa)); + pa += CACHELINESIZE; + } +#endif +} + +void +pmap_zero_page_area(vm_offset_t pa, int off, int size) +{ + bzero((caddr_t)pa + off, size); +} + +/* + * Copy the given physical source page to its destination. + */ +void +pmap_copy_page(vm_offset_t src, vm_offset_t dst) +{ + bcopy((caddr_t)src, (caddr_t)dst, PAGE_SIZE); +} + +static struct pv_entry * +pmap_alloc_pv() +{ + pv_entry_count++; + + if (pv_entry_high_water && + (pv_entry_count > pv_entry_high_water) && + (pmap_pagedaemon_waken == 0)) { + pmap_pagedaemon_waken = 1; + wakeup(&vm_pages_needed); + } + + return zalloc(pvzone); +} + +static void +pmap_free_pv(struct pv_entry *pv) +{ + pv_entry_count--; + + zfree(pvzone, pv); +} + +/* + * We really hope that we don't need overflow entries + * before the VM system is initialized! + * + * XXX: Should really be switched over to the zone allocator. + */ +static struct pte_ovfl * +poalloc() +{ + struct po_page *pop; + struct pte_ovfl *po; + vm_page_t mem; + int i; + + if (!pmap_initialized) { + panic("poalloc"); + } + + if (po_nfree == 0) { + /* + * Since we cannot use maps for potable allocation, + * we have to steal some memory from the VM system. XXX + */ + mem = vm_page_alloc(NULL, 0, VM_ALLOC_SYSTEM); + po_pcnt++; + pop = (struct po_page *)VM_PAGE_TO_PHYS(mem); + pop->pop_pgi.pgi_page = mem; + LIST_INIT(&pop->pop_pgi.pgi_freelist); + for (i = NPOPPG - 1, po = pop->pop_po + 1; --i >= 0; po++) { + LIST_INSERT_HEAD(&pop->pop_pgi.pgi_freelist, po, + po_list); + } + po_nfree += pop->pop_pgi.pgi_nfree = NPOPPG - 1; + LIST_INSERT_HEAD(&po_page_freelist, pop, pop_pgi.pgi_list); + po = pop->pop_po; + } else { + po_nfree--; + pop = po_page_freelist.lh_first; + if (--pop->pop_pgi.pgi_nfree <= 0) { + LIST_REMOVE(pop, pop_pgi.pgi_list); + } + po = pop->pop_pgi.pgi_freelist.lh_first; + LIST_REMOVE(po, po_list); + } + + return po; +} + +static void +pofree(struct pte_ovfl *po, int freepage) +{ + struct po_page *pop; + + pop = (struct po_page *)trunc_page((vm_offset_t)po); + switch (++pop->pop_pgi.pgi_nfree) { + case NPOPPG: + if (!freepage) { + break; + } + po_nfree -= NPOPPG - 1; + po_pcnt--; + LIST_REMOVE(pop, pop_pgi.pgi_list); + vm_page_free(pop->pop_pgi.pgi_page); + return; + case 1: + LIST_INSERT_HEAD(&po_page_freelist, pop, pop_pgi.pgi_list); + default: + break; + } + LIST_INSERT_HEAD(&pop->pop_pgi.pgi_freelist, po, po_list); + po_nfree++; +} + +/* + * This returns whether this is the first mapping of a page. + */ +static int +pmap_enter_pv(int pteidx, vm_offset_t va, vm_offset_t pa) +{ + struct pv_entry *pv, *npv; + int s, first; + + if (!pmap_initialized) { + return 0; + } + + s = splimp(); + + pv = pa_to_pv(pa); + first = pv->pv_idx; + if (pv->pv_idx == -1) { + /* + * No entries yet, use header as the first entry. + */ + pv->pv_va = va; + pv->pv_idx = pteidx; + 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_next = pv->pv_next; + pv->pv_next = npv; + } + splx(s); + return first; +} + +static void +pmap_remove_pv(int pteidx, vm_offset_t va, vm_offset_t pa, struct pte *pte) +{ + struct pv_entry *pv, *npv; + char *attr; + + /* + * First transfer reference/change bits to cache. + */ + attr = pa_to_attr(pa); + if (attr == NULL) { + return; + } + *attr |= (pte->pte_lo & (PTE_REF | PTE_CHG)) >> ATTRSHFT; + + /* + * Remove from the PV table. + */ + pv = pa_to_pv(pa); + + /* + * 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 (pteidx == pv->pv_idx && va == pv->pv_va) { + npv = pv->pv_next; + if (npv) { + *pv = *npv; + pmap_free_pv(npv); + } else { + pv->pv_idx = -1; + } + } else { + for (; (npv = pv->pv_next); pv = npv) { + if (pteidx == npv->pv_idx && va == npv->pv_va) { + break; + } + } + if (npv) { + pv->pv_next = npv->pv_next; + pmap_free_pv(npv); + } +#ifdef DIAGNOSTIC + else { + panic("pmap_remove_pv: not on list\n"); + } +#endif + } +} + +/* + * Insert physical page at pa into the given pmap at virtual address va. + */ +void +pmap_enter(pmap_t pm, vm_offset_t va, vm_page_t pg, vm_prot_t prot, + boolean_t wired) +{ + sr_t sr; + int idx, s; + pte_t pte; + struct pte_ovfl *po; + struct mem_region *mp; + vm_offset_t pa; + + pa = VM_PAGE_TO_PHYS(pg) & ~PAGE_MASK; + + /* + * Have to remove any existing mapping first. + */ + pmap_remove(pm, va, va + PAGE_SIZE); + + /* + * Compute the HTAB index. + */ + idx = pteidx(sr = ptesr(pm->pm_sr, va), 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_initialized && (pg->flags & PG_FICTITIOUS) == 0) { + if (pmap_enter_pv(idx, va, pa)) { + /* + * Flush the real memory from the cache. + */ + __syncicache((void *)pa, PAGE_SIZE); + } + } + + s = splimp(); + pm->pm_stats.resident_count++; + /* + * 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(vm_offset_t va, vm_offset_t pa) +{ + struct vm_page pg; + + pg.phys_addr = pa; + pmap_enter(kernel_pmap, va, &pg, VM_PROT_READ|VM_PROT_WRITE, TRUE); +} + +void +pmap_kremove(vm_offset_t va) +{ + pmap_remove(kernel_pmap, va, va + PAGE_SIZE); +} + +/* + * Remove the given range of mapping entries. + */ +void +pmap_remove(struct pmap *pm, vm_offset_t va, vm_offset_t endva) +{ + int idx, i, s; + sr_t sr; + pte_t *ptp; + struct pte_ovfl *po, *npo; + + s = splimp(); + while (va < endva) { + idx = pteidx(sr = ptesr(pm->pm_sr, va), va); + for (ptp = ptable + idx * 8, i = 8; --i >= 0; ptp++) { + if (ptematch(ptp, sr, va, PTE_VALID)) { + pmap_remove_pv(idx, va, ptp->pte_lo, ptp); + ptp->pte_hi &= ~PTE_VALID; + __asm __volatile ("sync"); + tlbie(va); + tlbsync(); + pm->pm_stats.resident_count--; + } + } + for (ptp = ptable + (idx ^ ptab_mask) * 8, i = 8; --i >= 0; + ptp++) { + if (ptematch(ptp, sr, va, PTE_VALID | PTE_HID)) { + pmap_remove_pv(idx, va, ptp->pte_lo, ptp); + ptp->pte_hi &= ~PTE_VALID; + __asm __volatile ("sync"); + tlbie(va); + tlbsync(); + pm->pm_stats.resident_count--; + } + } + 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(idx, va, po->po_pte.pte_lo, + &po->po_pte); + LIST_REMOVE(po, po_list); + pofree(po, 1); + pm->pm_stats.resident_count--; + } + } + va += PAGE_SIZE; + } + splx(s); +} + +static pte_t * +pte_find(struct pmap *pm, vm_offset_t va) +{ + int idx, i; + sr_t sr; + pte_t *ptp; + struct pte_ovfl *po; + + idx = pteidx(sr = ptesr(pm->pm_sr, va), 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. + */ +vm_offset_t +pmap_extract(pmap_t pm, vm_offset_t va) +{ + pte_t *ptp; + int s; + + s = splimp(); + + if (!(ptp = pte_find(pm, va))) { + splx(s); + return (0); + } + splx(s); + return ((ptp->pte_lo & PTE_RPGN) | (va & ADDR_POFF)); +} + +/* + * 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(struct pmap *pm, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot) +{ + pte_t *ptp; + int valid, s; + + if (prot & VM_PROT_READ) { + s = splimp(); + while (sva < eva) { + ptp = pte_find(pm, sva); + if (ptp) { + 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 += PAGE_SIZE; + } + splx(s); + return; + } + pmap_remove(pm, sva, eva); +} + +boolean_t +ptemodify(vm_page_t pg, u_int mask, u_int val) +{ + vm_offset_t pa; + struct pv_entry *pv; + pte_t *ptp; + struct pte_ovfl *po; + int i, s; + char *attr; + int rv; + + pa = VM_PAGE_TO_PHYS(pg); + + /* + * First modify bits in cache. + */ + attr = pa_to_attr(pa); + if (attr == NULL) { + return FALSE; + } + + *attr &= ~mask >> ATTRSHFT; + *attr |= val >> ATTRSHFT; + + pv = pa_to_pv(pa); + if (pv->pv_idx < 0) { + return FALSE; + } + + rv = FALSE; + 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(); + rv |= ptp->pte_lo & mask; + 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(); + rv |= ptp->pte_lo & mask; + 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) { + rv |= ptp->pte_lo & mask; + po->po_pte.pte_lo &= ~mask; + po->po_pte.pte_lo |= val; + } + } + } + splx(s); + return rv != 0; +} + +int +ptebits(vm_page_t pg, int bit) +{ + struct pv_entry *pv; + pte_t *ptp; + struct pte_ovfl *po; + int i, s, bits; + char *attr; + vm_offset_t pa; + + bits = 0; + pa = VM_PAGE_TO_PHYS(pg); + + /* + * First try the cache. + */ + attr = pa_to_attr(pa); + if (attr == NULL) { + return 0; + } + bits |= (*attr << ATTRSHFT) & bit; + if (bits == bit) { + return bits; + } + + pv = pa_to_pv(pa); + 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. + */ +void +pmap_page_protect(vm_page_t m, vm_prot_t prot) +{ + vm_offset_t pa; + vm_offset_t va; + pte_t *ptp; + struct pte_ovfl *po, *npo; + int i, s, idx; + struct pv_entry *pv; + + pa = VM_PAGE_TO_PHYS(m); + + pa &= ~ADDR_POFF; + if (prot & VM_PROT_READ) { + ptemodify(m, PTE_PP, PTE_RO); + return; + } + + pv = pa_to_pv(pa); + if (pv == NULL) { + return; + } + + s = splimp(); + while (pv->pv_idx >= 0) { + idx = pv->pv_idx; + va = pv->pv_va; + for (ptp = ptable + idx * 8, i = 8; --i >= 0; ptp++) { + if ((ptp->pte_hi & PTE_VALID) + && (ptp->pte_lo & PTE_RPGN) == pa) { + pmap_remove_pv(idx, va, pa, ptp); + ptp->pte_hi &= ~PTE_VALID; + __asm __volatile ("sync"); + tlbie(va); + tlbsync(); + goto next; + } + } + for (ptp = ptable + (idx ^ ptab_mask) * 8, i = 8; --i >= 0; + ptp++) { + if ((ptp->pte_hi & PTE_VALID) + && (ptp->pte_lo & PTE_RPGN) == pa) { + pmap_remove_pv(idx, va, pa, ptp); + ptp->pte_hi &= ~PTE_VALID; + __asm __volatile ("sync"); + tlbie(va); + tlbsync(); + goto next; + } + } + for (po = potable[idx].lh_first; po; po = npo) { + npo = po->po_list.le_next; + if ((po->po_pte.pte_lo & PTE_RPGN) == pa) { + pmap_remove_pv(idx, va, pa, &po->po_pte); + LIST_REMOVE(po, po_list); + pofree(po, 1); + goto next; + } + } +next: + } + splx(s); +} + +/* + * Activate the address space for the specified process. If the process + * is the current process, load the new MMU context. + */ +void +pmap_activate(struct proc *p) +{ + struct pcb *pcb; + pmap_t pmap; + pmap_t rpm; + int psl, i, ksr, seg; + + pcb = &p->p_addr->u_pcb; + pmap = p->p_vmspace->vm_map.pmap; + + /* + * XXX Normally performed in cpu_fork(). + */ + if (pcb->pcb_pm != pmap) { + pcb->pcb_pm = pmap; + (vm_offset_t) pcb->pcb_pmreal = pmap_extract(kernel_pmap, + (vm_offset_t)pcb->pcb_pm); + } + + if (p == curproc) { + /* Disable interrupts while switching. */ + __asm __volatile("mfmsr %0" : "=r"(psl) :); + psl &= ~PSL_EE; + __asm __volatile("mtmsr %0" :: "r"(psl)); + +#if 0 /* XXX */ + /* Store pointer to new current pmap. */ + curpm = pcb->pcb_pmreal; +#endif + + /* 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)); + } +} + +/* + * Add a list of wired pages to the kva + * this routine is only used for temporary + * kernel mappings that do not need to have + * page modification or references recorded. + * Note that old mappings are simply written + * over. The page *must* be wired. + */ +void +pmap_qenter(vm_offset_t va, vm_page_t *m, int count) +{ + int i; + + for (i = 0; i < count; i++) { + vm_offset_t tva = va + i * PAGE_SIZE; + pmap_kenter(tva, VM_PAGE_TO_PHYS(m[i])); + } +} + +/* + * this routine jerks page mappings from the + * kernel -- it is meant only for temporary mappings. + */ +void +pmap_qremove(vm_offset_t va, int count) +{ + vm_offset_t end_va; + + end_va = va + count*PAGE_SIZE; + + while (va < end_va) { + unsigned *pte; + + pte = (unsigned *)vtopte(va); + *pte = 0; + tlbie(va); + va += PAGE_SIZE; + } +} + +/* + * pmap_ts_referenced: + * + * Return the count of reference bits for a page, clearing all of them. + */ +int +pmap_ts_referenced(vm_page_t m) +{ + /* XXX: coming soon... */ + return (0); +} + +/* + * this routine returns true if a physical page resides + * in the given pmap. + */ +boolean_t +pmap_page_exists(pmap_t pmap, vm_page_t m) +{ +#if 0 /* XXX: This must go! */ + register pv_entry_t pv; + int s; + + if (!pmap_initialized || (m->flags & PG_FICTITIOUS)) + return FALSE; + + s = splvm(); + + /* + * Not found, check current mappings returning immediately if found. + */ + for (pv = pv_table; pv; pv = pv->pv_next) { + if (pv->pv_pmap == pmap) { + splx(s); + return TRUE; + } + } + splx(s); +#endif + return (FALSE); +} + +/* + * Used to map a range of physical addresses into kernel + * virtual address space. + * + * For now, VM is already on, we only need to map the + * specified memory. + */ +vm_offset_t +pmap_map(vm_offset_t *virt, vm_offset_t start, vm_offset_t end, int prot) +{ + vm_offset_t sva, va; + + sva = *virt; + va = sva; + + while (start < end) { + pmap_kenter(va, start); + va += PAGE_SIZE; + start += PAGE_SIZE; + } + + *virt = va; + return (sva); +} + +vm_offset_t +pmap_addr_hint(vm_object_t obj, vm_offset_t addr, vm_size_t size) +{ + return (addr); +} + +int +pmap_mincore(pmap_t pmap, vm_offset_t addr) +{ + /* XXX: coming soon... */ + return (0); +} + +void +pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_object_t object, + vm_pindex_t pindex, vm_size_t size, int limit) +{ + /* XXX: coming soon... */ + return; +} + +void +pmap_growkernel(vm_offset_t addr) +{ + /* XXX: coming soon... */ + return; +} + +/* + * Initialize the address space (zone) for the pv_entries. Set a + * high water mark so that the system can recover from excessive + * numbers of pv entries. + */ +void +pmap_init2() +{ + pv_entry_max = PMAP_SHPGPERPROC * maxproc + vm_page_array_size; + pv_entry_high_water = 9 * (pv_entry_max / 10); + zinitna(pvzone, &pvzone_obj, NULL, 0, pv_entry_max, ZONE_INTERRUPT, 1); +} + +void +pmap_swapin_proc(struct proc *p) +{ + /* XXX: coming soon... */ + return; +} + +void +pmap_swapout_proc(struct proc *p) +{ + /* XXX: coming soon... */ + return; +} + +void +pmap_new_proc(struct proc *p) +{ + /* XXX: coming soon... */ + return; +} + +void +pmap_pageable(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, boolean_t pageable) +{ + return; +} + +void +pmap_change_wiring(pmap_t pmap, vm_offset_t va, boolean_t wired) +{ + /* XXX: coming soon... */ + return; +} + +void +pmap_prefault(pmap_t pmap, vm_offset_t addra, vm_map_entry_t entry) +{ + /* XXX: coming soon... */ + return; +} + +void +pmap_remove_pages(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) +{ + /* XXX: coming soon... */ + return; +} + +void +pmap_pinit0(pmap_t pmap) +{ + /* XXX: coming soon... */ + return; +} + +void +pmap_dispose_proc(struct proc *p) +{ + /* XXX: coming soon... */ + return; +} + +vm_offset_t +pmap_steal_memory(vm_size_t size) +{ + vm_size_t bank_size; + vm_offset_t pa; + + size = round_page(size); + + bank_size = phys_avail[1] - phys_avail[0]; + while (size > bank_size) { + int i; + for (i = 0; phys_avail[i+2]; i+= 2) { + phys_avail[i] = phys_avail[i+2]; + phys_avail[i+1] = phys_avail[i+3]; + } + phys_avail[i] = 0; + phys_avail[i+1] = 0; + if (!phys_avail[0]) + panic("pmap_steal_memory: out of memory"); + bank_size = phys_avail[1] - phys_avail[0]; + } + + pa = phys_avail[0]; + phys_avail[0] += size; + + bzero((caddr_t) pa, size); + return pa; +} Index: powerpc/powerpc/procfs_machdep.c =================================================================== RCS file: procfs_machdep.c diff -N procfs_machdep.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ procfs_machdep.c Tue Jun 5 21:12:55 2001 @@ -0,0 +1,149 @@ +/* + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * Copyright (c) 1993 Jan-Simon Pendry + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry. + * + * 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. + * + * @(#)procfs_machdep.c 8.3 (Berkeley) 1/27/94 + * + * From: + * $FreeBSD: src/sys/alpha/alpha/procfs_machdep.c,v 1.4 1999/08/28 00:38:30 peter Exp $ + */ + +/* + * Functions to be implemented here are: + * + * procfs_read_regs(proc, regs) + * Get the current user-visible register set from the process + * and copy it into the regs structure (). + * The process is stopped at the time read_regs is called. + * + * procfs_write_regs(proc, regs) + * Update the current register set from the passed in regs + * structure. Take care to avoid clobbering special CPU + * registers or privileged bits in the PSL. + * Depending on the architecture this may have fix-up work to do, + * especially if the IAR or PCW are modified. + * The process is stopped at the time write_regs is called. + * + * procfs_read_fpregs, procfs_write_fpregs + * deal with the floating point register set, otherwise as above. + * + * procfs_sstep(proc) + * Arrange for the process to trap after executing a single instruction. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + +int +procfs_read_regs(struct proc *p, struct reg *regs) +{ + if ((p->p_flag & PS_INMEM) == 0) { + return (EIO); + } + + return (fill_regs(p, regs)); +} + +int +procfs_write_regs(struct proc *p, struct reg *regs) +{ + if ((p->p_flag & PS_INMEM) == 0) { + return (EIO); + } + + return (set_regs(p, regs)); +} + +/* + * Ptrace doesn't support fpregs at all, and there are no security holes + * or translations for fpregs, so we can just copy them. + */ + +int +procfs_read_fpregs(struct proc *p, struct fpreg *fpregs) +{ + if ((p->p_flag & PS_INMEM) == 0) { + return (EIO); + } + + return (fill_fpregs(p, fpregs)); +} + +int +procfs_write_fpregs(struct proc *p, struct fpreg *fpregs) +{ + if ((p->p_flag & PS_INMEM) == 0) { + return (EIO); + } + + return (set_fpregs(p, fpregs)); +} + +int +procfs_sstep(struct proc *p) +{ + return (EINVAL); +} + +/* + * Placeholders + */ +int +procfs_read_dbregs(struct proc *p, struct dbreg *dbregs) +{ + return (EIO); +} + +int +procfs_write_dbregs(struct proc *p, struct dbreg *dbregs) +{ + return (EIO); +} Index: powerpc/powerpc/subyte.c =================================================================== RCS file: subyte.c diff -N subyte.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ subyte.c Tue Jun 5 21:41:30 2001 @@ -0,0 +1,55 @@ +/* $NetBSD: subyte.c,v 1.2 2000/06/09 14:05:47 kleink Exp $ */ +/* $FreeBSD$ */ + +/*- + * Copyright (C) 1993 Wolfgang Solfrank. + * Copyright (C) 1993 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 + +/* + * Emulate subyte. + */ + +int +subyte(void *base, int byte) +{ + if (copyout(&byte, base, 1)) { + return -1; + } + + return 0; +} + +int +suibyte(void *base, int byte) +{ + return subyte(base, byte); +} Index: powerpc/powerpc/suswintr.c =================================================================== RCS file: suswintr.c diff -N suswintr.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ suswintr.c Tue Jun 5 19:20:13 2001 @@ -0,0 +1,47 @@ +/* $NetBSD: suswintr.c,v 1.2 2000/06/09 14:05:48 kleink Exp $ */ +/* $FreeBSD$ */ + +/*- + * Copyright (C) 1994 Wolfgang Solfrank. + * Copyright (C) 1994 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 +#include + +/* + * Emulate suswintr + * + * Simply return fault for all cases + */ +int +suswintr(void *addr, int s) +{ + return -1; +} Index: powerpc/powerpc/suword.c =================================================================== RCS file: suword.c diff -N suword.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ suword.c Tue Jun 5 19:21:19 2001 @@ -0,0 +1,48 @@ +/* $NetBSD: suword.c,v 1.2 2000/06/09 14:05:49 kleink Exp $ */ +/* $FreeBSD$ */ + +/*- + * Copyright (C) 1993 Wolfgang Solfrank. + * Copyright (C) 1993 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 + +/* + * Emulate suword + */ +int +suword(void *addr, long l) +{ + if (copyout(&l, addr, sizeof(l))) { + return -1; + } + + return 0; +} Index: powerpc/powerpc/swtch.s =================================================================== RCS file: swtch.s diff -N swtch.s --- /dev/null Tue Jun 5 21:44:00 2001 +++ swtch.s Tue Jun 5 21:38:46 2001 @@ -0,0 +1,249 @@ +/* $FreeBSD$ */ +/* $NetBSD: locore.S,v 1.24 2000/05/31 05:09:17 thorpej Exp $ */ + +/* + * Copyright (C) 2001 Benno Rice + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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. +*/ +/* + * 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 "assym.s" + +#include + +#include +#include +#include +#include +#include + +/* + * Some instructions gas doesn't understand (yet?) + */ +#define bdneq bdnzf 2, + +/* + * No processes are runnable, so loop waiting for one. + * Separate label here for accounting purposes. + */ +#if 0 /* XXX: I think this is now unneeded. Leaving it in just in case. */ +ASENTRY(Idle) + mfmsr 3 + andi. 3,3,~PSL_EE@l /* disable interrupts while + manipulating runque */ + mtmsr 3 + + lis 8,sched_whichqs@ha + lwz 9,sched_whichqs@l(8) + + or. 9,9,9 + bne- .Lsw1 /* at least one queue non-empty */ + + ori 3,3,PSL_EE@l /* reenable ints again */ + mtmsr 3 + isync + +/* Check if we can use power saving mode */ + lis 8,powersave@ha + lwz 9,powersave@l(8) + + or. 9,9,9 + beq 1f + + sync + oris 3,3,PSL_POW@h /* enter power saving mode */ + mtmsr 3 + isync +1: + b _ASM_LABEL(Idle) +#endif /* XXX */ + +/* + * switchexit gets called from cpu_exit to complete the exit procedure. + */ +ENTRY(switchexit) +/* First switch to the idle pcb/kernel stack */ +#if 0 /* XXX */ + lis 6,idle_u@ha + lwz 6,idle_u@l(6) + mfsprg 7,0 + stw 6,GD_CURPCB(7) +#endif + 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 sys_exit + +/* Fall through to cpu_switch to actually select another proc */ + li 3,0 /* indicate exited process */ + +/* + * void cpu_switch(struct proc *p) + * Find a runnable process and switch to it. + */ +/* XXX noprofile? --thorpej@netbsd.org */ +ENTRY(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 + mfsprg 3,0 + xor 31,31,31 + stw 31,GD_CURPROC(3) /* Zero to not accumulate cpu time */ + mfsprg 3,0 + lwz 31,GD_CURPCB(3) + + xor 3,3,3 +#if 0 /* XXX */ + bl lcsplx +#endif + stw 3,PCB_SPL(31) /* save spl */ + +/* Find a new process */ + bl chooseproc + +1: + /* just did this resched thing */ + xor 3,3,3 + lis 4,want_resched@ha + stw 3,want_resched@l(4) + + /* record new process */ + mfsprg 4,0 + stw 3,GD_CURPROC(4) + + 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 + + /* indicate new pcb */ + lwz 4,P_ADDR(31) + mfsprg 5,0 + stw 4,GD_CURPCB(5) + +#if 0 /* XXX */ + /* save real pmap pointer for spill fill */ + lwz 5,PCB_PMR(4) + lis 6,curpm@ha + stwu 5,curpm@l(6) + stwcx. 5,0,6 /* clear possible reservation */ +#endif + + 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@l /* 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) +#if 0 /* XXX */ + bl lcsplx +#endif + + 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 + +/* + * Fake savectx for the time being. + */ +ENTRY(savectx) + blr Index: powerpc/powerpc/syncicache.c =================================================================== RCS file: syncicache.c diff -N syncicache.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ syncicache.c Tue Jun 5 19:22:52 2001 @@ -0,0 +1,94 @@ +/* $NetBSD: syncicache.c,v 1.2 1999/05/05 12:36:40 tsubai Exp $ */ +/* $FreeBSD$ */ + +/* + * Copyright (C) 1995-1997, 1999 Wolfgang Solfrank. + * Copyright (C) 1995-1997, 1999 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 +#if defined(_KERNEL) || defined(_STANDALONE) +#include +#include +#include +#endif +#include + +#include + +#if defined(_KERNEL) || defined(_STANDALONE) +#ifndef CACHELINESIZE +#error "Must know the size of a cache line" +#endif +#else +static void getcachelinesize __P((void)); + +static int _cachelinesize; +#define CACHELINESIZE _cachelinesize + +static void +getcachelinesize() +{ + static int cachemib[] = { CTL_MACHDEP, CPU_CACHELINE }; + int clen; + + clen = sizeof(_cachelinesize); + + if (sysctl(cachemib, sizeof(cachemib) / sizeof(cachemib[0]), + &_cachelinesize, &clen, NULL, 0) < 0 + || !_cachelinesize) { + abort(); + } +} +#endif + +void +__syncicache(void *from, int len) +{ + int l, off; + char *p; + +#if !defined(_KERNEL) && !defined(_STANDALONE) + if (!_cachelinesize) + getcachelinesize(); +#endif + off = (u_int)from & (CACHELINESIZE - 1); + l = len += off; + p = (char *)from - off; + do { + __asm __volatile ("dcbst 0,%0" :: "r"(p)); + p += CACHELINESIZE; + } while ((l -= CACHELINESIZE) > 0); + __asm __volatile ("sync"); + p = (char *)from - off; + do { + __asm __volatile ("icbi 0,%0" :: "r"(p)); + p += CACHELINESIZE; + } while ((len -= CACHELINESIZE) > 0); + __asm __volatile ("isync"); +} Index: powerpc/powerpc/sys_machdep.c =================================================================== RCS file: sys_machdep.c diff -N sys_machdep.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ sys_machdep.c Tue Jun 5 21:43:47 2001 @@ -0,0 +1,37 @@ +/* $FreeBSD$ */ + +/* + * Copyright (C) 2001 Benno Rice. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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 +#include +#include +#include + +int +sysarch(struct proc *p, struct sysarch_args *uap) +{ + return (EOPNOTSUPP); +} Index: powerpc/powerpc/trap.c =================================================================== RCS file: trap.c diff -N trap.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ trap.c Tue Jun 5 19:23:21 2001 @@ -0,0 +1,586 @@ +/* $NetBSD: trap.c,v 1.26 2000/05/27 00:40:40 sommerfeld Exp $ */ +/* $FreeBSD$ */ + +/* + * 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 "opt_ddb.h" +#include "opt_ktrace.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +/* 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 astpending; +volatile int want_resched; + +#if 0 /* XXX: not used yet */ +static int fix_unaligned __P((struct proc *p, struct trapframe *frame)); +#endif + +void +trap(struct trapframe *frame) +{ +#if 0 /* XXX: This code hasn't been reworked yet. */ + struct proc *p = curproc; + int type = frame->exc; + u_quad_t sticks; + + if (frame->srr1 & PSL_PR) { + type |= EXC_USER; + sticks = p->p_sticks; + } + + switch (type) { + case EXC_TRC|EXC_USER: + frame->srr1 &= ~PSL_SE; + trapsignal(p, SIGTRAP, EXC_TRC); + break; + case EXC_DSI: + { + vm_map_t map; + vaddr_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; + if (uvm_fault(map, trunc_page(va), 0, ftype) + == KERN_SUCCESS) + return; + if (fb = p->p_addr->u_pcb.pcb_onfault) { + frame->srr0 = (*fb)[0]; + frame->fixreg[1] = (*fb)[1]; + frame->fixreg[2] = (*fb)[2]; + frame->cr = (*fb)[3]; + bcopy(&(*fb)[4], &frame->fixreg[13], + 19 * sizeof(register_t)); + return; + } + map = kernel_map; + } + goto brain_damage; + case EXC_DSI|EXC_USER: + { + int ftype, rv; + + if (frame->dsisr & DSISR_STORE) + ftype = VM_PROT_READ | VM_PROT_WRITE; + else + ftype = VM_PROT_READ; + if ((rv = uvm_fault(&p->p_vmspace->vm_map, + trunc_page(frame->dar), 0, ftype)) + == KERN_SUCCESS) + break; + if (rv == KERN_RESOURCE_SHORTAGE) { + printf("UVM: pid %d (%s), uid %d killed: " + "out of swap\n", + p->p_pid, p->p_comm, + p->p_cred && p->p_ucred ? + p->p_ucred->cr_uid : -1); + trapsignal(p, SIGKILL, EXC_DSI); + } else { + trapsignal(p, SIGSEGV, EXC_DSI); + } + } + break; + case EXC_ISI|EXC_USER: + { + int ftype; + + ftype = VM_PROT_READ | VM_PROT_EXECUTE; + if (uvm_fault(&p->p_vmspace->vm_map, + trunc_page(frame->srr0), 0, ftype) + == KERN_SUCCESS) + break; + } + trapsignal(p, SIGSEGV, EXC_ISI); + 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]; + + uvmexp.syscalls++; + + 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]; + + switch (error = (*callp->sy_call)(p, params, rval)) { + case 0: + 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[FIRSTARG] = error; + frame->cr |= 0x10000000; + break; + } +#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_AST|EXC_USER: + /* This is just here that we trap */ + break; + + case EXC_ALI|EXC_USER: + if (fix_unaligned(p, frame) != 0) + trapsignal(p, SIGBUS, EXC_ALI); + else + frame->srr0 += 4; + break; + + case EXC_PGM|EXC_USER: +/* XXX temporarily */ + if (frame->srr1 & 0x0002000) + trapsignal(p, SIGTRAP, EXC_PGM); + else + trapsignal(p, SIGILL, EXC_PGM); + break; + + case EXC_MCHK: + { + faultbuf *fb; + + if (fb = p->p_addr->u_pcb.pcb_onfault) { + frame->srr0 = (*fb)[0]; + frame->fixreg[1] = (*fb)[1]; + frame->fixreg[2] = (*fb)[2]; + frame->cr = (*fb)[3]; + bcopy(&(*fb)[4], &frame->fixreg[13], + 19 * sizeof(register_t)); + return; + } + } + goto brain_damage; + + default: +brain_damage: + printf("trap type %x at %x\n", type, frame->srr0); +#ifdef DDB + Debugger(); /* XXX temporarily */ +#endif +#ifdef TRAP_PANICWAIT + printf("Press a key to panic.\n"); + cngetc(); +#endif + panic("trap"); + } + + astpending = 0; /* we are about to do it */ + + uvmexp.softs++; + + 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 sig; + /* + * We are being preempted. + */ + preempt(NULL); + 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; + curcpu()->ci_schedstate.spc_curpriority = p->p_priority; +#endif +} + +#if 0 /* XXX: child_return not used */ +void +child_return(void *arg) +{ + struct proc *p = arg; + struct trapframe *tf = trapframe(p); + + 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 */ + curcpu()->ci_schedstate.spc_curpriority = p->p_priority; +} +#endif + +static __inline void +setusr(int content) +{ + __asm __volatile ("isync; mtsr %0,%1; isync" + :: "n"(USER_SR), "r"(content)); +} + +int +copyin(udaddr, kaddr, len) + const void *udaddr; + void *kaddr; + size_t len; +{ + const char *up = udaddr; + char *kp = kaddr; + char *p; + size_t l; + faultbuf env; + +#if 0 + if (setfault(env)) { + curpcb->pcb_onfault = 0; + return EFAULT; + } +#endif + while (len > 0) { + p = (char *)USER_ADDR + ((u_int)up & ~SEGMENT_MASK); + l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p; + if (l > len) + l = len; + setusr(curpcb->pcb_pm->pm_sr[(u_int)up >> ADDR_SR_SHFT]); + bcopy(p, kp, l); + up += l; + kp += l; + len -= l; + } + curpcb->pcb_onfault = 0; + return 0; +} + +int +copyout(kaddr, udaddr, len) + const void *kaddr; + void *udaddr; + size_t len; +{ + const char *kp = kaddr; + char *up = udaddr; + char *p; + size_t l; + faultbuf env; + +#if 0 + if (setfault(env)) { + curpcb->pcb_onfault = 0; + return EFAULT; + } +#endif + while (len > 0) { + p = (char *)USER_ADDR + ((u_int)up & ~SEGMENT_MASK); + l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p; + if (l > len) + l = len; + setusr(curpcb->pcb_pm->pm_sr[(u_int)up >> ADDR_SR_SHFT]); + bcopy(kp, p, l); + up += l; + kp += l; + len -= l; + } + curpcb->pcb_onfault = 0; + return 0; +} + +#if 0 /* XXX: not used yet */ +/* + * kcopy(const void *src, void *dst, size_t len); + * + * Copy len bytes from src to dst, aborting if we encounter a fatal + * page fault. + * + * kcopy() _must_ save and restore the old fault handler since it is + * called by uiomove(), which may be in the path of servicing a non-fatal + * page fault. + */ +int +kcopy(const void *src, void *dst, size_t len) +{ + faultbuf env, *oldfault; + + oldfault = curpcb->pcb_onfault; + if (setfault(env)) { + curpcb->pcb_onfault = oldfault; + return EFAULT; + } + + bcopy(src, dst, len); + + curpcb->pcb_onfault = oldfault; + return 0; +} + +int +badaddr(void *addr, size_t size) +{ + return badaddr_read(addr, size, NULL); +} + +int +badaddr_read(void *addr, size_t size, int *rptr) +{ + faultbuf env; + int x; + + /* Get rid of any stale machine checks that have been waiting. */ + __asm __volatile ("sync; isync"); + + if (setfault(env)) { + curpcb->pcb_onfault = 0; + __asm __volatile ("sync"); + return 1; + } + + __asm __volatile ("sync"); + + switch (size) { + case 1: + x = *(volatile int8_t *)addr; + break; + case 2: + x = *(volatile int16_t *)addr; + break; + case 4: + x = *(volatile int32_t *)addr; + break; + default: + panic("badaddr: invalid size (%d)", size); + } + + /* Make sure we took the machine check, if we caused one. */ + __asm __volatile ("sync; isync"); + + curpcb->pcb_onfault = 0; + __asm __volatile ("sync"); /* To be sure. */ + + /* Use the value to avoid reorder. */ + if (rptr) + *rptr = x; + + return 0; +} +#endif + +/* + * 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. + */ + +#if 0 /* XXX: Not used yet */ +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; +} +#endif + +void +userret(struct proc *p, struct trapframe *frame, u_quad_t oticks) +{ + /* XXX: Coming soon */ + return; +} Index: powerpc/powerpc/vm_machdep.c =================================================================== RCS file: vm_machdep.c diff -N vm_machdep.c --- /dev/null Tue Jun 5 21:44:00 2001 +++ vm_machdep.c Tue Jun 5 21:03:28 2001 @@ -0,0 +1,396 @@ +/*- + * Copyright (c) 1982, 1986 The Regents of the University of California. + * Copyright (c) 1989, 1990 William Jolitz + * Copyright (c) 1994 John Dyson + * 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 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. + * + * from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91 + * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$ + * $FreeBSD: src/sys/alpha/alpha/vm_machdep.c,v 1.40 2000/12/23 19:42:47 jake Exp $ + */ +/* + * Copyright (c) 1994, 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * quick version of vm_fault + */ +int +vm_fault_quick(caddr_t v, int prot) +{ + int r; + + if (prot & VM_PROT_WRITE) { + r = subyte(v, fubyte(v)); + } else { + r = fubyte(v); + } + + return(r); +} + +/* + * Finish a fork operation, with process p2 nearly set up. + * Copy and update the pcb, set up the stack so that the child + * ready to run and return to user mode. + */ +void +cpu_fork(struct proc *p1, struct proc *p2, int flags) +{ + /* XXX: coming soon... */ +} + +/* + * Intercept the return address from a freshly forked process that has NOT + * been scheduled yet. + * + * This is needed to make kernel threads stay in kernel mode. + */ +void +cpu_set_fork_handler(struct proc *p, void (*func)(void *), void *arg) +{ + /* + * Note that the trap frame follows the args, so the function + * is really called like this: func(arg, frame); + */ +#if 0 /* XXX */ + p->p_addr->u_pcb.pcb_context[0] = (u_long) func; + p->p_addr->u_pcb.pcb_context[2] = (u_long) arg; +#endif +} + +/* + * cpu_exit is called as the last action during exit. + * We release the address space of the process, block interrupts, + * and call switch_exit. switch_exit switches to proc0's PCB and stack, + * then jumps into the middle of cpu_switch, as if it were switching + * from proc0. + */ +void +cpu_exit(struct proc *p) +{ + mtx_lock_spin(&sched_lock); + mtx_unlock_flags(&Giant, MTX_NOSWITCH); + mtx_assert(&Giant, MA_NOTOWNED); + + /* + * We have to wait until after releasing all locks before + * changing p_stat. If we block on a mutex then we will be + * back at SRUN when we resume and our parent will never + * harvest us. + */ + p->p_stat = SZOMB; + + mp_fixme("assumption: p_pptr won't change at this time"); + wakeup(p->p_pptr); + + cnt.v_swtch++; + cpu_switch(); + panic("cpu_exit"); +} + +void +cpu_wait(struct proc *p) +{ + /* drop per-process resources */ + pmap_dispose_proc(p); + + /* and clean-out the vmspace */ + vmspace_free(p->p_vmspace); +} + +/* + * Dump the machine specific header information at the start of a core dump. + */ +int +cpu_coredump(struct proc *p, struct vnode *vp, struct ucred *cred) +{ + return (vn_rdwr(UIO_WRITE, vp, (caddr_t) p->p_addr, ctob(UPAGES), + (off_t)0, UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, (int *)NULL, + p)); +} + +#ifdef notyet +static void +setredzone(pte, vaddr) + u_short *pte; + caddr_t vaddr; +{ +/* eventually do this by setting up an expand-down stack segment + for ss0: selector, allowing stack access down to top of u. + this means though that protection violations need to be handled + thru a double fault exception that must do an integral task + switch to a known good context, within which a dump can be + taken. a sensible scheme might be to save the initial context + used by sched (that has physical memory mapped 1:1 at bottom) + and take the dump while still in mapped mode */ +} +#endif + +/* + * Map an IO request into kernel virtual address space. + * + * All requests are (re)mapped into kernel VA space. + * Notice that we use b_bufsize for the size of the buffer + * to be mapped. b_bcount might be modified by the driver. + */ +void +vmapbuf(struct buf *bp) +{ + register caddr_t addr, v, kva; + vm_offset_t pa; + + if ((bp->b_flags & B_PHYS) == 0) + panic("vmapbuf"); + + for (v = bp->b_saveaddr, addr = (caddr_t)trunc_page(bp->b_data); + addr < bp->b_data + bp->b_bufsize; + addr += PAGE_SIZE, v += PAGE_SIZE) { + /* + * Do the vm_fault if needed; do the copy-on-write thing + * when reading stuff off device into memory. + */ + vm_fault_quick(addr, + (bp->b_iocmd == BIO_READ)?(VM_PROT_READ|VM_PROT_WRITE):VM_PROT_READ); + pa = trunc_page(pmap_kextract((vm_offset_t) addr)); + if (pa == 0) + panic("vmapbuf: page not present"); + vm_page_hold(PHYS_TO_VM_PAGE(pa)); + pmap_kenter((vm_offset_t) v, pa); + } + + kva = bp->b_saveaddr; + bp->b_saveaddr = bp->b_data; + bp->b_data = kva + (((vm_offset_t) bp->b_data) & PAGE_MASK); +} + +/* + * Free the io map PTEs associated with this IO operation. + * We also invalidate the TLB entries and restore the original b_addr. + */ +void +vunmapbuf(struct buf *bp) +{ + caddr_t addr; + vm_offset_t pa; + + if ((bp->b_flags & B_PHYS) == 0) + panic("vunmapbuf"); + + for (addr = (caddr_t)trunc_page(bp->b_data); + addr < bp->b_data + bp->b_bufsize; + addr += PAGE_SIZE) { + pa = trunc_page(pmap_kextract((vm_offset_t) addr)); + pmap_kremove((vm_offset_t) addr); + vm_page_unhold(PHYS_TO_VM_PAGE(pa)); + } + + bp->b_data = bp->b_saveaddr; +} + +/* + * Reset back to firmware. + */ +void +cpu_reset() +{ + OF_exit(); +} + +int +grow_stack(struct proc *p, size_t sp) +{ + int rv; + + rv = vm_map_growstack (p, sp); + if (rv != KERN_SUCCESS) + return (0); + + return (1); +} + + +static int cnt_prezero; + +SYSCTL_INT(_machdep, OID_AUTO, cnt_prezero, CTLFLAG_RD, &cnt_prezero, 0, ""); + +/* + * Implement the pre-zeroed page mechanism. + * This routine is called from the idle loop. + */ + +#define ZIDLE_LO(v) ((v) * 2 / 3) +#define ZIDLE_HI(v) ((v) * 4 / 5) + +int +vm_page_zero_idle() +{ + static int free_rover; + static int zero_state; + vm_page_t m; + int s; + + /* + * Attempt to maintain approximately 1/2 of our free pages in a + * PG_ZERO'd state. Add some hysteresis to (attempt to) avoid + * generally zeroing a page when the system is near steady-state. + * Otherwise we might get 'flutter' during disk I/O / IPC or + * fast sleeps. We also do not want to be continuously zeroing + * pages because doing so may flush our L1 and L2 caches too much. + */ + + if (zero_state && vm_page_zero_count >= ZIDLE_LO(cnt.v_free_count)) + return(0); + if (vm_page_zero_count >= ZIDLE_HI(cnt.v_free_count)) + return(0); + + if (mtx_trylock(&Giant)) { + s = splvm(); + m = vm_page_list_find(PQ_FREE, free_rover, FALSE); + zero_state = 0; + if (m != NULL && (m->flags & PG_ZERO) == 0) { + vm_page_queues[m->queue].lcnt--; + TAILQ_REMOVE(&vm_page_queues[m->queue].pl, m, pageq); + m->queue = PQ_NONE; + splx(s); +#if 0 + rel_mplock(); +#endif + pmap_zero_page(VM_PAGE_TO_PHYS(m)); +#if 0 + get_mplock(); +#endif + (void)splvm(); + vm_page_flag_set(m, PG_ZERO); + m->queue = PQ_FREE + m->pc; + vm_page_queues[m->queue].lcnt++; + TAILQ_INSERT_TAIL(&vm_page_queues[m->queue].pl, m, + pageq); + ++vm_page_zero_count; + ++cnt_prezero; + if (vm_page_zero_count >= ZIDLE_HI(cnt.v_free_count)) + zero_state = 1; + } + free_rover = (free_rover + PQ_PRIME2) & PQ_L2_MASK; + splx(s); + mtx_unlock(&Giant); + return (1); + } + return (0); +} + +/* + * Software interrupt handler for queued VM system processing. + */ +void +swi_vm(void *dummy) +{ +#if 0 /* XXX: Don't have busdma stuff yet */ + if (busdma_swi_pending != 0) + busdma_swi(); +#endif +} + +/* + * Tell whether this address is in some physical memory region. + * Currently used by the kernel coredump code in order to avoid + * dumping the ``ISA memory hole'' which could cause indefinite hangs, + * or other unpredictable behaviour. + */ + + +int +is_physical_memory(vm_offset_t addr) +{ + /* + * stuff other tests for known memory-mapped devices (PCI?) + * here + */ + + return 1; +} Index: sys/mount.h =================================================================== RCS file: /home/ncvs/src/sys/sys/mount.h,v retrieving revision 1.109 diff -u -r1.109 mount.h --- sys/mount.h 2001/05/01 08:13:17 1.109 +++ sys/mount.h 2001/06/03 08:38:20 @@ -72,7 +72,7 @@ */ #define MFSNAMELEN 16 /* length of fs type name, including null */ -#ifdef __i386__ +#if defined(__i386__) || defined(__powerpc__) #define MNAMELEN 80 /* length of buffer for returned name */ #endif #if defined(__alpha__) || defined(__ia64__) Index: sys/user.h =================================================================== RCS file: /home/ncvs/src/sys/sys/user.h,v retrieving revision 1.37 diff -u -r1.37 user.h --- sys/user.h 2001/05/01 08:13:18 1.37 +++ sys/user.h 2001/06/01 08:58:11 @@ -82,6 +82,9 @@ #ifdef __i386__ #define KINFO_PROC_SIZE 648 /* the correct size for kinfo_proc */ #endif +#ifdef __powerpc__ +#define KINFO_PROC_SIZE 656 +#endif #ifndef KINFO_PROC_SIZE #error "Unknown architecture" #endif