Category : UNIX Files
Archive   : MK42BASE.ZIP
Filename : MK42BASE
# Copyright (c) 1989 Carnegie-Mellon University
# All rights reserved. The CMU software License Agreement specifies
# the terms and conditions for use and redistribution.
#
#
# HISTORY
# $Log: Makeconf,v $
# Revision 2.4 90/11/05 14:24:49 rpd
# Added REG_EXP.
# [90/10/29 rwd]
#
# Revision 2.3 90/06/02 14:44:52 rpd
# Export changed PATH and LPATH so the released mig is used.
# [90/03/26 21:22:44 rpd]
#
# Revision 2.2 89/10/16 15:21:50 rwd
# First Checkin
# [89/10/05 16:11:51 rwd]
#
OBJECTDIR=../../../release/@sys/${BCSBBASE?$(BCSBBASE:t):latest}/include
#
# Put the release bin and lib on our paths,
# so that we get the released mig/migcom.
#
PATH = ../bin:$(PATH)
LPATH = ../lib:$(LPATH)
I386_REG_EXP=.*
REG_EXP=${$(TARGET_MACHINE)_REG_EXP?${$(TARGET_MACHINE)_REG_EXP}:*}
.EXPORT : PATH LPATH
./include/Makefile 444 146 0 20567 4742765440 7344 #
# Mach Operating System
# Copyright (c) 1990 Carnegie-Mellon University
# Copyright (c) 1989 Carnegie-Mellon University
# All rights reserved. The CMU software License Agreement specifies
# the terms and conditions for use and redistribution.
#
# HISTORY
# $Log: Makefile,v $
# Revision 2.19 91/01/08 21:22:30 rpd
# Added i386at/disk.h.
#
# Revision 2.18 91/01/08 19:18:25 rpd
# Added i386/fp_reg.h.
# [91/01/08 rpd]
#
# Revision 2.17 91/01/08 15:08:33 rpd
# Added mach_debug/hash_info.h.
# [91/01/04 rpd]
#
# Revision 2.16 90/12/05 23:26:49 af
#
#
# Revision 2.15 90/12/05 20:42:01 af
# Revised PMAX device exports, for new copyright free code.
# [90/12/04 af]
#
# Revision 2.14 90/11/05 14:24:54 rpd
# Added machine/cthreads.h include file from libthreads.
# [90/11/01 rwd]
# Added REG_EXP.
# [90/10/29 rwd]
#
# Revision 2.13 90/09/09 23:19:43 rpd
# Added if_se.h for MIPS mapped ether.
# [90/08/23 af]
#
# Revision 2.12 90/08/06 15:06:31 rwd
# Rid ourselves of sys/types.h and sys/ioctl.h. These are bad to
# have around for server compilations.
# [90/07/16 rwd]
#
# Revision 2.11 90/06/02 14:44:56 rpd
# Fixed definition of SRCBASE so that symbolic links work
# when BCSBBASE isn't defined.
# [90/05/01 rpd]
#
# Added mach_debug/vm_info.h.
# [90/04/20 rpd]
#
# Use symbolic links instead of copying.
# [90/03/27 rpd]
# Removed mach/mach_extra.h, mach/vm_param.h.
# Added new host/processor header files.
# Added mach/notify.defs, mach/mach_port.defs.
# Changed mach_debug/ files.
# mach/mach.h comes from libmach now.
# [90/03/26 21:26:07 rpd]
#
# Revision 2.10 90/05/08 16:43:31 dbg
# Ensure that we always find MiG.
# [90/05/08 dbg]
#
# Revision 2.9 90/05/03 15:14:31 dbg
# Get the dependencies right.
# Fix list of MACH_DEBUG files.
# [90/05/02 dbg]
#
# Add i386 support.
# [90/04/23 dbg]
#
# Revision 2.8 90/03/14 21:09:52 rwd
# Added default_pager_object.defs and host_types.h.
# [90/01/22 rwd]
#
# Revision 2.7 90/01/22 23:04:10 af
# Added vm_attributes.h
# [89/12/09 10:43:29 af]
#
# Added PMAX device headers.
# [89/11/30 af]
#
# Revision 2.6 89/12/08 19:46:03 rwd
# Added PMAX device headers.
# [89/11/30 af]
#
# Revision 2.5 89/11/29 14:07:49 af
# Added one more mips file.
# [89/11/28 13:16:27 af]
#
# Added varargs.h in the include list. Copied from libmach.
# I think there are now three copies of varargs around...
# needs fixing.
# [89/10/28 10:52:10 af]
#
# Added MIPS files.
# [89/10/28 09:51:53 af]
#
# Revision 2.4 89/11/14 11:02:11 dbg
# Fix double make rule for 'sys' directory.
# [89/11/14 dbg]
#
# Revision 2.3 89/11/13 15:26:39 dbg
# Add vaxuba directory and header files for QD, QV drivers.
# [89/11/13 dbg]
#
# Revision 2.2 89/10/16 15:21:55 rwd
# Created version for $BCSBBASE/include
# [89/10/05 rwd]
#
#
#
# Makefile to populate include directory from kernel, libmach, libthreads.
#
# Assume in {base}/include; sources in {base}/src
#
SRCBASE= ${BCSBBASE?$(BCSBBASE):$(MAKECONF:h)/..}
MACH_KERNEL= ${SRCBASE}/kernel
LIBMACH= ${SRCBASE}/user/libmach
LIBTHREADS= ${SRCBASE}/user/threads
MACH_INCLUDES= mach/boolean.h mach/error.h mach/exception.h \
mach/kern_return.h mach/mach_traps.h \
mach/mach_types.h mach/machine.h mach/memory_object.h \
mach/message.h mach/mig_errors.h mach/msg_type.h \
mach/notify.h mach/port.h mach/std_types.h mach/syscall_sw.h \
mach/task_info.h mach/task_special_ports.h mach/thread_info.h \
mach/thread_special_ports.h mach/thread_status.h \
mach/time_value.h mach/vm_inherit.h \
mach/vm_prot.h mach/vm_statistics.h mach/vm_attributes.h \
mach/host_info.h mach/mach_param.h mach/policy.h \
mach/processor_info.h mach/thread_switch.h \
mach/mach_types.defs mach/std_types.defs
MACH_DEFS= mach/exc.defs mach/mach.defs \
mach/mach_host.defs mach/mach_port.defs mach/notify.defs \
mach/memory_object.defs mach/memory_object_default.defs \
mach/default_pager_object.defs
MACH_HDRS= mach/exc.h mach/mach_interface.h mach/memory_object_user.h \
mach/mach_host.h mach/mach_port.h \
mach/memory_object_default.h mach/default_pager_object.h
MACH_MACHINE_INCLUDES=\
boolean.h \
exception.h \
kern_return.h \
syscall_sw.h \
thread_status.h \
vm_param.h \
vm_types.h
MACH_VAX = mach/vax/
MACH_SUN3 = mach/sun3/
MACH_MIPS = mach/mips/
MACH_I386 = mach/i386/
MACH_VAX_INCLUDES= ${MACH_MACHINE_INCLUDES/$(REG_EXP)/${MACH_VAX}&}
MACH_SUN3_INCLUDES= ${MACH_MACHINE_INCLUDES/$(REG_EXP)/${MACH_SUN3}&} \
mach/sun3/reg.h
MACH_MIPS_INCLUDES= ${MACH_MACHINE_INCLUDES/$(REG_EXP)/${MACH_MIPS}&} \
mach/mips/asm.h mach/mips/mips_instruction.h
MACH_I386_INCLUDES= ${MACH_MACHINE_INCLUDES/$(REG_EXP)/${MACH_I386}&} \
i386/fp_reg.h
MACH_FILES= ${MACH_INCLUDES} ${MACH_DEFS} ${MACH_HDRS} \
${MACH_VAX_INCLUDES} ${MACH_SUN3_INCLUDES} \
${MACH_MIPS_INCLUDES} ${MACH_I386_INCLUDES}
MACH_DEBUG_INCLUDES=\
mach_debug/ipc_info.h mach_debug/vm_info.h \
mach_debug/zone_info.h mach_debug/page_info.h \
mach_debug/hash_info.h \
mach_debug/mach_debug_types.h \
mach_debug/mach_debug_types.defs
MACH_DEBUG_DEFS=\
mach_debug/mach_debug.defs
MACH_DEBUG_HDRS=\
${MACH_DEBUG_DEFS:.defs=.h}
MACH_DEBUG_FILES=\
${MACH_DEBUG_INCLUDES} ${MACH_DEBUG_DEFS} ${MACH_DEBUG_HDRS}
DEVICE_INCLUDES= \
device/device_types.h device/net_status.h device/tty_status.h \
device/device_types.defs
DEVICE_VAX_INCLUDES= \
vaxuba/qdioctl.h vaxuba/qdreg.h vaxuba/qduser.h \
vaxuba/qevent.h vaxuba/qvioctl.h vaxuba/qvreg.h
DEVICE_PMAX_INCLUDES= \
mips/PMAX/screen.h mips/PMAX/mapped_scsi.h mips/PMAX/if_se.h \
mips/PMAX/lk201.h
DEVICE_I386_INCLUDES= \
i386at/disk.h
DEVICE_DEFS= device/device.defs device/device_reply.defs \
device/device_request.defs
DEVICE_HDRS= ${DEVICE_DEFS:.defs=.h}
DEVICE_FILES= ${DEVICE_INCLUDES} ${DEVICE_DEFS} ${DEVICE_HDRS} \
${DEVICE_VAX_INCLUDES} ${DEVICE_PMAX_INCLUDES} \
${DEVICE_I386_INCLUDES}
DIRS= device mach mach/vax mach/sun3 mach/mips mach/i386 \
mach_debug \
./mips mips/PMAX sys vaxuba \
./vax ./sun3 ./i386 ./i386at
LINKS= mach/vax_mach mach/sun3_mach mach/pmax_mach mach/i386_mach \
mach/machine sun3_mach i386_mach pmax_mach vax_mach machine
LIBMACH_FILES= mach/mach.h mach_init.h setjmp.h strings.h varargs.h
LIBTHREADS_FILES=\
cthreads.h sun3/cthreads.h mips/cthreads.h vax/cthreads.h \
mips i386/cthreads.h
COMPAT_FILES_1= kern/mach.h sys/kern_return.h sys/message.h
COMPAT_FILES_2= ./mach.h ./mig_errors.h ./msg_type.h
COMPAT_FILES= ${COMPAT_FILES_1} ${COMPAT_FILES_2}
COMPAT_DIRS= kern sys
#
# Directory lists overlap - build their union.
#
ALLDIRLIST= ${DIRS} ${COMPAT_DIRS}
ALLDIRS= ${ALLDIRLIST:u}
all: ${ALLDIRS} ${LINKS} ${MACH_FILES} ${DEVICE_FILES} ${MACH_DEBUG_FILES} \
${LIBMACH_FILES} ${LIBTHREADS_FILES} \
${COMPAT_FILES}
${ALLDIRS}:
-if [ ! -d $@ ]; then mkdir $@; fi
${LINKS}:
-if [ ! -d mach/vax_mach ]; then ln -s vax mach/vax_mach; fi
-if [ ! -d mach/sun3_mach ]; then ln -s sun3 mach/sun3_mach; fi
-if [ ! -d mach/pmax_mach ]; then ln -s mips mach/pmax_mach; fi
-if [ ! -d mach/i386_mach ]; then ln -s i386 mach/i386_mach; fi
-if [ ! -d mach/machine ]; then ln -s @sys mach/machine; fi
-if [ ! -d vax_mach ]; then ln -s vax vax_mach; fi
-if [ ! -d sun3_mach ]; then ln -s sun3 sun3_mach; fi
-if [ ! -d pmax_mach ]; then ln -s mips pmax_mach; fi
-if [ ! -d i386_mach ]; then ln -s i386 i386_mach; fi
-if [ ! -d machine ]; then ln -s @sys machine; fi
${MACH_INCLUDES} ${MACH_DEFS} ${MACH_VAX_INCLUDES} ${MACH_SUN3_INCLUDES} \
${MACH_MIPS_INCLUDES} ${MACH_I386_INCLUDES} \
${MACH_DEBUG_INCLUDES} ${MACH_DEBUG_DEFS}:
ln -s ${MACH_KERNEL}/$@ $@
${DEVICE_INCLUDES} ${DEVICE_DEFS} ${DEVICE_VAX_INCLUDES} \
${DEVICE_PMAX_INCLUDES} ${DEVICE_I386_INCLUDES}:
ln -s ${MACH_KERNEL}/$@ $@
${LIBMACH_FILES}:
ln -s ${LIBMACH}/$(@F) $@
${LIBTHREADS_FILES}:
ln -s ${LIBTHREADS}/$@ $@
${COMPAT_FILES_1}:
ln -s ../mach/$(@F) $@
${COMPAT_FILES_2}:
ln -s mach/$(@F) $@
%.h: %.defs
mig -I. -server /dev/null -user /dev/null -header %.h %.defs
mach/memory_object_user.h: mach/memory_object.defs
mig -I. -server /dev/null -user /dev/null \
-header $@ mach/memory_object.defs
mach/mach_interface.h: mach/mach.defs
mig -I. -server /dev/null -user /dev/null \
-header $@ mach/mach.defs
clean:
rm -rf *
call_sw.h \
thread_status.h \
vm_param.h \
vm_types.h
MACH_VAX = mach/vax/
MACH_SUN3 = mach/sun3/
MACH_MIPS = mach/mips/
MACH_I386./user/ 755 146 0 0 4756612013 5112 ./user/libmach/ 755 146 0 0 4756613246 6522 ./user/libmach/mips/ 755 146 0 0 4756613047 7471 ./user/libmach/mips/_setjmp.s 444 146 0 10243 4756607737 11432 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: _setjmp.s,v $
* Revision 2.4 91/02/14 14:18:09 mrt
* Added new Mach copyright
* [91/02/13 12:46:43 mrt]
*
* Revision 2.3 90/06/02 15:12:46 rpd
* Rearranged fields in jmpbuf, to put size field first.
* This allows setjmp/longjmp to use a smaller jmpbuf.
* [90/04/29 rpd]
*
* Revision 2.2 89/11/29 14:18:33 af
* Changed names, so that standalone programs do not end
* up using the floating point unit for nothing.
* [89/11/16 14:30:45 af]
*
* Created.
* [89/10/12 af]
*
*/
#include
/*
* Non local goto for user programs.
*
*/
/*
* These definitions are here and not exported because
* it is unpleasant to think that someone might actually
* need to play with the content of a jumpbuf.
*/
#define JB_SIZE 0
#define JB_PC 4
#define JB_SP 8
#define JB_S0 12
#define JB_S1 16
#define JB_S2 20
#define JB_S3 24
#define JB_S4 28
#define JB_S5 32
#define JB_S6 36
#define JB_S7 40
#define JB_FP 44
#define JB_FPA_SR 48
#define JB_F20 52
#define JB_F22 56
#define JB_F24 60
#define JB_F26 64
#define JB_F28 68
#define JB_F30 72
#define JB_SMALL 48
#define JB_BIG 76
.set reorder
/*
* Object:
* setjmp EXPORTED function
* _setjmp_ EXPORTED function
*
* Save current context for non-local goto's
*
* Arguments:
* a0 jmp_buf *
*
* Saves all registers that are callee-saved in the
* given longjmp buffer.
* If a standalone program *really* needs to use the
* floating point accelerator it should use the slower
* alternate _setjmp_/_longjmp_ with some extra context
* switch time penalty.
* Note that our definitions of setjmp is the one that
* libc calls _setjmp, while libc's setjmp is what we
* call _setjmp_ [all this to avoid unintended use of
* the FPA...].
*
* Return 0.
*/
LEAF(_setjmp_)
li v0,JB_BIG
sw v0,JB_SIZE(a0)
cfc1 v0,fpa_csr
sw v0,JB_FPA_SR(a0)
s.d $f20,JB_F20(a0)
s.d $f22,JB_F22(a0)
s.d $f24,JB_F24(a0)
s.d $f26,JB_F26(a0)
s.d $f28,JB_F28(a0)
s.d $f30,JB_F30(a0)
b skips
XLEAF(setjmp)
XLEAF(_setjmp)
li v0,JB_SMALL
sw v0,JB_SIZE(a0)
skips: sw ra,JB_PC(a0)
sw sp,JB_SP(a0)
sw fp,JB_FP(a0)
sw s0,JB_S0(a0)
sw s1,JB_S1(a0)
sw s2,JB_S2(a0)
sw s3,JB_S3(a0)
sw s4,JB_S4(a0)
sw s5,JB_S5(a0)
sw s6,JB_S6(a0)
sw s7,JB_S7(a0)
move v0,zero
j ra
END(_setjmp)
/*
* Object:
* longjmp EXPORTED function
*
* Perform a non-local goto
*
* Arguments:
* a0 jmp_buf *
* a1 int
*
* Restores all registers that are callee-saved from the
* given longjmp buffer. Mild checks.
* Return the value in a1.
*/
LEAF(_longjmp_)
lw v0,JB_SIZE(a0)
li s0,JB_BIG
bne v0,s0,botch
lw v0,JB_FPA_SR(a0)
ctc1 v0,fpa_csr
l.d $f20,JB_F20(a0)
l.d $f22,JB_F22(a0)
l.d $f24,JB_F24(a0)
l.d $f26,JB_F26(a0)
l.d $f28,JB_F28(a0)
l.d $f30,JB_F30(a0)
b skipl
XLEAF(longjmp)
XLEAF(_longjmp)
lw v0,JB_SIZE(a0)
li s0,JB_SMALL
bne v0,s0,botch
skipl: lw ra,JB_PC(a0)
lw sp,JB_SP(a0)
lw fp,JB_FP(a0)
lw s0,JB_S0(a0)
lw s1,JB_S1(a0)
lw s2,JB_S2(a0)
lw s3,JB_S3(a0)
lw s4,JB_S4(a0)
lw s5,JB_S5(a0)
lw s6,JB_S6(a0)
lw s7,JB_S7(a0)
move v0,a1
j ra
botch:
break 0 # Illegal bp
b botch # ..just in case..
END(_longjmp)
ot exported because
* it is unpleasant to think that someone might actually
* need to play with the content of a jumpbuf.
*/
#define JB_SIZE 0
#define JB_PC 4
#define JB_SP 8
#define JB_S0 12
#define JB_S1 16
#define JB_S2 20
#define JB_S3 24
#define JB_S4 28
#define JB_S5 32
#define JB_S6 36
#define JB_S7 40
#define JB_FP 44
#defi./user/libmach/mips/bcopy.c 444 146 0 4442 4756607737 11051 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: bcopy.c,v $
* Revision 2.3 91/02/14 14:18:14 mrt
* Added new Mach copyright
* [91/02/13 12:46:06 mrt]
*
* Revision 2.2 89/11/29 14:18:36 af
* Forgot to bring over fixed kernel version.
* [89/11/26 10:28:45 af]
*
* Created.
* [89/10/12 af]
*
*/
/*
* Object:
* bcopy EXPORTED function
*
* Memory copy
*
*/
/*
* Object:
* bcopy EXPORTED function
*
* Memory copy
*
*/
void
bcopy(from, to, bcount)
register unsigned from;
register unsigned to;
register unsigned bcount;
{
register int i;
if ((from & 3) != (to & 3)) {
/* wont align easily */
while (bcount--)
*((char *) to++) = *((char *) from++);
return;
}
switch (to & 3) {
case 1:
*((char *) to++) = *((char *) from++);
if (--bcount == 0)
return;
case 2:
*((char *) to++) = *((char *) from++);
if (--bcount == 0)
return;
case 3:
*((char *) to++) = *((char *) from++);
if (--bcount == 0)
return;
default:
break;
}
for (i = bcount >> 2; i; i--, to += 4, from += 4)
*((int *) to) = *((int *) from);
switch (bcount & 3) {
case 3:
*((char *) to++) = *((char *) from++);
case 2:
*((char *) to++) = *((char *) from++);
case 1:
*((char *) to++) = *((char *) from++);
default:
break;
}
}
.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.
*/
/./user/libmach/mips/bzero.c 444 146 0 4156 4756607741 11053 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: bzero.c,v $
* Revision 2.3 91/02/14 14:18:18 mrt
* Added new Mach copyright
* [91/02/13 12:46:15 mrt]
*
* Revision 2.2 89/11/29 14:18:39 af
* Forgot to bring over bug fix from kernel.
* [89/11/26 10:28:12 af]
*
* Created.
* [89/10/12 af]
*
*/
/*
* Object:
* bzero EXPORTED function
*
* Clear memory locations
*
* Optimize for aligned memory ops, if possible and simple.
* Might need later recoding in assembly for better efficiency.
*/
void
bzero(addr, bcount)
register unsigned addr;
register unsigned bcount;
{
register int i;
if (bcount == 0) /* sanity */
return;
switch (addr & 3) {
case 1:
*((char *) addr++) = 0;
if (--bcount == 0)
return;
case 2:
*((char *) addr++) = 0;
if (--bcount == 0)
return;
case 3:
*((char *) addr++) = 0;
if (--bcount == 0)
return;
default:
break;
}
for (i = bcount >> 2; i; i--, addr += 4)
*((int *) addr) = 0;
switch (bcount & 3) {
case 3: *((char*)addr++) = 0;
case 2: *((char*)addr++) = 0;
case 1: *((char*)addr++) = 0;
default:break;
}
}
#define JB_F30 72
#define JB_SMALL 48
#define JB_BIG 76
.set reorder
/*
* Object:
* setjmp EXPORTED function
* _setjmp_ EXPORTED function
*
* Save current context for non-local goto's
*
* Arguments:
* a0 jmp_buf *
*
* Saves all registers that are callee-saved in the
* given longjmp buffer.
* If a standalone program *really* needs to use the
* floating point accelerato./user/libmach/mips/crt0.cv 444 146 0 5206 4756607742 10766 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: crt0.cv,v $
* Revision 2.5 91/02/14 14:18:22 mrt
* Added new Mach copyright
* [91/02/13 12:46:51 mrt]
*
* Revision 2.4 90/11/05 14:35:48 rpd
* Removed the definition of exit.
* [90/10/30 rpd]
*
* Revision 2.3 90/06/02 15:12:51 rpd
* Converted to new IPC.
* [90/03/26 23:27:20 rpd]
*
* Revision 2.2 89/11/29 14:18:42 af
* Created.
* [89/10/26 af]
*
*/
#include
/*
* Object:
* __start EXPORTED function
* environ EXPORTED variable
*
* C startup code
*
*
* The kernel sets up the stack pointer to point to
* "argc", which is followed by the argv values,
* followed by a 0 (the end of the argv list),
* followed by the environ values, followed by a 0.
* Then all the strings that argv and environ point
* to (first the argv ones, then the environ ones).
*
* Some hackery in the Makefile will do the following
* things for us:
* set the GP register
* pick the SP register and copy it to A0
* neither one can be done by C (sigh).
*
* This file compiles either into the normal crt0.o
* version, or in the mcrt0.o one for profiling.
*/
va_list environ;
int (*mach_init_routine)(),
(*_cthread_init_routine)(),
(*_cthread_exit_routine)();
__start( sp )
register va_list sp;
{
register unsigned argc;
register va_list argv;
argc = va_arg(sp, unsigned);
argv = sp;
environ = argv + (argc + 1) * sizeof(char *);
if (mach_init_routine)
(*mach_init_routine)();
if (_cthread_init_routine)
(*_cthread_init_routine)();
argc = main(argc, argv, environ);
if (_cthread_exit_routine)
(*_cthread_exit_routine)(argc);
exit(argc);
}
} ${MACH_I386_INCLUDES} \
${MACH_DEBUG_INCLUDES} ${MACH_DEBUG_DEFS}:
ln -s ${MACH_KERNEL}/$@ $@
${DEVICE_INCLUDES} ${DEVICE_DEFS} ${DEVICE_VAX_INCLUDES} \
${DEVICE_PMAX_INCLUDES} ${DEVICE_I386_INCLUDES}:
ln -s ${MACH_KERNEL}/$@ $@
${LIBMACH_FILES}:
ln -s ${LIBMACH}/$(@F) $@
${LIBTHREADS_FILES}:
ln -s ${LIBTHREADS}/$@ $@
${COMPAT_FILES_1}:
ln -s ../mach/$(@F) $@
${CO./user/libmach/mips/crt0.ss 444 146 0 5731 4756607743 11007 #
# Mach Operating System
# Copyright (c) 1991,1990,1989 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
# 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 [email protected]
# 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.
#
#
# HISTORY
# $Log: crt0.ss,v $
# Revision 2.5 91/02/14 14:18:29 mrt
# Added new Mach copyright
# [91/02/13 12:50:02 mrt]
#
# Revision 2.4 90/11/05 14:35:56 rpd
# Removed the definition of exit.
# [90/10/30 rpd]
#
# Revision 2.3 90/06/02 15:12:57 rpd
# Converted to new IPC.
# [90/03/26 23:28:04 rpd]
#
# Revision 2.2 90/01/19 14:36:34 rwd
# Version from sandro.
# [90/01/18 rwd]
#
#
.verstamp 1 31
.comm environ 4
.comm mach_init_routine 4
.comm _cthread_init_routine 4
.comm _cthread_exit_routine 4
.text
.align 2
.file 2 "crt0.cv"
.globl __start
.loc 2 49
# 49 {
.ent __start 2
__start:
la $28,_gp
move $4,$29
#.option O2
subu $sp, 24
sw $31, 20($sp)
sw $16, 16($sp)
.mask 0x80010000, -4
.frame $sp, 24, $31
move $5, $4
.loc 2 53
# 50 register unsigned argc;
# 51 register va_list argv;
# 52
# 53 argc = va_arg(sp, unsigned);
addu $5, $5, 7
and $5, $5, -4
lw $16, -4($5)
.loc 2 54
# 54 argv = sp;
.loc 2 55
# 55 environ = argv + (argc + 1) * sizeof(char *);
mul $14, $16, 4
addu $15, $5, $14
addu $24, $15, 4
sw $24, environ
.loc 2 57
# 56
# 57 if (mach_init_routine)
lw $25, mach_init_routine
beq $25, 0, $32
.loc 2 58
# 58 (*mach_init_routine)();
sw $5, 24($sp)
jal $25
lw $5, 24($sp)
$32:
lw $2, _cthread_init_routine
.loc 2 59
# 59 if (_cthread_init_routine)
beq $2, 0, $33
.loc 2 60
# 60 (*_cthread_init_routine)();
sw $5, 24($sp)
jal $2
lw $5, 24($sp)
beq $2, $0, $33
subu $2, 0x14
move $29,$2
$33:
.loc 2 62
# 61
# 62 argc = main(argc, argv, environ);
move $4, $16
lw $6, environ
jal main
lw $3, _cthread_exit_routine
move $16, $2
.loc 2 64
# 63
# 64 if (_cthread_exit_routine)
beq $3, 0, $34
.loc 2 65
# 65 (*_cthread_exit_routine)(argc);
move $4, $16
jal $3
$34:
.loc 2 67
# 66
# 67 exit(argc);
move $4, $16
jal exit
.loc 2 68
# 68 }
lw $16, 16($sp)
lw $31, 20($sp)
addu $sp, 24
j $31
.end __start
FILES_1}:
ln -s ../mach/$(@F) $@
${CO./user/libmach/pmax_mach 755 146 0 0 4754023344 11303 2mips ./user/libmach/machine 755 146 0 0 4754036347 10727 2@sys ./user/libmach/Makefile 444 146 0 16233 4756607713 10274 #
# Mach Operating System
# Copyright (c) 1991,1990,1989 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
# 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 [email protected]
# 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.
#
#
# HISTORY
# $Log: Makefile,v $
# Revision 2.14 91/02/14 14:16:54 mrt
# Added new Mach copyright
# [91/02/13 12:45:25 mrt]
#
# Revision 2.13 90/12/05 23:46:53 af
# Changed .cs->.o rule to account for GNU i386 compiler driver.
#
# Revision 2.12 90/11/05 14:35:27 rpd
# SUN->SUN3.
# [90/10/31 rwd]
# Change MACHINE to TARGET_MACHINE.
# [90/10/29 rwd]
#
# Revision 2.11 90/11/05 14:08:04 rpd
# Added start_float.s, for the Sun-3.
# [90/11/01 rpd]
# Added exit.c.
# [90/10/30 rpd]
#
# Revision 2.10 90/10/25 14:51:02 rwd
# Add I386 fields.
# [90/10/24 rwd]
#
# Revision 2.9 90/08/07 18:00:50 rpd
# Added mach_msg_destroy.c, mach_msg_server.c.
# [90/08/06 rpd]
#
# Revision 2.8 90/06/19 23:03:33 rpd
# Added mach_port_allocate, mach_port_deallocate, mach_port_insert_right
# to the sed script nonsense.
# [90/06/02 rpd]
#
# Revision 2.7 90/06/02 15:12:18 rpd
# Use -O2 -g3 on mips.
# [90/04/25 rpd]
# Compile with -DMACH_IPC_COMPAT=0.
# [90/03/26 23:25:36 rpd]
#
# Revision 2.6 90/05/29 18:40:00 rwd
# New mach_syscalls.c and sed changes to mach_user.
# [90/04/20 rwd]
#
# Revision 2.5 90/05/03 15:53:35 dbg
# Add files for AT386.
# [90/04/23 dbg]
#
# Revision 2.4 90/01/19 14:36:29 rwd
# mips crt0 is now .s instead of .cv
# [90/01/18 rwd]
#
# Revision 2.3 89/11/29 14:18:30 af
# Use MD switch in assembly compiles (af+mips problem).
# [89/11/26 10:27:18 af]
#
# Added Mips files and a special rule for compiling crt0.cv
# which needs a little massaging of the assembly but is otherwise
# a C file.
# Also, added machine-specific flags to assembler invocation,
# because on Mips as invokes cpp by default but does not like
# to see it twice.
# [89/10/28 10:59:33 af]
#
# Revision 2.2 89/08/11 17:57:18 rwd
# Make clean now removes crt0.c
# [89/08/11 rwd]
#
#
# Makefile for stand-alone stuff (so far)
LIB= libmach_sa.a
SRCS= mach_traps.cs mig_support.c mig_strncpy.c \
mach_msg_destroy.c mach_msg_server.c \
strcmp.c strlen.c strncpy.c msg.c mach_syscalls.c machine/_setjmp.s \
machine/bcopy.cs strcat.c strcpy.c mach_init.c exit.c
VAX_SRCS= urem.s udiv.s
SUN3_SRCS= start_float.s
VAX_CRT0= machine/crt0.cc
SUN3_CRT0= machine/crt0.s
# PMAX_CRT0= machine/crt0.cv
PMAX_CRT0 = machine/crt0.ss
AT386_CRT0 = machine/crt0.c
I386_CRT0 = machine/crt0.c
PMAX_ASFLAGS= -nocpp
OBJS= crt0.o exit.o mach_user.o mach_traps.o mig_support.o \
mach_msg_destroy.o mach_msg_server.o \
bcopy.o strcmp.o strlen.o strncpy.o msg.o exc_server.o \
mach_host_user.o mach_port_user.o mach_syscalls.o \
device_user.o device_request_user.o device_reply_server.o \
_setjmp.o bzero.o strcat.o strcpy.o mach_init.o mig_strncpy.o
VAX_OBJS= urem.o udiv.o
SUN3_OBJS= start_float.o
I386_OBJS= gcc.o
AT386_OBJS= gcc.o
DEFS= mach/exc.defs mach/memory_object.defs mach/mach.defs mach/host.defs \
device/device.defs device/device_request.defs device/device_reply.defs
PMAX_CDEBUGFLAGS = -O2 -g3
CDEBUGFLAGS = $($(TARGET_MACHINE)_CDEBUGFLAGS?$($(TARGET_MACHINE)_CDEBUGFLAGS):-O)
DEFINES = -DMACH_IPC_COMPAT=0 -DSTANDALONE -DTypeCheck=0
CFLAGS = $(CDEBUGFLAGS) $(DEFINES) $(INCLUDES)
CPP = $(CC) -ES
MIG=mig
MIGFLAGS = $(MIGOPTS) $(DEFINES) $(INCLUDES)
.SUFFIXES: .cs .cc .ss
${LIB}: ${OBJS} ${${TARGET_MACHINE}_OBJS}
rm -f ${LIB}
ar crv ${LIB} ${OBJS} ${${TARGET_MACHINE}_OBJS}
ranlib ${LIB}
crt0.o: ${${TARGET_MACHINE}_CRT0}
.c.o:
$(CC) -c $(CFLAGS) -o $*.o $*.c
.s.o:
${CPP} -MD ${DEFINES} ${INCLUDES} $*.s > $*.as
${AS} ${${TARGET_MACHINE}_ASFLAGS} -o $*.o $*.as
rm -f $*.as
.ss.o:
${AS} ${${TARGET_MACHINE}_ASFLAGS} -o $*.o $*.ss
.cs.o:
cp $*.cs $*.S
${CPP} -ES -MD ${DEFINES} ${INCLUDES} $*.S > $*.as
${AS} ${${TARGET_MACHINE}_ASFLAGS} -o $*.o $*.as
rm -f $*.S $*.as
#
# Special '.cc' suffix for putting crt0 thru cpp twice.
#
.cc.o:
cp $*.cc $*.c
${CC} -S -DCRT0 $*.c
${CPP} $*.s > $*.i
${AS} -o $*.o $*.i
#
# Special '.cv' suffix for massaging intermediate assembly code
# for mips
#
#.cv.o:
# cp $*.cv $*.c
# cc -O2 -S crt0.c
# sed -e 's<__start:<__start: la $$28,_gp;move $$4,$$29<' \
# -e 's<\.option<\#\.option<' \
# crt0.s > crt0t.s && mv crt0t.s crt0.s
# cc -O2 -c crt0.s && rm -f crt0.s
# ld -x -r crt0.o
# mv a.out crt0.o
mach_user.c: mach/mach.defs mach/mach_types.defs
${MIG} ${MIGFLAGS} \
-user mach_temp \
-header mach_interface.h \
-server /dev/null \
mach/mach.defs
sed -e 's/vm_allocate/mig_vm_allocate/' \
-e 's/vm_map/mig_vm_map/' \
-e 's/vm_deallocate/mig_vm_deallocate/' \
-e 's/task_create/mig_task_create/' \
-e 's/task_terminate/mig_task_terminate/' \
-e 's/task_suspend/mig_task_suspend/' \
-e 's/task_set_special_port/mig_task_set_special_port/' \
< mach_temp > mach_user.c
rm -f mach_temp
mach_port_user.c: mach/mach_port.defs mach/mach_types.defs
${MIG} ${MIGFLAGS} \
-user mach_port_temp \
-header mach_port.h \
-server /dev/null \
mach/mach_port.defs
sed -e 's/mach_port_allocate/mig_mach_port_allocate/' \
-e 's/mach_port_deallocate/mig_mach_port_deallocate/' \
-e 's/mach_port_insert_right/mig_mach_port_insert_right/' \
< mach_port_temp > mach_port_user.c
rm -f mach_port_temp
exc_server.c: mach/exc.defs mach/mach_types.defs
${MIG} ${MIGFLAGS} \
-server exc_server.c \
-header exc.h \
-user /dev/null \
mach/exc.defs
device_user.c: device/device.defs device/device_types.defs
${MIG} ${MIGFLAGS} \
-user device_user.c \
-header device.h \
-server /dev/null \
device/device.defs
device_request_user.c: device/device_request.defs device/device_types.defs
${MIG} ${MIGFLAGS} \
-user device_request_user.c \
-server /dev/null \
device/device_request.defs
device_reply_server.c: device/device_reply.defs device/device_types.defs
${MIG} ${MIGFLAGS} \
-server device_reply_server.c \
-user /dev/null \
device/device_reply.defs
mach_host_user.c: mach/mach_host.defs mach/mach_types.defs
${MIG} ${MIGFLAGS} \
-user mach_host_user.c \
-server /dev/null \
mach/mach_host.defs
clean:
rm -f ${OBJS} *.as *User.c *Server.c *_user.c *_server.c *.d
rm -f mach_interface.h exc.h device.h device_request.h device_reply.h
rm -f mach_port.h mach_host.h
rm -f crt0.s x.s crt0.c
mach/sun3/reg.h
MACH_MIPS_INCLUDES= ${MACH_MACHINE_INCLUDES/$(REG_EXP)/${MACH_MIPS}&} \
mach/mips/asm.h mach/mips/mips_instruction.h
MACH_I386_INCLUDES= ${MACH_MACHINE_INCLUDES/$(REG_EXP)/${MACH_I386}&} \
i386/fp_reg.h
MACH_FILES= ${MACH_INCLUDES} ${MACH_DEFS} ${MACH_HDRS} \
${MACH_VAX_INCLUDES} ${MACH_SUN3_INCLUDES} \
${MACH_MIPS_INCLUDES} ./user/libmach/exit.c 444 146 0 2701 4756607714 7725 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: exit.c,v $
* Revision 2.3 91/02/14 14:16:59 mrt
* Added new Mach copyright
* [91/02/13 12:43:58 mrt]
*
* Revision 2.2 90/11/05 14:35:34 rpd
* Created.
* [90/10/30 rpd]
*
*/
#include
void _exit(code)
int code;
{
for (;;) {
/* shouldn't return, but just in case... */
(void) task_terminate(mach_task_self());
}
}
void exit(code)
int code;
{
_exit(code);
}
.cv' suffix for massaging intermediate assembly code
# for mips./user/libmach/mach.h 444 146 0 3140 4756607724 7670 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: mach.h,v $
* Revision 2.3 91/02/14 14:17:30 mrt
* Added new Mach copyright
* [91/02/13 12:44:03 mrt]
*
* Revision 2.2 90/06/02 15:12:22 rpd
* Created
* [89/05/24 mrt]
*
*/
/*
* Includes all the types that a normal user
* of Mach programs should need
*/
#ifndef _MACH_H_
#define _MACH_H_
#include
#include
#include
#include
#include
#include
#include
#include
#endif _MACH_H_
ights 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 SOFT./user/libmach/mach_init.c 444 146 0 6752 4756607725 10723 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989,1988,1987 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: mach_init.c,v $
* Revision 2.3 91/02/14 14:17:35 mrt
* Added new Mach copyright
* [91/02/13 12:44:06 mrt]
*
* Revision 2.2 90/06/02 15:12:28 rpd
* Converted to new IPC.
* [90/03/26 23:26:00 rpd]
*
* Revision 2.1 89/08/03 17:05:42 rwd
* Created.
*
* 18-Jan-89 David Golub (dbg) at Carnegie-Mellon University
* Altered for stand-alone use:
* . Removed registered port list.
* . Removed task_data (obsolete), task_notify.
* . Removed Accent compatibility calls.
*
* 23-Nov-87 Mary Thompson (mrt) at Carnegie Mellon
* removed includes of
* as they are no longer used.
*
* 5-Oct-87 Mary Thompson (mrt) at Carnegie Mellon
* Added an extern void definition of mig_init to keep
* lint happy
*
* 30-Jul-87 Mary Thompson (mrt) at Carnegie Mellon
* Changed the intialization of the mig_reply_port to be
* a call to mig_init instead init_mach.
*
* 27-May-87 Richard Draves (rpd) at Carnegie-Mellon University
* Changed initialization of mach interface, because the
* new mig doesn't export an alloc_port_mach function.
*
* 15-May-87 Mary Thompson
* Removed include of sys/features.h and conditional
* compliations
*
* 4-May-87 Mary Thompson
* vm_deallocted the init_ports array so that brk might
* have a chance to be correct.
*
* 24-Apr-87 Mary Thompson
* changed type of mach_init_ports_count to unsigned int
*
* 12-Nov-86 Mary Thompson
* Added initialization call to init_netname the new
* interface for the net name server.
*
* 7-Nov-86 Michael Young
* Add "service_port"
*
* 7-Sep-86 Michael Young (mwyoung) at Carnegie-Mellon University
* Added initialization for MACH_IPC, using mach_ports_lookup.
*
* 29-Aug-86 Michael Young (mwyoung) at Carnegie-Mellon University
* Added other interesting global ports.
*/
#define MACH_INIT_SLOTS 1
#include "mach_init.h"
#include
extern void mig_init();
mach_port_t mach_task_self_ = MACH_PORT_NULL;
vm_size_t vm_page_size;
int mach_init()
{
vm_statistics_data_t vm_stat;
kern_return_t kr;
#undef mach_task_self
/*
* Get the important ports into the cached values,
* as required by "mach_init.h".
*/
mach_task_self_ = mach_task_self();
/*
* Initialize the single mig reply port
*/
mig_init(0);
/*
* Cache some other valuable system constants
*/
(void) vm_statistics(mach_task_self_, &vm_stat);
vm_page_size = vm_stat.pagesize;
return(0);
}
int (*mach_init_routine)() = mach_init;
LON ALLOWS FREE USE OF./user/libmach/mach_init.h 444 146 0 4734 4756607726 10727 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989,1988,1987,1986 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: mach_init.h,v $
* Revision 2.3 91/02/14 14:17:39 mrt
* Added new Mach copyright
* [91/02/13 12:44:11 mrt]
*
* Revision 2.2 90/06/02 15:12:32 rpd
* Converted to new IPC.
* Added user versions of round_page and trunc_page.
* [90/03/26 23:26:34 rpd]
*
* Revision 2.1 89/08/03 17:06:52 rwd
* Created.
*
* 18-Jan-89 David Golub (dbg) at Carnegie-Mellon University
* Altered for stand-alone use:
* . Removed registered port list.
* . Removed task_data (obsolete), task_notify.
*
* 18-May-87 Mary Thompson
* removed dependency on MACH_ACC || MACH_IPC
*
* 24-Apr-86 Mary Thompson
* changed type of mach_init_ports_count to unsigned int
*
* 7-Nov-86 Michael Young
* Add "service_port"
*
* 8-Sep-86 Michael Young (mwyoung) at Carnegie-Mellon University
* Added definition of mach_init_ports items for server startups.
*
*/
/*
* Items provided by the Mach environment initialization.
*/
#ifndef _MACH_INIT_
#define _MACH_INIT_ 1
#include
/*
* Kernel-related ports; how a task/thread controls itself
*/
extern mach_port_t mach_task_self_;
#define mach_task_self() mach_task_self_
#define current_task() mach_task_self()
/*
* Globally interesting numbers
*/
extern vm_size_t vm_page_size;
#define round_page(x) ((((vm_offset_t)(x) + (vm_page_size - 1)) / vm_page_size) * vm_page_size)
#define trunc_page(x) ((((vm_offset_t)(x)) / vm_page_size) * vm_page_size)
#endif _MACH_INIT_
call to init_netname the new
* inte./user/libmach/mach_msg_destroy.c 444 146 0 7447 4756607727 12323 /*
* Mach Operating System
* Copyright (c) 1991,1990 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: mach_msg_destroy.c,v $
* Revision 2.3 91/02/14 14:17:43 mrt
* Added new Mach copyright
* [91/02/13 12:44:15 mrt]
*
* Revision 2.2 90/08/06 17:24:22 rpd
* Created.
*
*/
#include
#include
#include
static void mach_msg_destroy_port();
static void mach_msg_destroy_memory();
/*
* Routine: mach_msg_destroy
* Purpose:
* Deallocates all port rights and out-of-line memory
* found in a received message.
*/
void
mach_msg_destroy(msg)
mach_msg_header_t *msg;
{
mach_msg_bits_t mbits = msg->msgh_bits;
/*
* The msgh_local_port field doesn't hold a port right.
* The receive operation consumes the destination port right.
*/
mach_msg_destroy_port(msg->msgh_remote_port, MACH_MSGH_BITS_REMOTE(mbits));
if (mbits & MACH_MSGH_BITS_COMPLEX) {
vm_offset_t saddr;
vm_offset_t eaddr;
saddr = (vm_offset_t) (msg + 1);
eaddr = (vm_offset_t) msg + msg->msgh_size;
while (saddr < eaddr) {
mach_msg_type_long_t *type;
mach_msg_type_name_t name;
mach_msg_type_size_t size;
mach_msg_type_number_t number;
boolean_t is_inline;
vm_size_t length;
vm_offset_t addr;
type = (mach_msg_type_long_t *) saddr;
is_inline = type->msgtl_header.msgt_inline;
if (type->msgtl_header.msgt_longform) {
name = type->msgtl_name;
size = type->msgtl_size;
number = type->msgtl_number;
saddr += sizeof(mach_msg_type_long_t);
} else {
name = type->msgtl_header.msgt_name;
size = type->msgtl_header.msgt_size;
number = type->msgtl_header.msgt_number;
saddr += sizeof(mach_msg_type_t);
}
/* calculate length of data in bytes, rounding up */
length = ((((number * size) + 7) >> 3) + 3) &~ 3;
addr = is_inline ? saddr : * (vm_offset_t *) saddr;
if (MACH_MSG_TYPE_PORT_ANY(name)) {
mach_port_t *ports = (mach_port_t *) addr;
mach_msg_type_number_t i;
for (i = 0; i < number; i++)
mach_msg_destroy_port(*ports++, name);
}
if (is_inline) {
/* inline data sizes round up to int boundaries */
saddr += length;
} else {
mach_msg_destroy_memory(addr, length);
saddr += sizeof(vm_offset_t);
}
}
}
}
static void
mach_msg_destroy_port(port, type)
mach_port_t port;
mach_msg_type_name_t type;
{
if (MACH_PORT_VALID(port)) switch (type) {
case MACH_MSG_TYPE_PORT_SEND:
case MACH_MSG_TYPE_PORT_SEND_ONCE:
(void) mach_port_deallocate(mach_task_self(), port);
break;
case MACH_MSG_TYPE_PORT_RECEIVE:
(void) mach_port_mod_refs(mach_task_self(), port,
MACH_PORT_RIGHT_RECEIVE, -1);
break;
}
}
static void
mach_msg_destroy_memory(addr, size)
vm_offset_t addr;
vm_size_t size;
{
if (size > 0)
(void) vm_deallocate(mach_task_self(), addr, size);
}
ACH_I386_INCLUDES= ${MACH_MACHINE_INCLUDES/$(REG_EXP)/${MACH_I386}&} \
i386/fp_reg.h
MACH_FILES= ${MACH_INCLUDES} ${MACH_DEFS} ${MACH_HDRS} \
${MACH_VAX_INCLUDES} ${MACH_SUN3_INCLUDES} \
${MACH_MIPS_INCLUDES} ./user/libmach/mach_msg_server.c 444 146 0 6333 4756607731 12124 /*
* Mach Operating System
* Copyright (c) 1991,1990 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: mach_msg_server.c,v $
* Revision 2.3 91/02/14 14:17:47 mrt
* Added new Mach copyright
* [91/02/13 12:44:20 mrt]
*
* Revision 2.2 90/08/06 17:23:58 rpd
* Created.
*
*/
#include
#include
#include
#include
#include
/*
* Routine: mach_msg_server
* Purpose:
* A simple generic server function.
*/
mach_msg_return_t
mach_msg_server(demux, max_size, rcv_name)
boolean_t (*demux)();
mach_msg_size_t max_size;
mach_port_t rcv_name;
{
register mig_reply_header_t *bufRequest, *bufReply, *bufTemp;
register mach_msg_return_t mr;
bufRequest = (mig_reply_header_t *) malloc(max_size);
if (bufRequest == 0)
return KERN_RESOURCE_SHORTAGE;
bufReply = (mig_reply_header_t *) malloc(max_size);
if (bufReply == 0)
return KERN_RESOURCE_SHORTAGE;
for (;;) {
get_request:
mr = mach_msg(&bufRequest->Head, MACH_RCV_MSG,
0, max_size, rcv_name,
MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
while (mr == MACH_MSG_SUCCESS) {
/* we have a request message */
(void) (*demux)(&bufRequest->Head, &bufReply->Head);
if (bufReply->RetCode != KERN_SUCCESS) {
if (bufReply->RetCode == MIG_NO_REPLY)
goto get_request;
/* don't destroy the reply port right,
so we can send an error message */
bufRequest->Head.msgh_remote_port = MACH_PORT_NULL;
mach_msg_destroy(&bufRequest->Head);
}
if (bufReply->Head.msgh_remote_port == MACH_PORT_NULL) {
/* no reply port, so destroy the reply */
if (bufReply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX)
mach_msg_destroy(&bufReply->Head);
goto get_request;
}
/* send reply and get next request */
bufTemp = bufRequest;
bufRequest = bufReply;
bufReply = bufTemp;
mr = mach_msg(&bufRequest->Head, MACH_SEND_MSG|MACH_RCV_MSG,
bufRequest->Head.msgh_size, max_size, rcv_name,
MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
}
/* a message error occurred */
if (mr != MACH_SEND_INVALID_DEST)
break;
/* the reply can't be delivered, so destroy it */
mach_msg_destroy(&bufRequest->Head);
}
free((char *) bufRequest);
free((char *) bufReply);
return mr;
}
oid
mach_msg_destroy_port(port, type)
mach_port_t port;
mach_msg_type_name_t type;
{
if (MACH_PORT_VALID(port)) switch (type) {
case MACH_MSG_TYPE_PORT_SEND:
case MACH_MSG_TYPE_PORT_SEND_ONCE:
(void) mach_port_deallocate(mach_task_self(), port);
break;
case MA./user/libmach/mach_syscalls.c 444 146 0 13025 4756607732 11622 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: mach_syscalls.c,v $
* Revision 2.6 91/02/14 14:17:54 mrt
* Added new Mach copyright
* [91/02/13 12:44:29 mrt]
*
* Revision 2.5 90/09/09 14:34:31 rpd
* Added mach_port_allocate_name since it didn't exist because of
* the makefile sed.
* [90/09/03 rwd]
*
* Revision 2.4 90/06/19 23:03:50 rpd
* Added mach_port_allocate, mach_port_deallocate, mach_port_insert_right.
* [90/06/02 rpd]
*
* Revision 2.3 90/06/02 15:12:36 rpd
* Try kernel call whenever syscall fails.
* [90/05/31 rpd]
*
* Updated for new IPC.
* Removed vm_allocate_with_pager.
* [90/05/31 rpd]
*
* Revision 2.2 90/05/29 18:40:03 rwd
* New file from rfr to try traps then mig.
* [90/04/20 rwd]
*
*/
#include
#include
kern_return_t task_create(target_task, inherit_memory, child_task)
task_t target_task;
boolean_t inherit_memory;
task_t *child_task;
{
kern_return_t result;
result = syscall_task_create(target_task, inherit_memory, child_task);
if (result != KERN_SUCCESS)
result = mig_task_create(target_task, inherit_memory,
child_task);
return(result);
}
kern_return_t task_terminate(target_task)
task_t target_task;
{
kern_return_t result;
result = syscall_task_terminate(target_task);
if (result != KERN_SUCCESS)
result = mig_task_terminate(target_task);
return(result);
}
kern_return_t task_suspend(target_task)
task_t target_task;
{
kern_return_t result;
result = syscall_task_suspend(target_task);
if (result != KERN_SUCCESS)
result = mig_task_suspend(target_task);
return(result);
}
kern_return_t task_set_special_port(task, which_port, special_port)
task_t task;
int which_port;
mach_port_t special_port;
{
kern_return_t result;
result = syscall_task_set_special_port(task, which_port, special_port);
if (result != KERN_SUCCESS)
result = mig_task_set_special_port(task, which_port,
special_port);
return(result);
}
kern_return_t vm_allocate(target_task, address, size, anywhere)
vm_task_t target_task;
vm_address_t *address;
vm_size_t size;
boolean_t anywhere;
{
kern_return_t result;
result = syscall_vm_allocate(target_task, address, size, anywhere);
if (result != KERN_SUCCESS)
result = mig_vm_allocate(target_task,address, size, anywhere);
return(result);
}
kern_return_t vm_deallocate(target_task, address, size)
vm_task_t target_task;
vm_address_t address;
vm_size_t size;
{
kern_return_t result;
result = syscall_vm_deallocate(target_task, address, size);
if (result != KERN_SUCCESS)
result = mig_vm_deallocate(target_task,address, size);
return(result);
}
kern_return_t vm_map
(target_task, address, size, mask, anywhere, memory_object, offset, copy, cur_protection, max_protection, inheritance)
vm_task_t target_task;
vm_address_t *address;
vm_size_t size;
vm_address_t mask;
boolean_t anywhere;
memory_object_t memory_object;
vm_offset_t offset;
boolean_t copy;
vm_prot_t cur_protection;
vm_prot_t max_protection;
vm_inherit_t inheritance;
{
kern_return_t result;
result = syscall_vm_map(target_task, address, size, mask, anywhere,
memory_object, offset, copy,
cur_protection, max_protection, inheritance);
if (result != KERN_SUCCESS)
result = mig_vm_map(target_task, address, size, mask, anywhere,
memory_object, offset, copy,
cur_protection, max_protection, inheritance);
return(result);
}
kern_return_t
mach_port_allocate(task, right, namep)
task_t task;
mach_port_right_t right;
mach_port_t *namep;
{
kern_return_t kr;
kr = syscall_mach_port_allocate(task, right, namep);
if (kr != KERN_SUCCESS)
kr = mig_mach_port_allocate(task, right, namep);
return kr;
}
kern_return_t
mach_port_allocate_name(task, right, namep)
task_t task;
mach_port_right_t right;
mach_port_t namep;
{
kern_return_t kr;
kr = syscall_mach_port_allocate_name(task, right, namep);
if (kr != KERN_SUCCESS)
kr = mig_mach_port_allocate_name(task, right, namep);
return kr;
}
kern_return_t
mach_port_deallocate(task, name)
task_t task;
mach_port_t name;
{
kern_return_t kr;
kr = syscall_mach_port_deallocate(task, name);
if (kr != KERN_SUCCESS)
kr = mig_mach_port_deallocate(task, name);
return kr;
}
kern_return_t
mach_port_insert_right(task, name, right, rightType)
task_t task;
mach_port_t name;
mach_port_t right;
mach_msg_type_name_t rightType;
{
kern_return_t kr;
kr = syscall_mach_port_insert_right(task, name, right, rightType);
if (kr != KERN_SUCCESS)
kr = mig_mach_port_insert_right(task, name, right, rightType);
return kr;
}
get_task, inherit_memory, child_task);
if (result != KERN_SUCCESS)
result = mig_task_create(target_task, inherit_memory,
child_task);
return(result);
}
kern_return_t task_terminate(target_task)
task_t target_task;
{
kern_return_t result;
result = syscall_task_terminate(target_task);
if (result != KERN_SUCCESS)
result = mig_task_terminate(target_task);
return(result);
}
kern_return_t task_suspend(target_task)
task_t target_task;
{
kern_return_t result;
result = sy./user/libmach/mach_traps.cs 444 146 0 2604 4756607733 11263 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989,1988,1987,1986 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: mach_traps.cs,v $
* Revision 2.3 91/02/14 14:17:58 mrt
* Added new Mach copyright
* [91/02/13 12:45:30 mrt]
*
* Revision 2.2 89/08/04 15:08:51 rwd
* Created. All the work gets done in "syscall_sw.h" now.
* [86/09/01 mwyoung]
*
* Revision 2.1 89/08/04 15:08:34 rwd
* Created.
*
*/
#include
and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE US./user/libmach/i386/ 755 146 0 0 4756613073 7211 ./user/libmach/i386/_setjmp.s 444 146 0 4665 4756607715 11142 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: _setjmp.s,v $
* Revision 2.4 91/02/14 14:17:03 mrt
* Added new Mach copyright
* [91/02/13 14:16:09 mrt]
*
* Revision 2.3 90/06/19 23:03:39 rpd
* Added setjmp, longjmp aliases for _setjmp, _longjmp.
* Changed longjmp to not override a zero return value.
* [90/06/07 rpd]
*
* Revision 2.2 90/05/03 15:53:42 dbg
* Remove call to fpinit. Ensure that _longjmp does not return 0.
* [90/03/15 dbg]
*
* Revision 1.3 89/11/30 19:52:47 kupfer
* Changes for Tahoe and a.out.
*
* Revision 1.2 89/11/16 21:22:02 kupfer
* longjmp should reset the floating point coprocessor.
*/
/*
* C library -- _setjmp, _longjmp
*
* _longjmp(a,v)
* will generate a "return(v)" from
* the last call to
* _setjmp(a)
* by restoring registers from the stack,
* The previous signal state is NOT restored.
*
*/
#include
ENTRY2(setjmp,_setjmp)
movl 4(%esp),%ecx / fetch buffer
movl %ebx,0(%ecx)
movl %esi,4(%ecx)
movl %edi,8(%ecx)
movl %ebp,12(%ecx) / save frame pointer of caller
popl %edx
movl %esp,16(%ecx) / save stack pointer of caller
movl %edx,20(%ecx) / save pc of caller
xorl %eax,%eax
jmp *%edx
ENTRY2(longjmp,_longjmp)
//// call EXT(_fpinit) / reset coprocessor
movl 8(%esp),%eax / return(v)
movl 4(%esp),%ecx / fetch buffer
movl 0(%ecx),%ebx
movl 4(%ecx),%esi
movl 8(%ecx),%edi
movl 12(%ecx),%ebp
movl 16(%ecx),%esp
jmp *20(%ecx)
nd(target_task)
task_t target_task;
{
kern_return_t result;
result = sy./user/libmach/i386/asm.h 444 146 0 7224 4756607716 10241 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: asm.h,v $
* Revision 2.4 91/02/14 14:17:08 mrt
* Added new Mach copyright
* [91/02/13 14:16:17 mrt]
*
* Revision 2.3 90/06/19 23:03:45 rpd
* Added ENTRY2.
* [90/06/07 rpd]
*
* Revision 2.2 90/05/03 15:53:50 dbg
* Created.
* [90/04/30 15:31:24 dbg]
*
* Typo on ENTRY if gprof
* [90/03/29 rvb]
* fix SVC for "ifdef wheeze" [kupfer]
* Fix the GPROF definitions.
* ENTRY(x) gets profiled iffdef GPROF.
* Entry(x) (and DATA(x)) is NEVER profiled.
* MCOUNT can be used by asm that intends to build a frame,
* after the frame is built.
* [90/02/26 rvb]
* Add #define addr16 .byte 0x67
* [90/02/09 rvb]
* Added LBi, SVC and ENTRY
* [89/11/10 09:51:33 rvb]
*
* New a.out and coff compatible .s files.
* [89/10/16 rvb]
*
*/
#define S_ARG0 4(%esp)
#define S_ARG1 8(%esp)
#define S_ARG2 12(%esp)
#define S_ARG3 16(%esp)
#define FRAME pushl %ebp; movl %esp, %ebp
#define EMARF leave
#define B_ARG0 8(%ebp)
#define B_ARG1 12(%ebp)
#define B_ARG2 16(%ebp)
#define B_ARG3 20(%ebp)
#ifdef wheeze
#define ALIGN 4
#define EXT(x) x
#define LCL(x) ./**/x
#define LB(x,n) ./**/x
#define LBb(x,n) ./**/x
#define LBf(x,n) ./**/x
#define SVC lcall $7,$0
#define String .string
#define Value .value
#define Times(a,b) [a\*b]
#define Divide(a,b) [a\\b]
#define INB inb (%dx)
#define OUTB outb (%dx)
#define INL inl (%dx)
#define OUTL outl (%dx)
#else wheeze
#define ALIGN 2
#define EXT(x) _/**/x
#define LCL(x) x
#define LB(x,n) n
#define LBb(x,n) n/**/b
#define LBf(x,n) n/**/f
#define SVC .byte 0x9a; .long 0; .word 0x7
#define String .ascii
#define Value .word
#define Times(a,b) (a*b)
#define Divide(a,b) (a/b)
#define INB inb %dx, %al
#define OUTB outb %al, %dx
#define INL inl %dx, %eax
#define OUTL outl %eax, %dx
#endif wheeze
#define data16 .byte 0x66
#define addr16 .byte 0x67
#ifdef GPROF
#define MCOUNT .data; LB(x, 9): .long 0; .text; lea LBb(x, 9),%edx; call mcount
#define ENTRY(x) .globl EXT(x); .align ALIGN; EXT(x): ; \
pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); .align ALIGN; EXT(x): EXT(y): ; \
pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
#define ASENTRY(x) .globl x; .align ALIGN; x: ; \
pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
#else GPROF
#define MCOUNT
#define ENTRY(x) .globl EXT(x); .align ALIGN; EXT(x):
#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); .align ALIGN; EXT(x): EXT(y):
#define ASENTRY(x) .globl x; .align ALIGN; x:
#endif GPROF
#define Entry(x) .globl EXT(x); .align ALIGN; EXT(x):
#define DATA(x) .globl EXT(x); .align ALIGN; EXT(x):
fy 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 SOFT./user/libmach/i386/bcopy.c 444 146 0 10542 4756607717 10606 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: bcopy.c,v $
* Revision 2.3 91/02/14 14:17:12 mrt
* Picked up BSD Reno version to get the permissive copyright
* and then modified it slightly to work in our environment.
* [91/02/13 mrt]
*
*/
/*-
* 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 are permitted provided
* that: (1) source distributions retain this entire copyright notice and
* comment, and (2) distributions including binaries display the following
* acknowledgement: ``This product includes software developed by the
* University of California, Berkeley and its contributors'' in the
* documentation or other materials provided with the distribution and in
* all advertising materials mentioning features or use of this software.
* 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bcopy.c 5.8 (Berkeley) 6/23/90";
#endif /* LIBC_SCCS and not lint */
/*
* 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.
*/
bcopy(src0, dst0, length)
char *dst0;
const char *src0;
register unsigned int length;
{
register char *dst = dst0;
register const char *src = src0;
register unsigned int t;
if (length == 0 || dst == src) /* nothing to do */
return;
/*
* Macros: loop-t-times; and loop-t-times, t>0
*/
#define TLOOP(s) if (t) TLOOP1(s)
#define TLOOP1(s) do { s; } while (--t)
if ((unsigned long)dst < (unsigned long)src) {
/*
* Copy forward.
*/
t = (int)src; /* only need low bits */
if ((t | (int)dst) & wmask) {
/*
* Try to align operands. This cannot be done
* unless the low bits match.
*/
if ((t ^ (int)dst) & wmask || length < wsize)
t = length;
else
t = wsize - (t & wmask);
length -= t;
TLOOP1(*dst++ = *src++);
}
/*
* Copy whole words, then mop up any trailing bytes.
*/
t = length / wsize;
TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
t = length & wmask;
TLOOP(*dst++ = *src++);
} else {
/*
* Copy backwards. Otherwise essentially the same.
* Alignment works as before, except that it takes
* (t&wmask) bytes to align, not wsize-(t&wmask).
*/
src += length;
dst += length;
t = (int)src;
if ((t | (int)dst) & wmask) {
if ((t ^ (int)dst) & wmask || length <= wsize)
t = length;
else
t &= wmask;
length -= t;
TLOOP1(*--dst = *--src);
}
t = length / wsize;
TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src);
t = length & wmask;
TLOOP(*--dst = *--src);
}
return(0);
}
memcpy(b, a, c)
char *b;
char *a;
unsigned c;
{
bcopy(a, b, c);
}
erived from software contributed to Berkeley by
* Chris Torek.
*
* Redistribution and use in source and binary forms are permitted provided
* that: (1) so./user/libmach/i386/bzero.s 444 146 0 3063 4756607721 10606 /*
* Mach Operating System
* Copyright (c) 1991,1990 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: bzero.s,v $
* Revision 2.3 91/02/14 14:17:19 mrt
* Added new Mach copyright
* [91/02/13 14:16:26 mrt]
*
* Revision 2.2 90/05/03 15:54:09 dbg
* From Bob Baron.
* [90/04/30 dbg]
*
*/
#include
/*
* bzero(char * addr, unsigned int length)
*/
Entry(blkclr)
ENTRY(bzero)
pushl %ebp
movl %esp,%ebp
pushl %edi
movl B_ARG1,%edx
movl B_ARG0,%edi
xorl %eax,%eax
cld
/ zero longs
movl %edx,%ecx
shrl $2,%ecx
rep
stosl
/ zero bytes
movl %edx,%ecx
andl $3,%ecx
rep
stosb
popl %edi
leave
ret
ice and
* comment, and (2) distributions including binaries display the following
* acknowledgement: ``This product includes software developed by the
* University of California, Berkeley and its contributors'' in the
* documentation or other materials provided with the distribution and in
* all advertising materials mentioning features or use of this software.
* Neither the name of the University nor the names of its contributors may
* be used to e./user/libmach/i386/crt0.c 444 146 0 13706 4756607722 10343 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: crt0.c,v $
* Revision 2.5 91/02/14 14:17:23 mrt
* Added new Mach copyright
* [91/02/13 14:16:29 mrt]
*
* Revision 2.4 90/11/05 14:35:42 rpd
* Removed the definition of exit.
* [90/10/30 rpd]
*
* Revision 2.3 90/06/02 14:36:49 rpd
* Converted to new IPC.
* [90/06/02 rpd]
*
* Revision 2.2 90/05/03 15:54:13 dbg
* Fix include of i386/asm.h
* [90/04/30 dbg]
* Created.
* [90/04/30 15:32:17 dbg]
*
*/
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* William Jolitz.
*
* Redistribution and use in source and binary forms are permitted
* provided that: (1) source distributions retain this entire copyright
* notice and comment, and (2) distributions including binaries display
* the following acknowledgement: ``This product includes software
* developed by the University of California, Berkeley and its contributors''
* in the documentation or other materials provided with the distribution
* and in all advertising materials mentioning features or use of this
* software. 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static char sccsid[] = "@(#)crt0.c 5.2 (Berkeley) 5/14/90";
#endif /* not lint */
/*
* C start up routine.
* Robert Henry, UCB, 20 Oct 81
*
* We make the following (true) assumptions:
* 1) when the kernel calls start, it does a jump to location 2,
* and thus avoids the register save mask. We are NOT called
* with a calls! see sys1.c:setregs().
* 2) The only register variable that we can trust is sp,
* which points to the base of the kernel calling frame.
* Do NOT believe the documentation in exec(2) regarding the
* values of fp and ap.
* 3) We can allocate as many register variables as we want,
* and don't have to save them for anybody.
* 4) Because of the ways that asm's work, we can't have
* any automatic variables allocated on the stack, because
* we must catch the value of sp before any automatics are
* allocated.
*/
#include
char **environ = (char **)0;
#ifdef paranoid
static int fd;
#endif paranoid
#if MACH
int (*mach_init_routine)();
int (*_cthread_init_routine)();
int (*_cthread_exit_routine)();
int (*_StrongBox_init_routine)();
int errno = 0;
int exit();
#endif MACH
extern unsigned char etext;
extern unsigned char _eprol;
_start()
{
struct kframe {
int kargc;
char *kargv[1]; /* size depends on kargc */
char kargstr[1]; /* size varies */
char kenvstr[1]; /* size varies */
};
/*
* ALL REGISTER VARIABLES!!!
*/
register int r11; /* needed for init */
register struct kframe *kfp; /* r10 */
register char **targv;
register char **argv;
#ifdef lint
kfp = 0;
initcode = initcode = 0;
#else not lint
#ifdef __wheeze__
asm(" leal 4(%ebp),%edi"); /* catch it quick */
#else __wheeze__
#define Entry_sp() \
({ int _spl__, _tmp1__; \
asm volatile("leal 4(%%ebp), %0" : "=r" (_spl__) : "r" (_tmp1__)); \
_spl__; })
kfp = (struct kframe *)Entry_sp();
#endif __wheeze__
#endif not lint
for (argv = targv = &kfp->kargv[0]; *targv++; /* void */)
/* void */ ;
if (targv >= (char **)(*argv))
--targv;
environ = targv;
#if MACH
if (mach_init_routine)
(void) mach_init_routine();
#endif MACH
asm("__eprol:");
#ifdef paranoid
/*
* The standard I/O library assumes that file descriptors 0, 1, and 2
* are open. If one of these descriptors is closed prior to the start
* of the process, I/O gets very confused. To avoid this problem, we
* insure that the first three file descriptors are open before calling
* main(). Normally this is undefined, as it adds two unnecessary
* system calls.
*/
do {
fd = open("/dev/null", 2);
} while (fd >= 0 && fd < 3);
close(fd);
#endif paranoid
#ifdef MCRT0
monstartup(&_eprol, &etext);
#endif MCRT0
#if MACH
if (_cthread_init_routine) {
int new_sp;
new_sp = (*_cthread_init_routine)();
if (new_sp) {
#ifdef __wheeze__
can't switch stacks - no registers!
#else __wheeze__
asm volatile("movl %0, %%esp" : : "g" (new_sp) );
#endif __wheeze__
}
}
if (_StrongBox_init_routine) (*_StrongBox_init_routine)();
(* (_cthread_exit_routine ? _cthread_exit_routine : exit))
(main(kfp->kargc, argv, targv));
#else MACH
exit(main(kfp->kargc, argv, environ));
#endif MACH
}
#ifdef MCRT0
/*ARGSUSED*/
exit(code)
register int code; /* r11 */
{
monitor(0);
_cleanup();
_exit(code);
}
#endif MCRT0
#ifdef CRT0
/*
* null mcount and moncontrol,
* just in case some routine is compiled for profiling
*/
moncontrol(val)
int val;
{
}
asm(" .globl _mcount");
asm("_mcount: ret");
#endif CRT0
NCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF./user/libmach/i386/gcc.s 444 146 0 3060 4756607723 10220 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: gcc.s,v $
* Revision 2.3 91/02/14 14:17:26 mrt
* Added new Mach copyright
* [91/02/13 14:16:34 mrt]
*
* Revision 2.2 90/05/03 15:54:17 dbg
* Created.
* [90/04/30 15:32:32 dbg]
*
* Replacement for gnulib calls made from kernel.
* [89/12/21 17:58:40 rvb]
*
* 20-Dec-89 Robert Baron (rvb) at Carnegie-Mellon University
* Created.
*/
#include
ENTRY(__divsi3)
movl 4(%esp), %eax
cdq
idivl 8(%esp), %eax
ret
ENTRY(__udivsi3)
movl 4(%esp), %eax
xorl %edx, %edx
divl 8(%esp), %eax
ret
LAIMS 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 [email protected]
* 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.
*/
/./user/libmach/mig_strncpy.c 444 146 0 3677 4756607733 11330 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: mig_strncpy.c,v $
* Revision 2.2 91/02/14 14:18:02 mrt
* Added new Mach copyright
* [91/02/13 12:44:34 mrt]
*
* Revision 2.1 89/08/03 17:06:47 rwd
* Created.
*
* Revision 2.1 89/05/09 22:06:06 mrt
* Created.
*
*/
/*
* mig_strncpy.c - by Joshua Block
*
* mig_strncp -- Bounded string copy. Does what the library routine strncpy
* OUGHT to do: Copies the (null terminated) string in src into dest, a
* buffer of length len. Assures that the copy is still null terminated
* and doesn't overflow the buffer, truncating the copy if necessary.
*
* Parameters:
*
* dest - Pointer to destination buffer.
*
* src - Pointer to source string.
*
* len - Length of destination buffer.
*/
void mig_strncpy(dest, src, len)
char *dest, *src;
int len;
{
int i;
if (len <= 0)
return;
for (i=1; i
return;
*dest = '\0';
return;
}
_routine) (*_StrongBox_init_routine)();
(* (_cthread_exit_routin./user/libmach/mig_support.c 444 146 0 5527 4756607734 11337 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: mig_support.c,v $
* Revision 2.3 91/02/14 14:18:05 mrt
* Added new Mach copyright
* [91/02/13 12:44:38 mrt]
*
* Revision 2.2 90/06/02 15:12:42 rpd
* Converted to new IPC.
* [90/03/26 23:27:00 rpd]
*
* Revision 2.1 89/08/03 17:05:48 rwd
* Created.
*
* 31-Aug-88 David Golub (dbg) at Carnegie-Mellon University
* Standalone version - no stdio assumed.
*
*
* 12-May-88 Mary Thompson (mrt) at Carnegie Mellon
* included mach_error.h to remove lint
* 30-Jul-87 Mary Thompson (mrt) at Carnegie Mellon
* started
*/
/*
* Abstract:
* Routines to set and deallocate the mig reply port.
* They are called from mig generated interfaces.
*
*/
#include
static mach_port_t mig_reply_port = MACH_PORT_NULL;
/*****************************************************
* Called by mach_init. This is necessary after
* a fork to get rid of bogus port number.
****************************************************/
void mig_init(first)
int first;
{
if (first == 0)
mig_reply_port = MACH_PORT_NULL;
}
/********************************************************
* Called by mig interfaces whenever they need a reply port.
* Used to provide the same interface as multi-threaded tasks need.
********************************************************/
mach_port_t
mig_get_reply_port()
{
if (mig_reply_port == MACH_PORT_NULL)
mig_reply_port = mach_reply_port();
return mig_reply_port;
}
/*************************************************************
* Called by mig interfaces after a timeout on the port.
* Could be called by user.
***********************************************************/
void
mig_dealloc_reply_port()
{
mach_port_t port;
port = mig_reply_port;
mig_reply_port = MACH_PORT_NULL;
(void) mach_port_mod_refs(mach_task_self(), port,
MACH_PORT_RIGHT_RECEIVE, -1);
}
ds the register save mask. We are NOT called
* with a calls! see sys1.c:setregs().
* 2) The only register variable that we can trust is sp,
* which points to the ba./user/libmach/msg.c 444 146 0 6312 4756607744 7547 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: msg.c,v $
* Revision 2.3 91/02/14 14:18:33 mrt
* Added new Mach copyright
* [91/02/13 12:44:42 mrt]
*
* Revision 2.2 90/06/02 15:13:01 rpd
* Converted to new IPC.
* [90/03/26 23:28:31 rpd]
*
* Revision 2.1 89/08/03 17:05:52 rwd
* Created.
*
* 21-Oct-88 Richard Draves (rpd) at Carnegie-Mellon University
* Added msg_send wrapper, which handles SEND_INTERRUPT.
* Fixed bug in msg_rpc wrapper; it gave the wrong size to msg_receive_.
* Converted to first try the new *_trap calls and fall back on
* the (renamed) *_old calls if they don't work.
*
* 19-May-87 Mary Thompson (mrt) at Carnegie-Mellon University
* Fixed the test for interupts in msg_rpc_.
* (Copied from mwyoung's version.)
*/
#include
#include
mach_msg_return_t
mach_msg(msg, option, send_size, rcv_size, rcv_name, timeout, notify)
mach_msg_header_t *msg;
mach_msg_option_t option;
mach_msg_size_t send_size;
mach_msg_size_t rcv_size;
mach_port_t rcv_name;
mach_msg_timeout_t timeout;
mach_port_t notify;
{
mach_msg_return_t mr;
/*
* Consider the following cases:
* 1) Errors in pseudo-receive (eg, MACH_SEND_INTERRUPTED
* plus special bits).
* 2) Use of MACH_SEND_INTERRUPT/MACH_RCV_INTERRUPT options.
* 3) RPC calls with interruptions in one/both halves.
*/
mr = mach_msg_trap(msg, option, send_size, rcv_size, rcv_name,
timeout, notify);
if (mr == MACH_MSG_SUCCESS)
return MACH_MSG_SUCCESS;
if ((option & MACH_SEND_INTERRUPT) == 0)
while (mr == MACH_SEND_INTERRUPTED)
mr = mach_msg_trap(msg, option,
send_size, rcv_size, rcv_name,
timeout, notify);
if ((option & MACH_RCV_INTERRUPT) == 0)
while (mr == MACH_RCV_INTERRUPTED)
mr = mach_msg_trap(msg, option &~ MACH_SEND_MSG,
0, rcv_size, rcv_name,
timeout, notify);
return mr;
}
mach_msg_return_t
mach_msg_send(msg)
mach_msg_header_t *msg;
{
return mach_msg(msg, MACH_SEND_MSG,
msg->msgh_size, 0, MACH_PORT_NULL,
MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
}
mach_msg_return_t
mach_msg_receive(msg)
mach_msg_header_t *msg;
{
return mach_msg(msg, MACH_RCV_MSG,
0, msg->msgh_size, msg->msgh_local_port,
MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
}
mig_reply_port;
mig_reply_port = MACH_PORT_NULL;
(void) mach_port_mod_refs(mach_task_self(), port,
MACH_PORT_RIGHT_RECEIVE, -1);
}
ds the register save mask. We are NOT called
* with a calls! see sys1.c:setregs().
* 2) The only register variable that we can trust is sp,
* which points to the ba./user/libmach/printf.c 444 146 0 22000 4756607745 10274 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989,1988 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: printf.c,v $
* Revision 2.3 91/02/14 14:18:37 mrt
* Added new Mach copyright
* [91/02/13 12:44:48 mrt]
*
* Revision 2.2 89/11/29 14:18:47 af
* Characters are passed as ints, on Mips %c broke.
* [89/10/28 10:28:25 af]
*
* Revision 2.1 89/08/03 17:05:57 rwd
* Created.
*
* 8-Aug-88 David Golub (dbg) at Carnegie-Mellon University
* Converted for MACH kernel use. Removed %r, %R, %b; added %b
* from Berkeley's kernel to print bit fields in device registers;
* changed to use varargs.
*
*/
/*
* Common code for printf et al.
*
* The calling routine typically takes a variable number of arguments,
* and passes the address of the first one. This implementation
* assumes a straightforward, stack implementation, aligned to the
* machine's wordsize. Increasing addresses are assumed to point to
* successive arguments (left-to-right), as is the case for a machine
* with a downward-growing stack with arguments pushed right-to-left.
*
* To write, for example, fprintf() using this routine, the code
*
* fprintf(fd, format, args)
* FILE *fd;
* char *format;
* {
* _doprnt(format, &args, fd);
* }
*
* would suffice. (This example does not handle the fprintf's "return
* value" correctly, but who looks at the return value of fprintf
* anyway?)
*
* This version implements the following printf features:
*
* %d decimal conversion
* %u unsigned conversion
* %x hexadecimal conversion
* %X hexadecimal conversion with capital letters
* %o octal conversion
* %c character
* %s string
* %m.n field width, precision
* %-m.n left adjustment
* %0m.n zero-padding
* %*.* width and precision taken from arguments
*
* This version does not implement %f, %e, or %g. It accepts, but
* ignores, an `l' as in %ld, %lo, %lx, and %lu, and therefore will not
* work correctly on machines for which sizeof(long) != sizeof(int).
* It does not even parse %D, %O, or %U; you should be using %ld, %o and
* %lu if you mean long conversion.
*
* This version implements the following nonstandard features:
*
* %b binary conversion
* %r roman numeral conversion
* %R roman numeral conversion with capital letters
*
* As mentioned, this version does not return any reasonable value.
*
* Permission is granted to use, modify, or propagate this code as
* long as this notice is incorporated.
*
* Steve Summit 3/25/87
*/
/*
* Added formats for decoding device registers:
*
* printf("reg = %b", regval, "
*
* where
* i.e. '\10' gives octal, '\20' gives hex. Each
* characters, the first of which gives the bit number to be inspected
* (origin 1), and the rest (up to a control character (<= 32)) give the
* name of the register. Thus
* printf("reg = %b\n", 3, "\10\2BITTWO\1BITONE")
* would produce
* reg = 3
*
* If the second character in
* indicates the last bit of a bit field. In this case, printf will extract
* bits <1> to <2> and print it. Characters following the second control
* character are printed before the bit field.
* printf("reg = %b\n", 0xb, "\10\4\3FIELD1=\2BITTWO\1BITONE")
* would produce
* reg = b
*/
#include
#include
#define isdigit(d) ((d) >= '0' && (d) <= '9')
#define Ctod(c) ((c) - '0')
#define MAXBUF (sizeof(long int) * 8) /* enough for binary */
_doprnt(fmt, argp, fd)
register char *fmt;
va_list *argp;
char *fd; /* generic pointer for output */
{
register char *p;
char *p2;
int length;
int prec;
int ladjust;
char padc;
int n;
unsigned int u;
int base;
int negflag;
char *s;
int i, any;
char c;
while (*fmt != '\0') {
if (*fmt != '%') {
putchar(*fmt++, fd);
continue;
}
fmt++;
if (*fmt == 'l')
fmt++; /* need to use it if sizeof(int) < sizeof(long) */
length = 0;
prec = -1;
ladjust = FALSE;
padc = ' ';
if (*fmt == '-') {
ladjust = TRUE;
fmt++;
}
if (*fmt == '0') {
padc = '0';
fmt++;
}
if (isdigit(*fmt)) {
while(isdigit(*fmt))
length = 10 * length + Ctod(*fmt++);
}
else if (*fmt == '*') {
length = va_arg(*argp, int);
fmt++;
if (length < 0) {
ladjust = !ladjust;
length = -length;
}
}
if (*fmt == '.') {
fmt++;
if (isdigit(*fmt)) {
prec = 0;
while(isdigit(*fmt))
prec = 10 * prec + Ctod(*fmt++);
}
else if (*fmt == '*') {
prec = va_arg(*argp, int);
fmt++;
}
}
negflag = FALSE;
switch(*fmt) {
case 'b':
case 'B':
u = va_arg(*argp, unsigned int);
p = va_arg(*argp, char *);
base = *p++;
printnum(u, base, FALSE, 0, FALSE, ' ', fd);
if (u == 0)
break;
any = FALSE;
while (i = *p++) {
if (*p <= 32) {
/*
* Bit field
*/
register int j;
if (any)
putchar(',', fd);
else {
putchar('<', fd);
any = TRUE;
}
j = *p++;
for (; (c = *p) > 32; p++)
putchar(c, fd);
printnum((unsigned)( (u>>(j-1)) & ((2<<(i-j))-1)),
base, FALSE, 0, FALSE, ' ', fd);
}
else if (u & (1<<(i-1))) {
if (any)
putchar(',', fd);
else {
putchar('<', fd);
any = TRUE;
}
for (; (c = *p) > 32; p++)
putchar(c, fd);
}
else {
for (; *p > 32; p++)
continue;
}
}
if (any)
putchar('>', fd);
break;
case 'c':
c = va_arg(*argp, int);
putchar(c, fd);
break;
case 'd':
case 'D':
n = va_arg(*argp, int);
if (n >= 0)
u = n;
else {
u = -n;
negflag = TRUE;
}
printnum(u, 10, negflag, length, ladjust, padc, fd);
break;
case 'o':
case 'O':
u = va_arg(*argp, unsigned int);
printnum(u, 8, FALSE, length, ladjust, padc, fd);
break;
case 's':
p = va_arg(*argp, char *);
if (p == (char *)0)
p = "(NULL)";
if (length > 0 && !ladjust) {
n = 0;
p2 = p;
for (; *p != '\0' && (prec == -1 || n < prec); p++)
n++;
p = p2;
while (n < length) {
putchar(' ', fd);
n++;
}
}
n = 0;
while (*p != '\0') {
if (++n > prec && prec != -1)
break;
putchar(*p++, fd);
}
if (n < length && ladjust) {
while (n < length) {
putchar(' ', fd);
n++;
}
}
break;
case 'u':
case 'U':
u = va_arg(*argp, unsigned int);
printnum(u, 10, FALSE, length, ladjust, padc, fd);
break;
case 'x':
u = va_arg(*argp, unsigned int);
printnum(u, 16, FALSE, length, ladjust, padc, fd);
break;
case '\0':
fmt--;
break;
default:
putchar(*fmt, fd);
}
fmt++;
}
}
printnum(u, base, negflag, length, ladjust, padc, fd)
register unsigned int u; /* number to print */
register int base;
boolean_t negflag;
register int length;
boolean_t ladjust;
char padc;
char * fd;
{
char buf[MAXBUF]; /* build number here */
register char * p = &buf[MAXBUF-1];
register int size;
static char digs[] = "0123456789abcdef";
do {
*p-- = digs[u % base];
u /= base;
} while (u != 0);
if (negflag)
putchar('-', fd);
size = &buf[MAXBUF - 1] - p;
if (size < length && !ladjust) {
while (length > size) {
putchar(padc, fd);
length--;
}
}
while (++p != &buf[MAXBUF])
putchar(*p, fd);
if (size < length) {
/* must be ladjust */
while (length > size) {
putchar(padc, fd);
length--;
}
}
}
/*
* Printing (to console)
*/
/*VARARGS1*/
printf(fmt, va_alist)
char * fmt;
va_dcl
{
va_list listp;
va_start(listp);
_doprnt(fmt, &listp, (char *)0);
va_end(listp);
}
/*VARARGS2*/
char *
sprintf_x(s, fmt, va_alist)
char * s; /* output string */
char * fmt;
va_dcl
{
va_list listp;
va_start(listp);
_doprnt(fmt, &listp, s);
va_end(listp);
*s = 0;
return (s);
}
/*
* Output routine.
*/
putchar(c, fd)
char c; /* character to output */
char *fd; /* output parameter */
{
*fd++ = c;
}
./user/libmach/setjmp.h 444 146 0 5776 4756607746 10307 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: setjmp.h,v $
* Revision 2.5 91/02/14 14:18:43 mrt
* Added new Mach copyright
* [91/02/13 12:44:53 mrt]
*
* Revision 2.4 90/11/05 14:36:03 rpd
* Changed the mips jmp_buf definition to the normal size.
* [90/10/30 rpd]
*
* Revision 2.3 90/05/03 15:54:23 dbg
* Add i386 definitions.
* [90/02/05 dbg]
*
* Revision 2.2 89/11/29 14:18:52 af
* Added mips defs. This file is only ok for standalone Mach use,
* not inside U*x.
* [89/10/28 10:23:02 af]
*
* Revision 2.1 89/08/03 17:06:57 rwd
* Created.
*
* Revision 2.3 88/12/22 17:06:02 mja
* Correct __STDC__ return value type and allow for recursive inclusion.
* [88/12/20 dld]
*
* Revision 2.2 88/12/14 23:34:14 mja
* Added ANSI-C (and C++) compatible argument declarations.
* [88/01/18 [email protected]]
*
* 3-Sep-87 Michael Jones (mbj) at Carnegie-Mellon University
* Added definition of jump buffer for Multimax.
*
* 29-May-87 Robert Baron (rvb) at Carnegie-Mellon University
* ns32000 jmp_buf for sequent and possibly mmax
*
* 17-Nov-86 Jonathan Chew (jjc) at Carnegie-Mellon University
* Added defintion of jump buffer for SUN.
*
* 22-Sep-86 Glenn Marcy (gm0w) at Carnegie-Mellon University
* Added changes for IBM RT.
*
*/
/* setjmp.h 4.1 83/05/03 */
#ifndef _SETJMP_H_PROCESSED_
#define _SETJMP_H_PROCESSED_ 1
#ifdef multimax
typedef int jmp_buf[10];
#endif /* multimax */
#ifdef balance
typedef int jmp_buf[11]; /* 4 regs, ... */
#endif /* balance */
#ifdef sun3
typedef int jmp_buf[15]; /* pc, sigmask, onsstack, d2-7, a2-7 */
#endif
#ifdef ibmrt
typedef int jmp_buf[16];
#endif
#ifdef vax
typedef int jmp_buf[10];
#endif
#ifdef mips
typedef int jmp_buf[75];
#endif mips
#ifdef i386
typedef int jmp_buf[21];
#endif i386
#if defined(CMUCS) && defined(__STDC__)
extern int setjmp (jmp_buf);
extern void longjmp (jmp_buf, int);
extern int _setjmp (jmp_buf);
extern void _longjmp (jmp_buf, int);
#endif
#endif /* _SETJMP_H_PROCESSED_ */
, ./user/libmach/strcat.c 444 146 0 4635 4756607747 10272 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: strcat.c,v $
* Revision 2.2 91/02/14 14:18:47 mrt
* Added new Mach copyright
* [91/02/13 12:44:57 mrt]
*
*/
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted provided
* that: (1) source distributions retain this entire copyright notice and
* comment, and (2) distributions including binaries display the following
* acknowledgement: ``This product includes software developed by the
* University of California, Berkeley and its contributors'' in the
* documentation or other materials provided with the distribution and in
* all advertising materials mentioning features or use of this software.
* 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#)string.h 5.4 (Berkeley) 5/29/90
*/
/*
* Concatenate s2 on the end of s1. S1's space must be large enough.
* Return s1.
*/
char *
strcat(s1, s2)
register char *s1, *s2;
{
register char *os1;
os1 = s1;
while (*s1++)
;
--s1;
while (*s1++ = *s2++)
;
return(os1);
}
ypedef int jmp_buf[10];
#endif /* multimax */
#ifdef balance
typedef int jmp_buf[11]; /* 4 regs, .../user/libmach/strcmp.c 444 146 0 2506 4756607747 10275 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: strcmp.c,v $
* Revision 2.2 91/02/14 14:18:50 mrt
* Added new Mach copyright
* [91/02/13 12:45:03 mrt]
*
*/
/*
* Compare strings: s1>s2: >0 s1==s2: 0 s1
strcmp(s1, s2)
register char *s1, *s2;
{
while (*s1 == *s2++)
if (*s1++=='\0')
return(0);
return(*s1 - *--s2);
}
nce
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
/./user/libmach/strcpy.c 444 146 0 2524 4756607750 10303 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: strcpy.c,v $
* Revision 2.2 91/02/14 14:18:53 mrt
* Added new Mach copyright
* [91/02/13 12:45:08 mrt]
*
*/
/*
* Copy string s2 to s1. s1 must be large enough.
* return s1
*/
char *
strcpy(s1, s2)
register char *s1, *s2;
{
register char *os1;
os1 = s1;
while (*s1++ = *s2++)
;
return(os1);
}
stributions retain this entire copyright notice and
* comment, and (2) distributions including binaries display the following
* acknowledgement: ``This product includes ./user/libmach/strings.h 444 146 0 2555 4756607751 10462 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: strings.h,v $
* Revision 2.2 91/02/14 14:18:57 mrt
* Added new Mach copyright
* [91/02/13 12:45:12 mrt]
*
*/
/*
* External function definitions
* for routines described in string(3).
*/
char *strcat();
char *strncat();
int strcmp();
int strncmp();
char *strcpy();
char *strncpy();
int strlen();
char *index();
char *rindex();
Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
/./user/libmach/strlen.c 444 146 0 2456 4756607752 10274 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: strlen.c,v $
* Revision 2.2 91/02/14 14:19:03 mrt
* Added new Mach copyright
* [91/02/13 12:45:15 mrt]
*
*/
/*
* Returns the number of
* non-NULL bytes in string argument.
*/
strlen(s)
register char *s;
{
register n;
n = 0;
while (*s++)
n++;
return(n);
}
e (*s1++ = *s2++)
;
return(os1);
}
stributions retain this entire copyright notice and
* comment, and (2) distributions including binaries display the following
* acknowledgement: ``This product includes ./user/libmach/strncpy.c 444 146 0 2720 4756607753 10462 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: strncpy.c,v $
* Revision 2.2 91/02/14 14:19:07 mrt
* Added new Mach copyright
* [91/02/13 12:45:18 mrt]
*
*/
/*
* Copy s2 to s1, truncating or null-padding to always copy n bytes
* return s1
*/
char *
strncpy(s1, s2, n)
register char *s1, *s2;
{
register i;
register char *os1;
os1 = s1;
for (i = 0; i < n; i++)
if ((*s1++ = *s2++) == '\0') {
while (++i < n)
*s1++ = '\0';
return(os1);
}
return(os1);
}
e
* rights to redistribute these changes.
*/
/./user/libmach/varargs.h 444 146 0 6257 4756607754 10444 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989,1988 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: varargs.h,v $
* Revision 2.3 91/02/14 14:19:10 mrt
* Added new Mach copyright
* [91/02/13 12:45:21 mrt]
*
* Revision 2.2 90/08/06 15:09:08 rwd
* Added i386 case.
*
* RCS-ed, added mips case. Mips also needs it in Mach standalone
* programs.
* [89/10/28 af]
*
* Revision 2.1 89/10/28 10:48:05 af
* Created.
*
*
*/
#if defined(vax) || defined(sun3) || defined(mips) || defined(i386)
#define va_dcl int va_alist;
typedef char * va_list;
#define va_start(pvar) (pvar) = (va_list)&va_alist
#define va_end(pvar)
#ifdef mips
# define va_arg(pvar, type) ((type *)(pvar = \
(va_list) (sizeof(type) > 4 ? ((int)pvar + 2*8 - 1) & -8 \
: ((int)pvar + 2*4 - 1) & -4)))[-1]
#else mips
#define va_arg(pvar,type) ( \
(pvar) += ((sizeof(type)+3) & ~0x3), \
*((type *)((pvar) - ((sizeof(type)+3) & ~0x3))) )
#endif mips
#endif /* vax */
/*
* Try to make varargs work for the Multimax so that _doprnt can be
* declared as
* _doprnt(file, fmt, list)
* FILE *file;
* char *fmt;
* va_list *list;
* and use
*
* n = va_arg(*list, type)
*
* without needing to drag in extra declarations
*
* and printf becomes
*
* printf(fmt, va_alist)
* char *fmt;
* va_dcl
* {
* va_list listp;
* va_start(listp);
* _doprnt((FILE *)0, fmt, &listp);
* va_end(listp);
* }
*/
#if defined(multimax) && defined(KERNEL)
/*
* the vararglist pointer is an elaborate structure (ecch)
*/
typedef struct va_list {
char *va_item; /* current item */
int *va_ptr1, /* arglist pointers for 1, 2, n */
*va_ptr2,
*va_ptrn;
int va_ct; /* current argument number */
} va_list;
#define va_alist va_arg1, va_arg2, va_argn
#define va_dcl int va_arg1, va_arg2, va_argn;
#define va_start(pvar) ( \
(pvar).va_ptr1 = &va_arg1, \
(pvar).va_ptr2 = &va_arg2, \
(pvar).va_ptrn = &va_argn, \
(pvar).va_ct = 0 )
#define va_end(pvar)
#define va_arg(pvar, type) ( \
(pvar).va_ct++, \
(pvar).va_item = (char *) \
( ((pvar).va_ct == 1) \
? (pvar).va_ptr1 \
: ((pvar).va_ct == 2) \
? (pvar).va_ptr2 \
: (pvar).va_ptrn++ ) , \
*((type *)((pvar).va_item)) )
/* what a mess! */
#endif /* defined(multimax) && defined(KERNEL) */
lon requests users of this software to return to
*
* Software Distribution Coordinator or [email protected]
* 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.
./user/libmach/i386_mach 755 146 0 0 4754031730 10546 2i386 ./user/Makeconf 444 146 0 2232 4640223432 6635 # Mach Operating System
# Copyright (c) 1989 Carnegie-Mellon University
# All rights reserved. The CMU software License Agreement specifies
# the terms and conditions for use and redistribution.
#
#
# HISTORY
# $Log: Makeconf,v $
# Revision 2.5 90/06/02 15:12:13 rpd
# Export munged PATH and LPATH, to use released mig.
# [90/03/26 23:24:50 rpd]
#
# Revision 2.4 89/10/16 15:22:39 rwd
# Changed references to MAKECONF
# [89/10/05 rwd]
#
# Revision 2.3 89/08/05 16:10:36 rwd
# Fix BCSBBASE reference
# [89/08/05 11:49:14 rwd]
#
# MAke CPATH relative.
# [89/08/04 20:38:49 rwd]
#
# Revision 2.2 89/08/04 15:06:30 rwd
# Fixed VPATH
#
#
OBJECTDIR=$(MAKECONF:h)/../../../obj/@sys/${BCSBBASE?$(BCSBBASE:t):latest}/user
VPATH=.:machine:$(MAKECONF:h)/../kernel
# Clear out CPATH to avoid old definitions.
# Use release PATH, LPATH to get released Mig.
CPATH=.:$(MAKECONF:h)/../../../release/@sys/${BCSBBASE?$(BCSBBASE:t):latest}/include
PATH=$(MAKECONF:h)/../../../release/@sys/${BCSBBASE?$(BCSBBASE:t):latest}/bin:$(PATH)
LPATH=$(MAKECONF:h)/../../../release/@sys/${BCSBBASE?$(BCSBBASE:t):latest}/lib:$(LPATH)
.EXPORT: CPATH PATH LPATH
on 2.2 90/08/06 15:09:08 rwd
* Added i386 case.
*
* RCS-ed, added mips case. Mips also needs it in Mach standalone
* programs.
* [89/10/28 af]
*
* Revision 2.1 89/10/28 10:48:05 af
* Created.
*
*
*/
#if defined(vax) || defined(sun3) || defined(mips) || defined(i386)
#define va_dcl int va_alist;
typedef char * va_list;
./user/Makefile 444 146 0 1305 4516425740 6637 #
# Mach Operating System
# Copyright (c) 1989 Carnegie-Mellon University
# All rights reserved. The CMU software License Agreement specifies
# the terms and conditions for use and redistribution.
#
# HISTORY
# $Log: Makefile,v $
# Revision 2.2 89/10/16 15:22:43 rwd
# Created
# [89/10/06 rwd]
#
#
LIBBASE = $(MAKECONF:h)/../../../release/@sys/${BCSBBASE?$(BCSBBASE:t):latest}/lib
OBJBASE = $(MAKECONF:h)/../../../obj/@sys/${BCSBBASE?$(BCSBBASE:t):latest}/user
install:
-if [ -f $(LIBBASE)/libmach_sa.a ]; then true ; else ln -s $(OBJBASE)/libmach/libmach_sa.a $(LIBBASE) ; fi
-if [ -f $(LIBBASE)/libthreads.a ]; then true ; else ln -s $(OBJBASE)/threads/libthreads.a $(LIBBASE) ; fi
/../obj/@sys/${BCSBBASE?$(BCSBBASE:t):latest}/user
VPATH=.:machine:$(MAKECONF:h)/../kernel
# Clear out CPATH to avoid old definitions.
# Use release PATH, LPATH to get released Mig.
CPATH=.:$(MAKECONF:h)/../../../release/@sys/${BCSBBASE?$(BCSBBASE:t):latest}/include
PATH=$(MAKECONF:h)/../../../release/@sys/${BCSB./user/threads/ 755 146 0 0 4756612402 6546 ./user/threads/Makefile 444 146 0 11044 4756607755 10330 #
# Mach Operating System
# Copyright (c) 1991,1990,1989 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
# 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 [email protected]
# 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.
#
#
# HISTORY
# $Log: Makefile,v $
# Revision 2.13 91/02/14 14:19:15 mrt
# Added new Mach copyright
# [91/02/13 12:41:48 mrt]
#
# Revision 2.12 90/11/05 14:36:32 rpd
# Change MACHINE to TARGET_MACHINE.
# [90/10/29 rwd]
#
# Revision 2.11 90/09/09 14:34:39 rpd
# Remove call.o
# [90/08/24 rwd]
#
# Revision 2.10 90/06/02 15:13:30 rpd
# Compile with -DMACH_IPC_COMPAT=0.
# [90/03/26 23:29:39 rpd]
#
# Revision 2.9 90/05/29 18:40:08 rwd
# Fix PMAX_ASFLAGS.
# [90/05/22 rwd]
#
# Revision 2.8 90/05/03 15:54:28 dbg
# Use -ES switch to preprocess assembler files.
# Not all machines' 'cc' can directly assemble .s files.
# [90/04/23 dbg]
#
# Revision 2.7 90/01/19 14:36:46 rwd
# Added call.o
# [90/01/03 rwd]
#
# Revision 2.6 89/12/08 19:53:01 rwd
# Use ASFLAGS for assembler, the mips one wants to know which
# optimization level the C code was compiled at.
# [89/12/06 af]
#
# Changed CFLAGS to remove -g and add -O
# [89/10/24 rwd]
# Worked over for new merged coroutine-thread version. Removed
# task version.
# [89/10/24 rwd]
#
#
LIB = libthreads.a
COMMONFLAGS = -I. -DMACH_IPC_COMPAT=0
COPTS = -MD $(COMMONFLAGS) $(PROFILE)
CPPFLAGS = ${COPTS}
CFLAGS = -O ${COPTS}
PMAX_ASFLAGS= -O -nocpp
ASFLAGS = ${${TARGET_MACHINE}_ASFLAGS}
I = -c -d -v
# Use the following definition to enable inline expansion.
INLINE = awk -f cthread_inline.awk
# Use the following definition to disable inline expansion.
# INLINE = cat
.SUFFIXES: .c .o
.c.o:
$(CC) $(CFLAGS) -S $*.c
# The Sun assembler requires an input file.
$(MV) $*.s $*.S
$(INLINE) $*.S > $*.s
$(AS) $(ASFLAGS) -o $@ $*.s
$(RM) $(RMFLAGS) $*.s $*.S
SRCS = cprocs.c cthreads.c malloc.c \
mig_support.c stack.c sync.c \
machine/thread.c
OBJS = $(LIB)(cprocs.o) $(LIB)(cthreads.o) $(LIB)(malloc.o) \
$(LIB)(mig_support.o) $(LIB)(stack.o) $(LIB)(sync.o) \
$(LIB)(thread.o) $(LIB)(lock.o) $(LIB)(csw.o)
lib: $(LIB)
include: machine ckdir
mach_install $I cthreads.h $(DSTBASE)/include
machine:
-if [ -d machine ]; then true; else ln -s $(machine) machine; fi
clean:
$(RM) $(RMFLAGS) machine lib*.a Makedep* a.out core errs \
*.d *.s *.S *.o *.BAK *.CKP */*.BAK */*.CKP
#
# Get inline expansion file before we do anything else.
#
.INIT: cthread_inline.awk
cthread_inline.awk: machine/cthread_inline.awk
-if [ -f $@ ]; then chmod 644 $@; else true; fi
cp -p machine/$@ $@
# The following are the "generic" rules,
# parameterized by LIB, IMPL, and PROFILE.
$(LIB): $(OBJS)
$(AR) r$(ARFLAGS) $(LIB) $?
$(RANLIB) $(LIB)
$(RM) $(RMFLAGS) $?
# Avoid complaints from md in case Makedep doesn't exist yet.
touch Makedep
md -m Makedep -d *.d
# Massage dependency file to reflect object files within library.
cp Makedep Makedep.BAK
sed 's/^[^ #$$]*\.o/$$(LIB)(&)/' < Makedep.BAK > Makedep
rm Makedep.BAK
$(LIB)(thread.o): machine/thread.c
$(CC) $(CFLAGS) -c machine/thread.c
$(LIB)(malloc.o): malloc.c
-if [ "$(TARGET_MACHINE)" = IBMRT -a "$(CC)" != /usr/cs/bin/cc ]; then \
$(MAKE) $(MFLAGS) CC=/usr/cs/bin/cc malloc.o ; \
else \
$(CC) $(CFLAGS) -S malloc.c ; \
$(MV) malloc.s malloc.S ; \
$(INLINE) malloc.S > malloc.s ; \
$(AS) $(ASFLAGS) -o malloc.o malloc.s ; \
$(RM) $(RMFLAGS) malloc.s malloc.S ; \
fi
$(LIB)(lock.o): machine/lock.s
$(CC) -ES $(CPPFLAGS) machine/lock.s > $*.as
$(AS) $(ASFLAGS) -o $@ $*.as
$(RM) $(RMFLAGS) $*.as
$(LIB)(csw.o): machine/csw.s
$(CC) -ES $(CPPFLAGS) machine/csw.s > $*.as
$(AS) $(ASFLAGS) -o $@ $*.as
$(RM) $(RMFLAGS) $*.as
-include Makedep
3
typedef int jmp_buf[15]; /* pc, sigmask, onsstack, d2-7, a2-7 */
#endif
#ifdef ibmrt
typedef int jmp_buf[16];
#endif
#ifdef vax
typedef int jmp_buf[10];
#endif
#ifdef mips
typedef int jmp_buf[75];
#endif mips
#ifdef i386
typedef int jmp_buf[21];
#endif i386
#if defined(CMUCS) && defined(__STDC__)
extern int setjmp (jmp_buf);
extern void longjmp (jmp_buf, int);
extern int _setjmp (jmp_buf);
extern void _longjmp (jmp_buf, int);
#endif
#endif /* _SETJMP_H_PROCESSED_ */
, ./user/threads/call.c 444 146 0 3573 4756607756 7740 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: call.c,v $
* Revision 2.3 91/02/14 14:19:20 mrt
* Added new Mach copyright
* [91/02/13 12:40:44 mrt]
*
* Revision 2.2 90/01/19 14:36:50 rwd
* Created. Routines to replace thread_* and cthread_call_on.
* [90/01/03 rwd]
*
*/
#include
#include "cthread_internals.h"
#ifdef THREAD_CALLS
kern_return_t cthread_get_state(thread)
cthread_t thread;
{
cproc_t p = thread->ur;
}
kern_return_t cthread_set_state(thread)
cthread_t thread;
{
cproc_t p = thread->ur;
}
kern_return_t cthread_abort(thread)
cthread_t thread;
{
cproc_t p = thread->ur;
}
kern_return_t cthread_resume(thread)
cthread_t thread;
{
cproc_t p = thread->ur;
}
kern_return_t cthread_suspend(thread)
cthread_t thread;
{
cproc_t p = thread->ur;
}
kern_return_t cthread_call_on(thread)
cthread_t thread;
{
cproc_t p = thread->ur;
}
#endif THREAD_CALLS
]; then chmod 644 $@; else true; fi
cp -p machine/$@ $@
# The following are the "generic" rules,
# parameterized by LIB, IMPL, and./user/threads/cprocs.c 444 146 0 70056 4756607761 10332 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: cprocs.c,v $
* Revision 2.11 91/02/14 14:19:26 mrt
* Added new Mach copyright
* [91/02/13 12:40:50 mrt]
*
* Revision 2.10 90/11/05 14:36:41 rpd
* Added cproc_fork_{prepare,parent,child}.
* [90/11/02 rwd]
*
* Fix for positive stack growth.
* [90/11/01 rwd]
*
* Add spin_lock_t.
* [90/10/31 rwd]
*
* Revision 2.9 90/10/12 13:07:12 rpd
* Fix type
* [90/10/10 15:09:59 rwd]
*
* Comment code.
* [90/10/02 rwd]
*
* Revision 2.8 90/09/09 14:34:44 rpd
* Remove special mutex. Remove thread_calls and debug_mutex
* [90/08/24 rwd]
* Fix up old call to cthread_msg_busy to new format.
* [90/08/22 rwd]
*
* Revision 2.7 90/08/06 15:09:17 rwd
* Fixed arguments to cthread_mach_msg.
* [90/06/26 rwd]
* Add additional STATISTICS.
* [90/06/07 rwd]
*
* Attempt to reduce number of times a cthread is released to to a
* msg_receive by adding min/max instead of single number to
* cthread_msg calls.
* [90/06/06 rwd]
*
* Revision 2.6 90/06/02 15:13:36 rpd
* Converted to new IPC.
* [90/03/20 20:46:16 rpd]
*
* Revision 2.5 90/05/29 18:40:11 rwd
* Don't incr special field until the mutex grab is successful.
* [90/05/09 rwd]
*
* Revision 2.4 90/03/14 21:12:02 rwd
* Added WAIT_DEBUG code for deadlock debugging.
* [90/03/01 rwd]
* Insert cprocs in cproc_list as allocated.
* [90/03/01 10:20:16 rwd]
*
* Revision 2.3 90/01/19 14:36:57 rwd
* Make cthread_msg_busy only release new thread if this is still
* busy. Ie don't release two on back to back calls.
* [90/01/11 rwd]
* Add THREAD_CALL code. Add CPROC_ARUN state.
* [90/01/03 rwd]
* Add new cthread_msg_rpc call
* [89/12/20 rwd]
* Change cproc_self pointer to top of stack. Now need to change
* the stack of the first thread.
* [89/12/12 rwd]
*
* Revision 2.2 89/12/08 19:53:13 rwd
* Added CPROC_CONDWAIT state to deal with lock held
* across mutex_unlock problem.
* [89/11/29 rwd]
* Changed mutexes to not hand off. MUTEX_EXTRA conditional is
* now obsolete.
* [89/11/27 rwd]
*
* Add MUTEX_EXTRA code for extra kernel threads to serve special
* mutexes in time of need.
* [89/11/25 rwd]
* Add MUTEX_SPECIAL and DEBUG_MUTEX code
* [89/11/24 rwd]
* Changed mutex_lock to mutex_lock_solid. Mutex_lock is now a
* macro which tries the spin_lock before making a subroutine call.
* Mutex_unlock is now a macro with mutex_unlock_solid for worst case.
* [89/11/13 rwd]
*
* Rewrite most to merge coroutine and thread implementation.
* New routines are cthread_set_kernel_limit, cthread_kernel_limit,
* cthread_wire, cthread_unwire, and cthread_receive.
* [89/10/23 rwd]
*
* Revision 2.1 89/08/03 17:07:10 rwd
* Created.
*
* 11-Apr-89 David Golub (dbg) at Carnegie-Mellon University
* Made condition_yield loop break if swtch_pri returns TRUE (in
* case we fix it).
*
* 31-Mar-89 David Golub (dbg) at Carnegie-Mellon University
* Change cond_signal, cond_broadcast, and cproc_continue so that
* the condition's spin lock is not held while continuing the
* process.
*
* 16-Jan-89 David Golub (dbg) at Carnegie-Mellon University
* Changes for stand-alone library to run on pure kernel:
* . made IPC_WAIT standard, as calls that are used if IPC_WAIT == 0
* vanished a year ago.
* . Removed (as much as possible) references to stdio or other U*X
* features.
*
*
* 01-Apr-88 Eric Cooper (ecc) at Carnegie Mellon University
* Changed condition_clear(c) to acquire c->lock,
* to serialize after any threads still doing condition_signal(c).
* Suggested by Dan Julin.
*
* 19-Feb-88 Eric Cooper (ecc) at Carnegie Mellon University
* Extended the inline scripts to handle spin_unlock() and mutex_unlock().
*
* 28-Jan-88 David Golub (dbg) at Carnegie Mellon University
* Removed thread_data argument from thread_create
* and converted to new thread_set_state call.
*
* 01-Dec-87 Eric Cooper (ecc) at Carnegie Mellon University
* Added inline expansion for cthread_sp() function.
*
* 21-Aug-87 Eric Cooper (ecc) at Carnegie Mellon University
* Fixed uninitialized reply_port in cproc_alloc() (found by rds).
*
* 14-Aug-87 Eric Cooper (ecc) at Carnegie Mellon University
* Tried using return value of swtch() to guide condition_wait().
* Performance was worse than using a hybrid spin/yield/block
* scheme, so the version using swtch() was commented out.
* Disabled IPC_WAIT in released version.
*
* 13-Aug-87 Eric Cooper (ecc) at Carnegie Mellon University
* Added IPC_WAIT option.
* If defined, thread synchronization (condition_wait() and
* cproc_continue()) are implemented using msg_receive() and
* msg_send() instead of thread_suspend() and thread_resume().
*
* 11-Aug-87 Eric Cooper (ecc) at Carnegie Mellon University
* Moved thread reply port to cproc structure in cthread_internals.h,
* because mig calls are made while cproc is idle (no cthread structure).
* Changed cproc_switch() and cproc_start (COROUTINE implementation)
* to use address of saved context, rather than address of enclosing cproc,
* to eliminate dependency on cproc layout.
*/
/*
* File: cprocs.c
* Author: Eric Cooper, Carnegie Mellon University
* Date: Aug, 1987
*
* Implementation of cprocs (lightweight processes)
* and primitive synchronization operations.
*/
#include
#include "cthread_internals.h"
#include
/*
* C Threads imports:
*/
extern void alloc_stack();
extern void cproc_switch(); /* cproc context switch */
extern void cproc_start_wait(); /* cproc idle thread */
extern int cproc_stack_base(); /* return start of stack */
extern vm_offset_t stack_init();
/*
* Mach imports:
*/
extern boolean_t swtch_pri(); /* force kernel context switch */
/*
* Port_entry's are used by cthread_mach_msg to store information
* about each port/port_set for which it is managing threads
*/
typedef struct port_entry {
struct port_entry *next; /* next port_entry */
mach_port_t port; /* which port/port_set */
struct cthread_queue queue; /* queue of runnable threads for
this port/port_set */
int min; /* minimum number of kernel threads
to be used by this port/port_set */
int max; /* maximum number of kernel threads
to be used by this port/port_set */
int held; /* actual number of kernel threads
currentlt in use */
spin_lock_t lock; /* lock governing all above fields */
} *port_entry_t;
#define PORT_ENTRY_NULL ((port_entry_t) 0)
/* Available to outside for statistics */
int cthread_wait_stack_size = 8192; /* stack size for idle threads */
int cthread_max_kernel_threads = 0; /* max kernel threads */
int cthread_kernel_threads = 0; /* current kernel threads */
private spin_lock_t n_kern_lock = SPIN_LOCK_INITIALIZER;
/* lock for 2 above */
#ifdef STATISTICS
int cthread_ready = 0; /* currently runnable */
int cthread_running = 1; /* currently running */
int cthread_waiting = 0; /* currently waiting */
int cthread_wired = 0; /* currently wired */
private spin_lock_t wired_lock = SPIN_LOCK_INITIALIZER;
/* lock for above */
int cthread_wait_stacks = 0; /* total cthread waiting stacks */
int cthread_waiters = 0; /* total of watiers */
int cthread_wakeup = 0; /* total times woken when starting to
block */
int cthread_blocked = 0; /* total blocked */
int cthread_rnone = 0; /* total times no cthread available
to meet minimum for port_entry */
int cthread_yields = 0; /* total cthread_yields */
int cthread_none = 0; /* total idle wakeups w/o runnable */
int cthread_switches = 0; /* total number of cproc_switches */
int cthread_no_mutex = 0; /* total number times woken to get
mutex and couldn't */
private spin_lock_t mutex_count_lock = SPIN_LOCK_INITIALIZER;
/* lock for above */
#endif STATISTICS
cproc_t cproc_list = NO_CPROC; /* list of all cprocs */
private cproc_list_lock = SPIN_LOCK_INITIALIZER;
/* lock for above */
private int cprocs_started = FALSE; /* initiliazed? */
private struct cthread_queue ready = QUEUE_INITIALIZER;
/* ready queue */
private int ready_count = 0; /* number of ready threads on ready
queue - number of messages sent */
private spin_lock_t ready_lock = SPIN_LOCK_INITIALIZER;
/* lock for 2 above */
private mach_port_t wait_port = MACH_PORT_NULL;
/* port on which idle threads wait */
private int wait_count = 0; /* number of waiters - messages pending
to wake them */
private struct cthread_queue waiters = QUEUE_INITIALIZER;
/* queue of cthreads to run as idle */
private spin_lock_t waiters_lock = SPIN_LOCK_INITIALIZER;
/* lock for 2 above */
private port_entry_t port_list = PORT_ENTRY_NULL;
/* master list of port_entries */
private spin_lock_t port_lock = SPIN_LOCK_INITIALIZER;
/* lock for above queue */
private mach_msg_header_t wakeup_msg; /* prebuilt message used by idle
threads */
/*
* Return current value for max kernel threads
* Note: 0 means no limit
*/
cthread_kernel_limit()
{
return cthread_max_kernel_threads;
}
/*
* Set max number of kernel threads
* Note: This will not currently terminate existing threads
* over maximum.
*/
cthread_set_kernel_limit(n)
int n;
{
cthread_max_kernel_threads = n;
}
/*
* Wire a cthread to its current kernel thread
*/
void cthread_wire()
{
register cproc_t p = cproc_self();
kern_return_t r;
/*
* A wired thread has a port associated with it for all
* of its wait/block cases. We also prebuild a wakeup
* message.
*/
if (p->wired == MACH_PORT_NULL) {
MACH_CALL(mach_port_allocate(mach_task_self(),
MACH_PORT_RIGHT_RECEIVE,
&p->wired), r);
MACH_CALL(mach_port_insert_right(mach_task_self(),
p->wired, p->wired,
MACH_MSG_TYPE_MAKE_SEND), r);
p->msg.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
p->msg.msgh_size = 0; /* initialized in call */
p->msg.msgh_remote_port = p->wired;
p->msg.msgh_local_port = MACH_PORT_NULL;
p->msg.msgh_kind = MACH_MSGH_KIND_NORMAL;
p->msg.msgh_id = 0;
#ifdef STATISTICS
spin_lock(&wired_lock);
cthread_wired++;
spin_unlock(&wired_lock);
#endif STATISTICS
}
}
/*
* Unwire a cthread. Deallocate its wait port.
*/
void cthread_unwire()
{
register cproc_t p = cproc_self();
kern_return_t r;
if (p->wired != MACH_PORT_NULL) {
MACH_CALL(mach_port_mod_refs(mach_task_self(), p->wired,
MACH_PORT_RIGHT_SEND, -1), r);
MACH_CALL(mach_port_mod_refs(mach_task_self(), p->wired,
MACH_PORT_RIGHT_RECEIVE, -1), r);
p->wired = MACH_PORT_NULL;
#ifdef STATISTICS
spin_lock(&wired_lock);
cthread_wired--;
spin_unlock(&wired_lock);
#endif STATISTICS
}
}
private cproc_t
cproc_alloc()
{
register cproc_t p = (cproc_t) malloc(sizeof(struct cproc));
p->incarnation = NO_CTHREAD;
p->reply_port = MACH_PORT_NULL;
spin_lock_init(&p->lock);
p->wired = MACH_PORT_NULL;
p->state = CPROC_RUNNING;
p->busy = 0;
spin_lock(&cproc_list_lock);
p->list = cproc_list;
cproc_list = p;
spin_unlock(&cproc_list_lock);
return p;
}
/*
* Called by cthread_init to set up initial data structures.
*/
vm_offset_t
cproc_init()
{
kern_return_t r;
cproc_t p = cproc_alloc();
cthread_kernel_threads = 1;
MACH_CALL(mach_port_allocate(mach_task_self(),
MACH_PORT_RIGHT_RECEIVE,
&wait_port), r);
MACH_CALL(mach_port_insert_right(mach_task_self(),
wait_port, wait_port,
MACH_MSG_TYPE_MAKE_SEND), r);
wakeup_msg.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
wakeup_msg.msgh_size = 0; /* initialized in call */
wakeup_msg.msgh_remote_port = wait_port;
wakeup_msg.msgh_local_port = MACH_PORT_NULL;
wakeup_msg.msgh_kind = MACH_MSGH_KIND_NORMAL;
wakeup_msg.msgh_id = 0;
cprocs_started = TRUE;
/*
* We pass back the new stack which should be switched to
* by crt0. This guarantess correct size and alignment.
*/
return (stack_init(p));
}
/*
* Insert cproc on ready queue. Make sure it is ready for queue by
* sinking on its lock. Just send message to wired cproc.
*/
private int cproc_ready(p, preq)
register cproc_t p;
register int preq;
{
register cproc_t s=cproc_self();
kern_return_t r;
if (p->wired != MACH_PORT_NULL) {
r = mach_msg(&p->msg, MACH_SEND_MSG,
sizeof p->msg, 0, MACH_PORT_NULL,
MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
#ifdef CHECK_STATUS
if (r != MACH_MSG_SUCCESS) {
mach_error("mach_msg", r);
exit(1);
}
#endif CHECK_STATUS
return TRUE;
}
spin_lock(&p->lock); /* is it ready to be queued? It
can appear on a queue before
being switched from. This lock
is released by cproc_switch as
its last operation. */
if (p->state & CPROC_SWITCHING) {
/*
* We caught it early on. Just set to RUNNING
* and we will save a lot of time.
*/
p->state = (p->state & ~CPROC_SWITCHING) | CPROC_RUNNING;
spin_unlock(&p->lock);
return TRUE;
}
spin_unlock(&p->lock);
spin_lock(&ready_lock);
if (preq) {
cthread_queue_preq(&ready, p);
} else {
cthread_queue_enq(&ready, p);
}
#ifdef STATISTICS
cthread_ready++;
#endif STATISTICS
ready_count++;
if ((s->state & CPROC_CONDWAIT) && !(s->wired)) {
/*
* This is an optimiztion. Don't bother waking anyone to grab
* this guy off the ready queue since my thread will block
* momentarily for the condition wait.
*/
spin_unlock(&ready_lock);
return TRUE;
}
if ((ready_count > 0) && wait_count) {
wait_count--;
ready_count--;
spin_unlock(&ready_lock);
r = mach_msg(&wakeup_msg, MACH_SEND_MSG,
sizeof wakeup_msg, 0, MACH_PORT_NULL,
MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
#ifdef CHECK_STATUS
if (r != MACH_MSG_SUCCESS) {
mach_error("mach_msg", r);
exit(1);
}
#endif CHECK_STATUS
return TRUE;
}
spin_unlock(&ready_lock);
return FALSE;
}
/*
* This is only run on a partial "waiting" stack and called from
* cproc_start_wait
*/
void
cproc_waiting(p)
register cproc_t p;
{
mach_msg_header_t msg;
register cproc_t new;
kern_return_t r;
#ifdef STATISTICS
spin_lock(&ready_lock);
cthread_waiting++;
cthread_waiters++;
spin_unlock(&ready_lock);
#endif STATISTICS
for (;;) {
MACH_CALL(mach_msg(&msg, MACH_RCV_MSG,
0, sizeof msg, wait_port,
MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL), r);
spin_lock(&ready_lock);
cthread_queue_deq(&ready, cproc_t, new);
if (new != NO_CPROC) break;
wait_count++;
ready_count++;
#ifdef STATISTICS
cthread_none++;
#endif STATISTICS
spin_unlock(&ready_lock);
}
#ifdef STATISTICS
cthread_ready--;
cthread_running++;
cthread_waiting--;
#endif STATISTICS
spin_unlock(&ready_lock);
spin_lock(&new->lock);
new->state = CPROC_RUNNING;
spin_unlock(&new->lock);
spin_lock(&waiters_lock);
cthread_queue_enq(&waiters, p);
spin_lock(&p->lock);
spin_unlock(&waiters_lock);
cproc_switch(&p->context,&new->context,&p->lock);
}
/*
* Get a waiter with stack
*
*/
cproc_t
cproc_waiter()
{
register cproc_t waiter;
spin_lock(&waiters_lock);
cthread_queue_deq(&waiters, cproc_t, waiter);
spin_unlock(&waiters_lock);
if (waiter == NO_CPROC) {
vm_address_t base;
kern_return_t r;
#ifdef STATISTICS
spin_lock(&waiters_lock);
cthread_wait_stacks++;
spin_unlock(&waiters_lock);
#endif STATISTICS
waiter = cproc_alloc();
MACH_CALL(vm_allocate(mach_task_self(), &base,
cthread_wait_stack_size, TRUE), r);
waiter->stack_base = base;
waiter->stack_size = cthread_wait_stack_size;
}
return (waiter);
}
/*
* Current cproc is blocked so switch to any ready cprocs, or, if
* none, go into the wait state.
*
* You must hold cproc_self()->lock when called.
*/
cproc_block()
{
register cproc_t waiter, new, p = cproc_self();
register int extra;
if (p->wired != MACH_PORT_NULL) {
mach_msg_header_t msg;
kern_return_t r;
spin_unlock(&p->lock);
MACH_CALL(mach_msg(&msg, MACH_RCV_MSG,
0, sizeof msg, p->wired,
MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL), r);
return;
}
p->state = CPROC_SWITCHING;
spin_unlock(&p->lock);
spin_lock(&ready_lock);
#ifdef STATISTICS
cthread_blocked++;
#endif STATISTICS
cthread_queue_deq(&ready, cproc_t, new);
if (new) {
#ifdef STATISTICS
cthread_ready--;
cthread_switches++;
#endif STATISTICS
ready_count--;
spin_unlock(&ready_lock);
spin_lock(&p->lock);
if (p->state == CPROC_RUNNING) { /* have we been saved */
spin_unlock(&p->lock);
#ifdef STATISTICS
spin_lock(&ready_lock);
cthread_wakeup++;
cthread_switches--;
spin_unlock(&ready_lock);
#endif STATISTICS
cproc_ready(new, 1); /* requeue at head were it was */
} else {
p->state = CPROC_BLOCKED;
spin_lock(&new->lock); /* incase still switching */
new->state = CPROC_RUNNING;
spin_unlock(&new->lock);
cproc_switch(&p->context,&new->context,&p->lock);
}
} else {
wait_count++;
#ifdef STATISTICS
cthread_running--;
#endif STATISTICS
spin_unlock(&ready_lock);
waiter = cproc_waiter();
spin_lock(&p->lock);
if (p->state == CPROC_RUNNING) { /* we have been saved */
spin_unlock(&p->lock);
spin_lock(&ready_lock);
wait_count--;
#ifdef STATISTICS
cthread_running++;
cthread_wakeup++;
#endif STATISTICS
spin_unlock(&ready_lock);
spin_lock(&waiters_lock);
cthread_queue_preq(&waiters, waiter);
spin_unlock(&waiters_lock);
} else {
p->state = CPROC_BLOCKED;
spin_lock(&waiter->lock); /* incase still switching */
spin_unlock(&waiter->lock);
cproc_start_wait(&p->context, waiter,
cproc_stack_base(waiter, sizeof(int)),
&p->lock);
}
}
}
/*
* Implement C threads using MACH threads.
*/
cproc_t
cproc_create()
{
register cproc_t child = cproc_alloc();
register kern_return_t r;
extern void cproc_setup();
extern void cproc_prepare();
extern void cthread_body();
int n;
alloc_stack(child);
spin_lock(&n_kern_lock);
if (cthread_max_kernel_threads == 0 || cthread_kernel_threads < cthread_max_kernel_threads) {
cthread_kernel_threads++;
spin_unlock(&n_kern_lock);
MACH_CALL(thread_create(mach_task_self(), &n), r);
cproc_setup(child, n, cthread_body); /* machine dependent */
MACH_CALL(thread_resume(n), r);
#ifdef STATISTICS
spin_lock(&ready_lock);
cthread_running++;
spin_unlock(&ready_lock);
#endif STATISTICS
} else {
spin_unlock(&n_kern_lock);
child->state = CPROC_BLOCKED;
cproc_prepare(child, &child->context,
cproc_stack_base(child, 0));
cproc_ready(child,0);
}
return child;
}
void
condition_wait(c, m)
register condition_t c;
mutex_t m;
{
register cproc_t p = cproc_self();
p->state = CPROC_CONDWAIT | CPROC_SWITCHING;
spin_lock(&c->lock);
cthread_queue_enq(&c->queue, p);
spin_unlock(&c->lock);
#ifdef WAIT_DEBUG
p->waiting_for = (char *)c;
#endif WAIT_DEBUG
mutex_unlock(m);
spin_lock(&p->lock);
if (p->state & CPROC_SWITCHING) {
cproc_block();
} else {
p->state = CPROC_RUNNING;
spin_unlock(&p->lock);
}
#ifdef WAIT_DEBUG
p->waiting_for = (char *)0;
#endif WAIT_DEBUG
/*
* Re-acquire the mutex and return.
*/
mutex_lock(m);
}
void
cond_signal(c)
register condition_t c;
{
register cproc_t p;
spin_lock(&c->lock);
cthread_queue_deq(&c->queue, cproc_t, p);
spin_unlock(&c->lock);
if (p != NO_CPROC) {
cproc_ready(p,0);
}
}
void
cond_broadcast(c)
register condition_t c;
{
register cproc_t p;
struct cthread_queue blocked_queue;
cthread_queue_init(&blocked_queue);
spin_lock(&c->lock);
for (;;) {
register int old_state;
cthread_queue_deq(&c->queue, cproc_t, p);
if (p == NO_CPROC)
break;
cthread_queue_enq(&blocked_queue, p);
}
spin_unlock(&c->lock);
for(;;) {
cthread_queue_deq(&blocked_queue, cproc_t, p);
if (p == NO_CPROC)
break;
cproc_ready(p,0);
}
}
void
cthread_yield()
{
register cproc_t new, p = cproc_self();
if (p->wired != MACH_PORT_NULL) {
swtch_pri(0);
return;
}
spin_lock(&ready_lock);
#ifdef STATISTICS
cthread_yields++;
#endif STATISTICS
cthread_queue_deq(&ready, cproc_t, new);
if (new) {
cthread_queue_enq(&ready, p);
spin_lock(&p->lock);
p->state = CPROC_BLOCKED;
spin_unlock(&ready_lock);
spin_lock(&new->lock);
new->state = CPROC_RUNNING;
spin_unlock(&new->lock);
cproc_switch(&p->context,&new->context,&p->lock);
} else {
spin_unlock(&ready_lock);
swtch_pri(0);
}
}
/*
* Mutex objects.
*/
void
mutex_lock_solid(m)
register mutex_t m;
{
register cproc_t p = cproc_self();
register int queued;
register int tried = 0;
#ifdef WAIT_DEBUG
p->waiting_for = (char *)m;
#endif WAIT_DEBUG
while (1) {
spin_lock(&m->lock);
if (cthread_queue_head(&m->queue, cproc_t) == NO_CPROC) {
cthread_queue_enq(&m->queue, p);
queued = 1;
} else {
queued = 0;
}
if (spin_try_lock(&m->held)) {
if (queued) cthread_queue_deq(&m->queue, cproc_t, p);
spin_unlock(&m->lock);
#ifdef WAIT_DEBUG
p->waiting_for = (char *)0;
#endif WAIT_DEBUG
return;
} else {
if (!queued) cthread_queue_enq(&m->queue, p);
spin_lock(&p->lock);
spin_unlock(&m->lock);
cproc_block();
if (spin_try_lock(&m->held)) {
#ifdef WAIT_DEBUG
p->waiting_for = (char *)0;
#endif WAIT_DEBUG
return;
}
#ifdef STATISTICS
spin_lock(&mutex_count_lock);
cthread_no_mutex++;
spin_unlock(&mutex_count_lock);
#endif STATISTICS
}
}
}
void
mutex_unlock_solid(m)
register mutex_t m;
{
register cproc_t new;
if (!spin_try_lock(&m->held))
return;
spin_lock(&m->lock);
cthread_queue_deq(&m->queue, cproc_t, new);
spin_unlock(&m->held);
spin_unlock(&m->lock);
if (new) {
cproc_ready(new,0);
}
}
/*
* Use instead of mach_msg in a multi-threaded server so as not
* to tie up excessive kernel threads. This uses a simple linked list for
* ports since this should never be more than a few.
*/
/*
* A cthread holds a reference to a port_entry even after it receives a
* message. This reference is not released until the thread does a
* cthread_msg_busy. This allows the fast case of a single mach_msg
* call to occur as often as is possible.
*/
private port_entry_t get_port_entry(port, min, max)
mach_port_t port;
{
register port_entry_t i;
spin_lock(&port_lock);
for(i=port_list;i!=PORT_ENTRY_NULL;i=i->next)
if (i->port == port) {
spin_unlock(&port_lock);
return i;
}
i = (port_entry_t)malloc(sizeof(struct port_entry));
cthread_queue_init(&i->queue);
i->port = port;
i->next = port_list;
port_list = i;
i->min = min;
i->max = max;
i->held = 0;
spin_lock_init(&i->lock);
spin_unlock(&port_lock);
return i;
}
cthread_msg_busy(port, min, max)
mach_port_t port;
{
register port_entry_t port_entry;
register cproc_t new, p = cproc_self();
if (p->busy) {
port_entry = get_port_entry(port, min, max);
spin_lock(&port_entry->lock);
p->busy = 0;
if (port_entry->held <= port_entry->min) {
cthread_queue_deq(&port_entry->queue, cproc_t, new);
if (new != NO_CPROC){
spin_unlock(&port_entry->lock);
cproc_ready(new,0);
} else {
port_entry->held--;
spin_unlock(&port_entry->lock);
#ifdef STATISTICS
spin_lock(&port_lock);
cthread_rnone++;
spin_unlock(&port_lock);
#endif STATISTICS
}
} else {
port_entry->held--;
spin_unlock(&port_entry->lock);
}
}
}
cthread_msg_active(port, min, max)
mach_port_t port;
{
register cproc_t p = cproc_self();
register port_entry_t port_entry;
if (!p->busy) {
port_entry = get_port_entry(port, min, max);
if (port_entry == 0) return;
spin_lock(&port_entry->lock);
if (port_entry->held < port_entry->max) {
port_entry->held++;
p->busy = (int)port_entry;
}
spin_unlock(&port_entry->lock);
}
}
mach_msg_return_t
cthread_mach_msg(header, option,
send_size, rcv_size, rcv_name,
timeout, notify, min, max)
register mach_msg_header_t *header;
register mach_msg_option_t option;
mach_msg_size_t send_size;
mach_msg_size_t rcv_size;
register mach_port_t rcv_name;
mach_msg_timeout_t timeout;
mach_port_t notify;
int min, max;
{
register port_entry_t port_entry;
register cproc_t p = cproc_self();
register int sent=0;
mach_msg_return_t r;
port_entry_t op = (port_entry_t)p->busy;
port_entry = get_port_entry(rcv_name, min, max);
if (op && (port_entry_t)op != port_entry)
cthread_msg_busy(op->port, op->min, op->max);
spin_lock(&port_entry->lock);
if (!(port_entry == (port_entry_t)p->busy)) {
if (port_entry->held >= max) {
if (option & MACH_SEND_MSG) {
spin_unlock(&port_entry->lock);
r = mach_msg(header, option &~ MACH_RCV_MSG,
send_size, 0, MACH_PORT_NULL,
timeout, notify);
if (r != MACH_MSG_SUCCESS) return r;
spin_lock(&port_entry->lock);
sent=1;
}
if (port_entry->held >= max) {
spin_lock(&p->lock);
cthread_queue_preq(&port_entry->queue, p);
spin_unlock(&port_entry->lock);
#ifdef WAIT_DEBUG
p->waiting_for = (char *)port_entry;
#endif WAIT_DEBUG
cproc_block();
} else {
port_entry->held++;
spin_unlock(&port_entry->lock);
}
} else {
port_entry->held++;
spin_unlock(&port_entry->lock);
}
} else {
spin_unlock(&port_entry->lock);
}
#ifdef WAIT_DEBUG
p->waiting_for = (char *)0;
#endif WAIT_DEBUG
p->busy = (int)port_entry;
if ((option & MACH_SEND_MSG) && !sent) {
r = mach_msg(header, option,
send_size, rcv_size, rcv_name,
timeout, notify);
} else {
r = mach_msg(header, option &~ MACH_SEND_MSG,
0, rcv_size, rcv_name,
timeout, notify);
}
return r;
}
cproc_fork_prepare()
{
register cproc_t p = cproc_self();
vm_inherit(mach_task_self(),p->stack_base, p->stack_size, VM_INHERIT_COPY);
spin_lock(&port_lock);
spin_lock(&cproc_list_lock);
}
cproc_fork_parent()
{
register cproc_t p = cproc_self();
spin_unlock(&cproc_list_lock);
spin_unlock(&port_lock);
vm_inherit(mach_task_self(),p->stack_base, p->stack_size, VM_INHERIT_NONE);
}
cproc_fork_child()
{
register cproc_t l,p = cproc_self();
cproc_t m;
register port_entry_t pe;
port_entry_t pet;
kern_return_t r;
vm_inherit(mach_task_self(),p->stack_base, p->stack_size, VM_INHERIT_NONE);
spin_lock_init(&n_kern_lock);
cthread_kernel_threads=0;
#ifdef STATISTICS
cthread_ready = 0;
cthread_running = 1;
cthread_waiting = 0;
cthread_wired = 0;
spin_lock_init(&wired_lock);
cthread_wait_stacks = 0;
cthread_waiters = 0;
cthread_wakeup = 0;
cthread_blocked = 0;
cthread_rnone = 0;
cthread_yields = 0;
cthread_none = 0;
cthread_switches = 0;
cthread_no_mutex = 0;
spin_lock_init(&mutex_count_lock);
#endif STATISTICS
for(l=cproc_list;l!=NO_CPROC;l=m)
if (l!=p) {
m-l->next;
free(l);
}
cproc_list = p;
p->next = NO_CPROC;
spin_lock_init(&cproc_list_lock);
cprocs_started = FALSE;
cthread_queue_init(&ready);
ready_count = 0;
spin_lock_init(&ready_lock);
MACH_CALL(mach_port_allocate(mach_task_self(),
MACH_PORT_RIGHT_RECEIVE,
&wait_port), r);
MACH_CALL(mach_port_insert_right(mach_task_self(),
wait_port, wait_port,
MACH_MSG_TYPE_MAKE_SEND), r);
wakeup_msg.msgh_remote_port = wait_port;
wait_count = 0;
cthread_queue_init(&waiters);
spin_lock_init(&waiters_lock);
for(pe=port_list;pe!=PORT_ENTRY_NULL;pe=pet) {
pet = pe->next;
free(pe);
}
port_list = PORT_ENTRY_NULL;
spin_lock_init(&port_lock);
if (p->wired) cthread_wire();
}
y;
if (!p->busy) {
port_entry = get_port_entry(port, min, max);
if (port_entry == 0) return;
spin_lock(&port_entry->lock);
if (port_entry->held < port_entry->max) {
port_entry->held++;
p->busy = (int)port_entry;
}
spin_unlock(&port_entry->lock);
}
}
mach_msg_return_t
cthread_mach_msg(header, option,
send_size, rcv_size, rcv_name,
timeout, notify, min, max)
register mach_msg_header_t *header;
register mach_msg_option_./user/threads/cthread_internals.h 444 146 0 10521 4756607762 12527 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: cthread_internals.h,v $
* Revision 2.8 91/02/14 14:19:42 mrt
* Added new Mach copyright
* [91/02/13 12:41:02 mrt]
*
* Revision 2.7 90/11/05 14:36:55 rpd
* Added spin_lock_t.
* [90/10/31 rwd]
*
* Revision 2.6 90/09/09 14:34:51 rpd
* Remove special field.
* [90/08/24 rwd]
*
* Revision 2.5 90/06/02 15:13:44 rpd
* Converted to new IPC.
* [90/03/20 20:52:47 rpd]
*
* Revision 2.4 90/03/14 21:12:11 rwd
* Added waiting_for field for debugging deadlocks.
* [90/03/01 rwd]
* Added list field to keep a master list of all cprocs.
* [90/03/01 rwd]
*
* Revision 2.3 90/01/19 14:37:08 rwd
* Keep track of real thread for use in thread_* substitutes.
* Add CPROC_ARUN for about to run and CPROC_HOLD to avoid holding
* spin_locks over system calls.
* [90/01/03 rwd]
* Add busy field to be used by cthread_msg calls to make sure we
* have the right number of blocked kernel threads.
* [89/12/21 rwd]
*
* Revision 2.2 89/12/08 19:53:28 rwd
* Added CPROC_CONDWAIT state
* [89/11/28 rwd]
* Added on_special field.
* [89/11/26 rwd]
* Removed MSGOPT conditionals
* [89/11/25 rwd]
* Removed old debugging code. Add wired port/flag. Add state
* for small state machine.
* [89/10/30 rwd]
* Added CPDEBUG code
* [89/10/26 rwd]
* Change TRACE to {x;} else.
* [89/10/24 rwd]
* Rewrote to work for limited number of kernel threads. This is
* basically a merge of coroutine and thread. Added
* cthread_receivce call for use by servers.
* [89/10/23 rwd]
*
*/
/*
* cthread_internals.h
*
*
* Private definitions for the C Threads implementation.
*
* The cproc structure is used for different implementations
* of the basic schedulable units that execute cthreads.
*
*/
#include "options.h"
#include
/*
* Low-level thread implementation.
* This structure must agree with struct ur_cthread in cthreads.h
*/
typedef struct cproc {
struct cproc *next; /* for lock, condition, and ready queues */
cthread_t incarnation; /* for cthread_self() */
struct cproc *list; /* for master cproc list */
#ifdef WAIT_DEBUG
char *waiting_for; /* address of mutex/cond waiting for */
#endif WAIT_DEBUG
mach_port_t reply_port; /* for mig_get_reply_port() */
int context;
spin_lock_t lock;
int state; /* current state */
#define CPROC_RUNNING 0
#define CPROC_SWITCHING 1
#define CPROC_BLOCKED 2
#define CPROC_CONDWAIT 4
mach_port_t wired; /* is cthread wired to kernel thread */
int busy; /* used with cthread_msg calls */
mach_msg_header_t msg;
unsigned int stack_base;
unsigned int stack_size;
} *cproc_t;
#define NO_CPROC ((cproc_t) 0)
#define cproc_self() ((cproc_t) ur_cthread_self())
/*
* C Threads imports:
*/
extern char *malloc();
/*
* Mach imports:
*/
extern void mach_error();
/*
* C library imports:
*/
extern exit();
/*
* Macro for MACH kernel calls.
*/
#ifdef CHECK_STATUS
#define MACH_CALL(expr, ret) if (((ret) = (expr)) != KERN_SUCCESS) { \
mach_error("expr", (ret)); \
ASSERT(SHOULDNT_HAPPEN); \
exit(1); \
} else
#else CHECK_STATUS
#define MACH_CALL(expr, ret) (ret) = (expr)
#endif CHECK_STATUS
#define private static
#define ASSERT(x)
#define TRACE(x)
=1;
}
if (port_entry->held >= max) {
spin_lock(&p->lock);
cthread_queue_preq(&port_entry->queue, p);
spin_unlock(&port_entry->lock);
#ifdef WAIT_DEBUG
./user/threads/cthreads.c 444 146 0 23131 4756607764 10631 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: cthreads.c,v $
* Revision 2.7 91/02/14 14:19:47 mrt
* Added new Mach copyright
* [91/02/13 12:41:07 mrt]
*
* Revision 2.6 90/11/05 14:37:03 rpd
* Added cthread_fork_{prepare,parent,child}.
* [90/11/02 rwd]
*
* Add spin_lock_t.
* [90/10/31 rwd]
*
* Revision 2.5 90/08/07 14:30:58 rpd
* Removed RCS keyword nonsense.
*
* Revision 2.4 90/06/02 15:13:49 rpd
* Converted to new IPC.
* [90/03/20 20:56:44 rpd]
*
* Revision 2.3 90/01/19 14:37:12 rwd
* Make cthread_init return pointer to new stack.
* [89/12/18 19:17:45 rwd]
*
* Revision 2.2 89/12/08 19:53:37 rwd
* Change cproc and cthread counters to globals with better names.
* [89/11/02 rwd]
*
* Revision 2.1 89/08/03 17:09:34 rwd
* Created.
*
*
* 31-Dec-87 Eric Cooper (ecc) at Carnegie Mellon University
* Changed cthread_exit() logic for the case of the main thread,
* to fix thread and stack memory leak found by Camelot group.
*
* 21-Aug-87 Eric Cooper (ecc) at Carnegie Mellon University
* Added consistency check in beginning of cthread_body().
*
* 11-Aug-87 Eric Cooper (ecc) at Carnegie Mellon University
* Removed cthread_port() and cthread_set_port().
* Removed port deallocation from cthread_free().
* Minor changes to cthread_body(), cthread_exit(), and cthread_done().
*
* 10-Aug-87 Eric Cooper (ecc) at Carnegie Mellon University
* Changed call to mig_init() in cthread_init() to pass 1 as argument.
*
* 31-Jul-87 Eric Cooper (ecc) at Carnegie Mellon University
* Added call to mig_init() from cthread_init().
*/
/*
* File: cthreads.c
* Author: Eric Cooper, Carnegie Mellon University
* Date: July, 1987
*
* Implementation of fork, join, exit, etc.
*/
#include
#include "cthread_internals.h"
/*
* C Threads imports:
*/
extern void cproc_create();
extern vm_offset_t cproc_init();
extern void mig_init();
/*
* Mach imports:
*/
/*
* C library imports:
*/
extern _setjmp(), _longjmp();
/*
* Thread status bits.
*/
#define T_MAIN 0x1
#define T_RETURNED 0x2
#define T_DETACHED 0x4
#ifdef DEBUG
int cthread_debug = FALSE;
#endif DEBUG
private struct cthread_queue cthreads = QUEUE_INITIALIZER;
private struct mutex cthread_lock = MUTEX_INITIALIZER;
private struct condition cthread_needed = CONDITION_INITIALIZER;
private struct condition cthread_idle = CONDITION_INITIALIZER;
int cthread_cprocs = 0;
int cthread_cthreads = 0;
int cthread_max_cprocs = 0;
private cthread_t free_cthreads = NO_CTHREAD; /* free list */
private spin_lock_t free_lock = SPIN_LOCK_INITIALIZER; /* unlocked */
private struct cthread initial_cthread = { 0 };
private cthread_t
cthread_alloc(func, arg)
cthread_fn_t func;
any_t arg;
{
register cthread_t t = NO_CTHREAD;
if (free_cthreads != NO_CTHREAD) {
/*
* Don't try for the lock unless
* the list is likely to be nonempty.
* We can't be sure, though, until we lock it.
*/
spin_lock(&free_lock);
t = free_cthreads;
if (t != NO_CTHREAD)
free_cthreads = t->next;
spin_unlock(&free_lock);
}
if (t == NO_CTHREAD) {
/*
* The free list was empty.
* We may have only found this out after
* locking it, which is why this isn't an
* "else" branch of the previous statement.
*/
t = (cthread_t) malloc(sizeof(struct cthread));
}
*t = initial_cthread;
t->func = func;
t->arg = arg;
return t;
}
private void
cthread_free(t)
register cthread_t t;
{
spin_lock(&free_lock);
t->next = free_cthreads;
free_cthreads = t;
spin_unlock(&free_lock);
}
int
cthread_init()
{
static int cthreads_started = FALSE;
register cproc_t p;
register cthread_t t;
vm_offset_t stack;
if (cthreads_started)
return 0;
stack = cproc_init();
cthread_cprocs = 1;
t = cthread_alloc((cthread_fn_t) 0, (any_t) 0);
cthread_cthreads = 1;
t->state |= T_MAIN;
cthread_set_name(t, "main");
/* cproc_self() doesn't work yet, because
we haven't yet switched to the new stack. */
p = *((cproc_t *)((stack | cthread_stack_mask) - 3));
p->incarnation = t;
mig_init(p); /* enable multi-threaded mig interfaces */
cthreads_started = TRUE;
return stack;
}
/*
* Used for automatic initialization by crt0.
* Cast needed since too many C compilers choke on the type void (*)().
*/
int (*_cthread_init_routine)() = (int (*)()) cthread_init;
/*
* Procedure invoked at the base of each cthread.
*/
void
cthread_body(self)
cproc_t self;
{
register cthread_t t;
ASSERT(cproc_self() == self);
TRACE(printf("[idle] cthread_body(%x)\n", self));
mutex_lock(&cthread_lock);
for (;;) {
/*
* Dequeue a thread invocation request.
*/
cthread_queue_deq(&cthreads, cthread_t, t);
if (t != NO_CTHREAD) {
/*
* We have a thread to execute.
*/
mutex_unlock(&cthread_lock);
cthread_assoc(self, t); /* assume thread's identity */
if (_setjmp(t->catch) == 0) { /* catch for cthread_exit() */
/*
* Execute the fork request.
*/
t->result = (*(t->func))(t->arg);
}
/*
* Return result from thread.
*/
TRACE(printf("[%s] done()\n", cthread_name(t)));
mutex_lock(&t->lock);
if (t->state & T_DETACHED) {
mutex_unlock(&t->lock);
cthread_free(t);
} else {
t->state |= T_RETURNED;
mutex_unlock(&t->lock);
condition_signal(&t->done);
}
cthread_assoc(self, NO_CTHREAD);
mutex_lock(&cthread_lock);
cthread_cthreads -= 1;
} else {
/*
* Queue is empty.
* Signal that we're idle in case the main thread
* is waiting to exit, then wait for reincarnation.
*/
condition_signal(&cthread_idle);
condition_wait(&cthread_needed, &cthread_lock);
}
}
}
cthread_t
cthread_fork(func, arg)
cthread_fn_t func;
any_t arg;
{
register cthread_t t;
TRACE(printf("[%s] fork()\n", cthread_name(cthread_self())));
mutex_lock(&cthread_lock);
t = cthread_alloc(func, arg);
cthread_queue_enq(&cthreads, t);
if (++cthread_cthreads > cthread_cprocs && (cthread_max_cprocs == 0 || cthread_cprocs < cthread_max_cprocs)) {
cthread_cprocs += 1;
cproc_create();
}
mutex_unlock(&cthread_lock);
condition_signal(&cthread_needed);
return t;
}
void
cthread_detach(t)
cthread_t t;
{
TRACE(printf("[%s] detach(%s)\n", cthread_name(cthread_self()), cthread_name(t)));
mutex_lock(&t->lock);
if (t->state & T_RETURNED) {
mutex_unlock(&t->lock);
cthread_free(t);
} else {
t->state |= T_DETACHED;
mutex_unlock(&t->lock);
}
}
any_t
cthread_join(t)
cthread_t t;
{
any_t result;
TRACE(printf("[%s] join(%s)\n", cthread_name(cthread_self()), cthread_name(t)));
mutex_lock(&t->lock);
ASSERT(! (t->state & T_DETACHED));
while (! (t->state & T_RETURNED))
condition_wait(&t->done, &t->lock);
result = t->result;
mutex_unlock(&t->lock);
cthread_free(t);
return result;
}
void
cthread_exit(result)
any_t result;
{
register cthread_t t = cthread_self();
TRACE(printf("[%s] exit()\n", cthread_name(t)));
t->result = result;
if (t->state & T_MAIN) {
mutex_lock(&cthread_lock);
while (cthread_cthreads > 1)
condition_wait(&cthread_idle, &cthread_lock);
mutex_unlock(&cthread_lock);
exit((int) result);
} else {
_longjmp(t->catch, TRUE);
}
}
/*
* Used for automatic finalization by crt0. Cast needed since too many C
* compilers choke on the type void (*)().
*/
int (*_cthread_exit_routine)() = (int (*)()) cthread_exit;
void
cthread_set_name(t, name)
cthread_t t;
char *name;
{
t->name = name;
}
char *
cthread_name(t)
cthread_t t;
{
return (t == NO_CTHREAD
? "idle"
: (t->name == 0 ? "?" : t->name));
}
int
cthread_limit()
{
return cthread_max_cprocs;
}
void
cthread_set_limit(n)
int n;
{
cthread_max_cprocs = n;
}
int
cthread_count()
{
return cthread_cthreads;
}
cthread_fork_prepare()
{
spin_lock(&free_lock);
mutex_lock(&cthread_lock);
malloc_fork_prepare();
cproc_fork_prepare();
}
cthread_fork_parent()
{
cproc_fork_parent();
malloc_fork_parent();
mutex_unlock(&cthread_lock);
spin_unlock(&free_lock);
}
cthread_fork_child()
{
cthread_t t;
cproc_fork_child();
malloc_fork_child();
mutex_unlock(&cthread_lock);
spin_unlock(&free_lock);
condition_init(&cthread_needed);
condition_init(&cthread_idle);
cthread_max_cprocs = 0;
stack_fork_child();
while (TRUE) { /* Free cthread runnable list */
cthread_queue_deq(&cthreads, cthread_t, t);
if (t == NO_CTHREAD) break;
free((char *) t);
}
while (free_cthreads != NO_CTHREAD) { /* Free cthread free list */
t = free_cthreads;
free_cthreads = free_cthreads->next;
free((char *) t);
}
cthread_cprocs = 1;
t = cthread_self();
cthread_cthreads = 1;
t->state |= T_MAIN;
cthread_set_name(t, "main");
mig_init(1); /* enable multi-threaded mig interfaces */
}
t);
if (t != NO_CTHREAD) {
/*
* We have a thread to execute.
*/
mutex_unlock(&cthread_lock);
cthread_assoc(self, t); /* assume thread's identity */
if (_setjmp(t->catch) == 0) { /* catch for cthread_exit() */
/*
* Execute the fork request.
*/
t->result = (*(t->func))(t->arg);
}
/*
* Return result from thread.
*/
TRACE(printf("[%s] done()\n", cthread_name(t)));
./user/threads/cthreads.h 444 146 0 25444 4756607764 10647 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: cthreads.h,v $
* Revision 2.8 91/02/14 14:19:52 mrt
* Added new Mach copyright
* [91/02/13 12:41:15 mrt]
*
* Revision 2.7 90/11/05 14:37:12 rpd
* Include machine/cthreads.h. Added spin_lock_t.
* [90/10/31 rwd]
*
* Revision 2.6 90/10/12 13:07:24 rpd
* Channge to allow for positive stack growth.
* [90/10/10 rwd]
*
* Revision 2.5 90/09/09 14:34:56 rpd
* Remove mutex_special and debug_mutex.
* [90/08/24 rwd]
*
* Revision 2.4 90/08/07 14:31:14 rpd
* Removed RCS keyword nonsense.
*
* Revision 2.3 90/01/19 14:37:18 rwd
* Add back pointer to cthread structure.
* [90/01/03 rwd]
* Change definition of cthread_init and change ur_cthread_self macro
* to reflect movement of self pointer on stack.
* [89/12/18 19:18:34 rwd]
*
* Revision 2.2 89/12/08 19:53:49 rwd
* Change spin_try_lock to int.
* [89/11/30 rwd]
* Changed mutex macros to deal with special mutexs
* [89/11/26 rwd]
* Make mutex_{set,clear}_special routines instead of macros.
* [89/11/25 rwd]
* Added mutex_special to specify a need to context switch on this
* mutex.
* [89/11/21 rwd]
*
* Made mutex_lock a macro trying to grab the spin_lock first.
* [89/11/13 rwd]
* Removed conditionals. Mutexes are more like conditions now.
* Changed for limited kernel thread version.
* [89/10/23 rwd]
*
* Revision 2.1 89/08/03 17:09:40 rwd
* Created.
*
*
* 28-Oct-88 Eric Cooper (ecc) at Carnegie Mellon University
* Implemented spin_lock() as test and test-and-set logic
* (using mutex_try_lock()) in sync.c. Changed ((char *) 0)
* to 0, at Mike Jones's suggestion, and turned on ANSI-style
* declarations in either C++ or _STDC_.
*
* 29-Sep-88 Eric Cooper (ecc) at Carnegie Mellon University
* Changed NULL to ((char *) 0) to avoid dependency on
* at Alessandro Forin's suggestion.
*
* 08-Sep-88 Alessandro Forin (af) at Carnegie Mellon University
* Changed queue_t to cthread_queue_t and string_t to char *
* to avoid conflicts.
*
* 01-Apr-88 Eric Cooper (ecc) at Carnegie Mellon University
* Changed compound statement macros to use the
* do { ... } while (0) trick, so that they work
* in all statement contexts.
*
* 19-Feb-88 Eric Cooper (ecc) at Carnegie Mellon University
* Made spin_unlock() and mutex_unlock() into procedure calls
* rather than macros, so that even smart compilers can't reorder
* the clearing of the lock. Suggested by Jeff Eppinger.
* Removed the now empty
*
* 01-Dec-87 Eric Cooper (ecc) at Carnegie Mellon University
* Changed cthread_self() to mask the current SP to find
* the self pointer stored at the base of the stack.
*
* 22-Jul-87 Eric Cooper (ecc) at Carnegie Mellon University
* Fixed bugs in mutex_set_name and condition_set_name
* due to bad choice of macro formal parameter name.
*
* 21-Jul-87 Eric Cooper (ecc) at Carnegie Mellon University
* Moved #include
* to types before they are declared (required by C++).
*
* 9-Jul-87 Michael Jones (mbj) at Carnegie Mellon University
* Added conditional type declarations for C++.
* Added _cthread_init_routine and _cthread_exit_routine variables
* for automatic initialization and finalization by crt0.
*/
/*
/*
* File: cthread.h
* Author: Eric Cooper, Carnegie Mellon University
* Date: Jul, 1987
*
* Definitions for the C Threads package.
*
*/
#ifndef _CTHREADS_
#define _CTHREADS_ 1
#include
#if c_plusplus || _STDC_
#ifndef C_ARG_DECLS
#define C_ARG_DECLS(arglist) arglist
#endif not C_ARG_DECLS
typedef void *any_t;
#else not (c_plusplus || _STDC_)
#ifndef C_ARG_DECLS
#define C_ARG_DECLS(arglist) ()
#endif not C_ARG_DECLS
typedef char *any_t;
#endif not (c_plusplus || _STDC_)
#include
#include
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif TRUE
/*
* C Threads package initialization.
*/
extern int cthread_init();
extern any_t calloc C_ARG_DECLS((unsigned n, unsigned size));
/*
* Queues.
*/
typedef struct cthread_queue {
struct cthread_queue_item *head;
struct cthread_queue_item *tail;
} *cthread_queue_t;
typedef struct cthread_queue_item {
struct cthread_queue_item *next;
} *cthread_queue_item_t;
#define NO_QUEUE_ITEM ((cthread_queue_item_t) 0)
#define QUEUE_INITIALIZER { NO_QUEUE_ITEM, NO_QUEUE_ITEM }
#define cthread_queue_alloc() ((cthread_queue_t) calloc(1, sizeof(struct cthread_queue)))
#define cthread_queue_init(q) ((q)->head = (q)->tail = 0)
#define cthread_queue_free(q) free((any_t) (q))
#define cthread_queue_enq(q, x) \
do { \
(x)->next = 0; \
if ((q)->tail == 0) \
(q)->head = (cthread_queue_item_t) (x); \
else \
(q)->tail->next = (cthread_queue_item_t) (x); \
(q)->tail = (cthread_queue_item_t) (x); \
} while (0)
#define cthread_queue_preq(q, x) \
do { \
if ((q)->tail == 0) \
(q)->tail = (cthread_queue_item_t) (x); \
((cthread_queue_item_t) (x))->next = (q)->head; \
(q)->head = (cthread_queue_item_t) (x); \
} while (0)
#define cthread_queue_head(q, t) ((t) ((q)->head))
#define cthread_queue_deq(q, t, x) \
if (((x) = (t) ((q)->head)) != 0 && \
((q)->head = (cthread_queue_item_t) ((x)->next)) == 0) \
(q)->tail = 0; \
else
#define cthread_queue_map(q, t, f) \
do { \
register cthread_queue_item_t x, next; \
for (x = (cthread_queue_item_t) ((q)->head); x != 0; x = next) { \
next = x->next; \
(*(f))((t) x); \
} \
} while (0)
/*
* Spin locks.
*/
extern void
spin_lock_solid C_ARG_DECLS((spin_lock_t *p));
extern void
spin_unlock C_ARG_DECLS((spin_lock_t *p));
extern int
spin_try_lock C_ARG_DECLS((spin_lock_t *p));
#define spin_lock(p) if (!spin_try_lock(p)) spin_lock_solid(p); else
/*
* Mutex objects.
*/
typedef struct mutex {
spin_lock_t lock;
char *name;
struct cthread_queue queue;
spin_lock_t held;
} *mutex_t;
#define MUTEX_INITIALIZER { SPIN_LOCK_INITIALIZER, 0, QUEUE_INITIALIZER, SPIN_LOCK_INITIALIZER}
#define mutex_alloc() ((mutex_t) calloc(1, sizeof(struct mutex)))
#define mutex_init(m) do {spin_lock_init(&(m)->lock); cthread_queue_init(&(m)->queue); spin_lock_init(&(m)->held);} while (0)
#define mutex_set_name(m, x) ((m)->name = (x))
#define mutex_name(m) ((m)->name != 0 ? (m)->name : "?")
#define mutex_clear(m) /* nop */???
#define mutex_free(m) free((any_t) (m))
extern void
mutex_lock_solid C_ARG_DECLS((mutex_t m)); /* blocking */
extern void
mutex_unlock_solid C_ARG_DECLS((mutex_t m));
#define mutex_try_lock(m) spin_try_lock(&(m)->held)
#define mutex_lock(m) if (!spin_try_lock(&(m)->held)) mutex_lock_solid(m);else
#define mutex_unlock(m) if (spin_unlock(&(m)->held),cthread_queue_head(&(m)->queue, int) != 0)mutex_unlock_solid(m); else
/*
* Condition variables.
*/
typedef struct condition {
spin_lock_t lock;
struct cthread_queue queue;
char *name;
} *condition_t;
#define CONDITION_INITIALIZER { SPIN_LOCK_INITIALIZER, QUEUE_INITIALIZER, 0 }
#define condition_alloc() ((condition_t) calloc(1, sizeof(struct condition)))
#define condition_init(c) do { spin_lock_init(&(c)->lock); cthread_queue_init(&(c)->queue); } while (0)
#define condition_set_name(c, x) ((c)->name = (x))
#define condition_name(c) ((c)->name != 0 ? (c)->name : "?")
#define condition_clear(c) do { condition_broadcast(c); spin_lock(&(c)->lock); } while (0)
#define condition_free(c) do { condition_clear(c); free((any_t) (c)); } while (0)
#define condition_signal(c) if ((c)->queue.head) \
cond_signal(c); \
else
#define condition_broadcast(c) if ((c)->queue.head) \
cond_broadcast(c); \
else
extern void
cond_signal C_ARG_DECLS((condition_t c));
extern void
cond_broadcast C_ARG_DECLS((condition_t c));
extern void
condition_wait C_ARG_DECLS((condition_t c, mutex_t m));
/*
* Threads.
*/
typedef any_t (*cthread_fn_t) C_ARG_DECLS((any_t arg));
#include
typedef struct cthread {
struct cthread *next;
struct mutex lock;
struct condition done;
int state;
jmp_buf catch;
cthread_fn_t func;
any_t arg;
any_t result;
char *name;
any_t data;
struct ur_cthread *ur;
} *cthread_t;
#define NO_CTHREAD ((cthread_t) 0)
extern cthread_t
cthread_fork C_ARG_DECLS((cthread_fn_t func, any_t arg));
extern void
cthread_detach C_ARG_DECLS((cthread_t t));
extern any_t
cthread_join C_ARG_DECLS((cthread_t t));
extern void
cthread_yield();
extern void
cthread_exit C_ARG_DECLS((any_t result));
/*
* This structure must agree with struct cproc in cthread_internals.h
*/
typedef struct ur_cthread {
struct ur_cthread *next;
cthread_t incarnation;
} *ur_cthread_t;
extern int
cthread_sp();
extern int cthread_stack_mask;
#ifdef STACK_GROWTH_UP
#define ur_cthread_self() (* (ur_cthread_t *) (cthread_sp() & cthread_stack_mask))
#else STACK_GROWTH_UP
#define ur_cthread_self() (* (ur_cthread_t *) (((char *)(cthread_sp() | cthread_stack_mask)) - 3))
#endif STACK_GROWTH_UP
#define cthread_assoc(id, t) ((((ur_cthread_t) (id))->incarnation = (t)), \
((t) ? ((t)->ur = (ur_cthread_t)(id)) : 0))
#define cthread_self() (ur_cthread_self()->incarnation)
extern void
cthread_set_name C_ARG_DECLS((cthread_t t, char *name));
extern char *
cthread_name C_ARG_DECLS((cthread_t t));
extern int
cthread_count();
extern void
cthread_set_limit C_ARG_DECLS((int n));
extern int
cthread_limit();
#define cthread_set_data(t, x) ((t)->data = (x))
#define cthread_data(t) ((t)->data)
/*
* Debugging support.
*/
#ifdef DEBUG
#ifndef ASSERT
/*
* Assertion macro, similar to
*/
#include
#define ASSERT(p) if (!(p)) { \
fprintf(stderr, \
"File %s, line %d: assertion p failed.\n", \
__FILE__, __LINE__); \
abort(); \
} else
#endif ASSERT
#define SHOULDNT_HAPPEN 0
extern int cthread_debug;
#else DEBUG
#ifndef ASSERT
#define ASSERT(p)
#endif ASSERT
#endif DEBUG
#endif _CTHREADS_
ypedef struct mutex {
spin_lock_t lock;
char *name;
struct cthread_queue queue;
spin_lock_t held;
} *mutex_t;
#define MUTEX_INITIALIZER { SPIN_LOCK_INITIALIZER, 0, QUEUE_INITIALIZER, SPIN_LOCK_INITIALIZER}
#define ./user/threads/machine 755 146 0 0 4756612025 10755 2@sys ./user/threads/malloc.c 444 146 0 16617 4756607775 10320 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: malloc.c,v $
* Revision 2.6 91/02/14 14:20:26 mrt
* Added new Mach copyright
* [91/02/13 12:41:21 mrt]
*
* Revision 2.5 90/11/05 14:37:33 rpd
* Added malloc_fork* code.
* [90/11/02 rwd]
*
* Add spin_lock_t.
* [90/10/31 rwd]
*
* Revision 2.4 90/08/07 14:31:28 rpd
* Removed RCS keyword nonsense.
*
* Revision 2.3 90/06/02 15:14:00 rpd
* Converted to new IPC.
* [90/03/20 20:56:57 rpd]
*
* Revision 2.2 89/12/08 19:53:59 rwd
* Removed conditionals.
* [89/10/23 rwd]
*
* Revision 2.1 89/08/03 17:09:46 rwd
* Created.
*
*
* 13-Sep-88 Eric Cooper (ecc) at Carnegie Mellon University
* Changed realloc() to copy min(old size, new size) bytes.
* Bug found by Mike Kupfer at Olivetti.
*/
/*
* File: malloc.c
* Author: Eric Cooper, Carnegie Mellon University
* Date: July, 1988
*
* Memory allocator for use with multiple threads.
*/
#include
#include "cthread_internals.h"
/*
* C library imports:
*/
extern bcopy();
/*
* Structure of memory block header.
* When free, next points to next block on free list.
* When allocated, fl points to free list.
* Size of header is 4 bytes, so minimum usable block size is 8 bytes.
*/
typedef union header {
union header *next;
struct free_list *fl;
} *header_t;
#define MIN_SIZE 8 /* minimum block size */
typedef struct free_list {
spin_lock_t lock; /* spin lock for mutual exclusion */
header_t head; /* head of free list for this size */
#ifdef DEBUG
int in_use; /* # mallocs - # frees */
#endif DEBUG
} *free_list_t;
/*
* Free list with index i contains blocks of size 2^(i+3) including header.
* Smallest block size is 8, with 4 bytes available to user.
* Size argument to malloc is a signed integer for sanity checking,
* so largest block size is 2^31.
*/
#define NBUCKETS 29
static struct free_list malloc_free_list[NBUCKETS];
static void
more_memory(size, fl)
int size;
register free_list_t fl;
{
register int amount;
register int n;
vm_address_t where;
register header_t h;
kern_return_t r;
if (size <= vm_page_size) {
amount = vm_page_size;
n = vm_page_size / size;
/*
* We lose vm_page_size - n*size bytes here.
*/
} else {
amount = size;
n = 1;
}
MACH_CALL(vm_allocate(mach_task_self(), &where, (vm_size_t) amount, TRUE), r);
h = (header_t) where;
do {
h->next = fl->head;
fl->head = h;
h = (header_t) ((char *) h + size);
} while (--n != 0);
}
char *
malloc(size)
register unsigned int size;
{
register int i, n;
register free_list_t fl;
register header_t h;
if ((int) size <= 0) /* sanity check */
return 0;
size += sizeof(union header);
/*
* Find smallest power-of-two block size
* big enough to hold requested size plus header.
*/
i = 0;
n = MIN_SIZE;
while (n < size) {
i += 1;
n <<= 1;
}
ASSERT(i < NBUCKETS);
fl = &malloc_free_list[i];
spin_lock(&fl->lock);
h = fl->head;
if (h == 0) {
/*
* Free list is empty;
* allocate more blocks.
*/
more_memory(n, fl);
h = fl->head;
if (h == 0) {
/*
* Allocation failed.
*/
spin_unlock(&fl->lock);
return 0;
}
}
/*
* Pop block from free list.
*/
fl->head = h->next;
#ifdef DEBUG
fl->in_use += 1;
#endif DEBUG
spin_unlock(&fl->lock);
/*
* Store free list pointer in block header
* so we can figure out where it goes
* at free() time.
*/
h->fl = fl;
/*
* Return pointer past the block header.
*/
return ((char *) h) + sizeof(union header);
}
free(base)
char *base;
{
register header_t h;
register free_list_t fl;
register int i;
if (base == 0)
return;
/*
* Find free list for block.
*/
h = (header_t) (base - sizeof(union header));
fl = h->fl;
i = fl - malloc_free_list;
/*
* Sanity checks.
*/
if (i < 0 || i >= NBUCKETS) {
ASSERT(0 <= i && i < NBUCKETS);
return;
}
if (fl != &malloc_free_list[i]) {
ASSERT(fl == &malloc_free_list[i]);
return;
}
/*
* Push block on free list.
*/
spin_lock(&fl->lock);
h->next = fl->head;
fl->head = h;
#ifdef DEBUG
fl->in_use -= 1;
#endif DEBUG
spin_unlock(&fl->lock);
return;
}
char *
realloc(old_base, new_size)
char *old_base;
unsigned int new_size;
{
register header_t h;
register free_list_t fl;
register int i;
unsigned int old_size;
char *new_base;
if (old_base == 0)
return 0;
/*
* Find size of old block.
*/
h = (header_t) (old_base - sizeof(union header));
fl = h->fl;
i = fl - malloc_free_list;
/*
* Sanity checks.
*/
if (i < 0 || i >= NBUCKETS) {
ASSERT(0 <= i && i < NBUCKETS);
return 0;
}
if (fl != &malloc_free_list[i]) {
ASSERT(fl == &malloc_free_list[i]);
return 0;
}
/*
* Free list with index i contains blocks of size 2^(i+3) including header.
*/
old_size = (1 << (i+3)) - sizeof(union header);
/*
* Allocate new block, copy old bytes, and free old block.
*/
new_base = malloc(new_size);
if (new_base != 0)
bcopy(old_base, new_base, (int) (old_size < new_size ? old_size : new_size));
free(old_base);
return new_base;
}
#ifdef DEBUG
void
print_malloc_free_list()
{
register int i, size;
register free_list_t fl;
register int n;
register header_t h;
int total_used = 0;
int total_free = 0;
fprintf(stderr, " Size In Use Free Total\n");
for (i = 0, size = MIN_SIZE, fl = malloc_free_list;
i < NBUCKETS;
i += 1, size <<= 1, fl += 1) {
spin_lock(&fl->lock);
if (fl->in_use != 0 || fl->head != 0) {
total_used += fl->in_use * size;
for (n = 0, h = fl->head; h != 0; h = h->next, n += 1)
;
total_free += n * size;
fprintf(stderr, "%10d %10d %10d %10d\n",
size, fl->in_use, n, fl->in_use + n);
}
spin_unlock(&fl->lock);
}
fprintf(stderr, " all sizes %10d %10d %10d\n",
total_used, total_free, total_used + total_free);
}
#endif DEBUG
void malloc_fork_prepare()
/*
* Prepare the malloc module for a fork by insuring that no thread is in a
* malloc critical section.
*/
{
register int i;
for (i = 0; i < NBUCKETS; i++) {
spin_lock(&malloc_free_list[i].lock);
}
}
void malloc_fork_parent()
/*
* Called in the parent process after a fork() to resume normal operation.
*/
{
register int i;
for (i = NBUCKETS-1; i >= 0; i--) {
spin_unlock(&malloc_free_list[i].lock);
}
}
void malloc_fork_child()
/*
* Called in the child process after a fork() to resume normal operation.
*/
{
register int i;
for (i = NBUCKETS-1; i >= 0; i--) {
spin_unlock(&malloc_free_list[i].lock);
}
}
header_t) ((char *) h + size);
} while (--n != 0);
}
char *
malloc(size)
register unsigned int size;
{
regist./user/threads/mig_support.c 444 146 0 10217 4756607776 11410 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: mig_support.c,v $
* Revision 2.5 91/02/14 14:20:30 mrt
* Added new Mach copyright
* [91/02/13 12:41:26 mrt]
*
* Revision 2.4 90/08/07 14:31:41 rpd
* Removed RCS keyword nonsense.
*
* Revision 2.3 90/08/07 14:27:48 rpd
* When we recycle the global reply port by giving it to the first
* cthread, clear the global reply port. This will take care of
* someone accidently calling this twice.
* [90/08/07 rwd]
*
* Revision 2.2 90/06/02 15:14:04 rpd
* Converted to new IPC.
* [90/03/20 20:56:50 rpd]
*
* Revision 2.1 89/08/03 17:09:50 rwd
* Created.
*
* 18-Jan-89 David Golub (dbg) at Carnegie-Mellon University
* Replaced task_data() by thread_reply().
*
*
* 27-Aug-87 Eric Cooper (ecc) at Carnegie Mellon University
* Changed mig_support.c to avoid deadlock that can occur
* if tracing is turned on during calls to mig_get_reply_port().
*
* 10-Aug-87 Eric Cooper (ecc) at Carnegie Mellon University
* Changed mig_support.c to use MACH_CALL.
* Changed "is_init" to "multithreaded" and reversed its sense.
*
* 30-Jul-87 Mary Thompson (mrt) at Carnegie Mellon University
* Created.
*/
/*
* File: mig_support.c
* Author: Mary R. Thompson, Carnegie Mellon University
* Date: July, 1987
*
* Routines to set and deallocate the mig reply port for the current thread.
* Called from mig-generated interfaces.
*
*/
#include
#include
#include "cthread_internals.h"
private boolean_t multithreaded = FALSE;
/* use a global reply port before becoming multi-threaded */
private mach_port_t mig_reply_port = MACH_PORT_NULL;
/*
* Called by mach_init with 0 before cthread_init is
* called and again with initial cproc at end of cthread_init.
*/
void
mig_init(initial)
register cproc_t initial;
{
if (initial == NO_CPROC) {
/* called from mach_init before cthread_init,
possibly after a fork. clear global reply port. */
multithreaded = FALSE;
mig_reply_port = MACH_PORT_NULL;
} else {
/* recycle global reply port as this cthread's reply port */
multithreaded = TRUE;
initial->reply_port = mig_reply_port;
mig_reply_port = MACH_PORT_NULL;
}
}
/*
* Called by mig interface code whenever a reply port is needed.
*/
mach_port_t
mig_get_reply_port()
{
register mach_port_t reply_port;
if (multithreaded) {
register cproc_t self;
self = cproc_self();
ASSERT(self != NO_CPROC);
if ((reply_port = self->reply_port) == MACH_PORT_NULL)
self->reply_port = reply_port = mach_reply_port();
} else {
if ((reply_port = mig_reply_port) == MACH_PORT_NULL)
mig_reply_port = reply_port = mach_reply_port();
}
return reply_port;
}
/*
* Called by mig interface code after a timeout on the reply port.
* May also be called by user.
*/
void
mig_dealloc_reply_port()
{
register mach_port_t reply_port;
if (multithreaded) {
register cproc_t self;
self = cproc_self();
ASSERT(self != NO_CPROC);
reply_port = self->reply_port;
self->reply_port = MACH_PORT_NULL;
} else {
reply_port = mig_reply_port;
mig_reply_port = MACH_PORT_NULL;
}
(void) mach_port_mod_refs(mach_task_self(), reply_port,
MACH_PORT_RIGHT_RECEIVE, -1);
}
*/
fl->head = h->next;
#ifdef DEBUG
fl->in_use += 1;
#endif DEBUG
spin_unlock(&fl->lock);
/*
* Store free list pointer in block header
* so we can figure out where it goes
* at free() time.
*/
h->fl = fl;
/*
* Return pointer past the block header.
*/
return ((char *) h) + sizeof(union header);
}
free(base)
char *base;
{
register header_t h;
./user/threads/options.h 444 146 0 5427 4756610004 10501 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: options.h,v $
* Revision 2.7 91/02/14 14:21:03 mrt
* Added new Mach copyright
* [91/02/13 12:41:31 mrt]
*
* Revision 2.6 90/09/09 14:35:04 rpd
* Remove special option , debug_mutex and thread_calls.
* [90/08/24 rwd]
*
* Revision 2.5 90/06/02 15:14:14 rpd
* Removed RCS Source, Header lines.
* [90/05/03 00:07:27 rpd]
*
* Revision 2.4 90/03/14 21:12:15 rwd
* Added new option:
* WAIT_DEBUG: keep track of who a blocked thread is
* waiting for.
* [90/03/01 rwd]
*
* Revision 2.3 90/01/19 14:37:25 rwd
* New option:
* THREAD_CALLS: cthread_* version of thread_* calls.
* [90/01/03 rwd]
*
* Revision 2.2 89/12/08 19:54:09 rwd
* Added code:
* MUTEX_SPECIAL: Have extra kernel threads available for
* special mutexes to avoid deadlocks
* Removed options:
* MSGOPT, RECEIVE_YIELD
* [89/11/25 rwd]
* Added option:
* MUTEX_SPECIAL: Allow special mutexes which will
* garuntee the resulting threads runs
* on a mutex_unlock
* [89/11/21 rwd]
* Options added are:
* STATISTICS: collect [kernel/c]thread state stats.
* SPIN_RESCHED: call swtch_pri(0) when spin will block.
* MSGOPT: try to minimize message sends
* CHECK_STATUS: check status of mach calls
* RECEIVE_YIELD: yield thread if no waiting threads after
* cthread_msg_receive
* RED_ZONE: make redzone at end of stacks
* DEBUG_MUTEX: in conjunction with same in cthreads.h
* use slow mutex with held=cproc_self().
* [89/11/13 rwd]
* Added copyright. Removed all options.
* [89/10/23 rwd]
*
*/
/*
* options.h
*/
/*#define STATISTICS*/
#define SPIN_RESCHED
/*#define CHECK_STATUS*/
/*#define RED_ZONE*/
#define WAIT_DEBUG
ister mach_port_t reply_port;
if (multithreaded) {
register cproc_t self;
self = cproc_self();
ASSERT(self != NO_CPROC);
reply_port = self->reply_port;
self->reply_port = MACH_PORT_NULL;
} else {
reply_port = mig_rep./user/threads/stack.c 444 146 0 21417 4756610005 10124 /*
* Mach Operating System
* Copyright (c) 1991,1990 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: stack.c,v $
* Revision 2.9 91/02/14 14:21:08 mrt
* Added new Mach copyright
* [91/02/13 12:41:35 mrt]
*
* Revision 2.8 90/11/05 18:10:46 rpd
* Added cproc_stack_base. Add stack_fork_child().
* [90/11/01 rwd]
*
* Revision 2.7 90/11/05 14:37:51 rpd
* Fixed addr_range_check for new vm_region semantics.
* [90/11/02 rpd]
*
* Revision 2.6 90/10/12 13:07:34 rpd
* Deal with positively growing stacks.
* [90/10/10 rwd]
* Deal with initial user stacks that are not perfectly aligned.
* [90/09/26 11:51:46 rwd]
*
* Leave extra stack page around in case it is needed before we
* switch stacks.
* [90/09/25 rwd]
*
* Revision 2.5 90/08/07 14:31:46 rpd
* Removed RCS keyword nonsense.
*
* Revision 2.4 90/06/02 15:14:18 rpd
* Moved cthread_sp to machine-dependent files.
* [90/04/24 rpd]
* Converted to new IPC.
* [90/03/20 20:56:35 rpd]
*
* Revision 2.3 90/01/19 14:37:34 rwd
* Move self pointer to top of stack
* [89/12/12 rwd]
*
* Revision 2.2 89/12/08 19:49:52 rwd
* Back out change from af.
* [89/12/08 rwd]
*
* Revision 2.1.1.3 89/12/06 12:54:17 rwd
* Gap fix from af
* [89/12/06 rwd]
*
* Revision 2.1.1.2 89/11/21 15:01:40 rwd
* Add RED_ZONE ifdef.
* [89/11/20 rwd]
*
* Revision 2.1.1.1 89/10/24 13:00:44 rwd
* Remove conditionals.
* [89/10/23 rwd]
*
* Revision 2.1 89/08/03 17:10:05 rwd
* Created.
*
* 18-Jan-89 David Golub (dbg) at Carnegie-Mellon University
* Altered for stand-alone use:
* use vm_region to probe for the bottom of the initial thread's
* stack.
*
*
* 01-Dec-87 Eric Cooper (ecc) at Carnegie Mellon University
* Changed cthread stack allocation to use aligned stacks
* and store self pointer at base of stack.
* Added inline expansion for cthread_sp() function.
*/
/*
* File: stack.c
* Author: Eric Cooper, Carnegie Mellon University
* Date: Dec, 1987
*
* C Thread stack allocation.
*
*/
#include
#include "cthread_internals.h"
#define BYTES_TO_PAGES(b) (((b) + vm_page_size - 1) / vm_page_size)
int cthread_stack_mask;
private vm_size_t cthread_stack_size;
private vm_address_t next_stack_base;
/*
* Set up a stack segment for a thread.
* Segment has a red zone (invalid page)
* for early detection of stack overflow.
* The cproc_self pointer is stored at the base.
*
* --------- (high address)
* | |
* | ... |
* | |
* | stack |
* | |
* | ... |
* | |
* --------- (stack base)
* | |
* |invalid|
* | |
* ---------
* | |
* | |
* | self |
* --------- (low address)
*/
private void
setup_stack(p, base)
register cproc_t p;
register vm_address_t base;
{
register kern_return_t r;
p->stack_base = base;
/*
* Stack size is segment size minus one int
*/
p->stack_size = cthread_stack_size;
/*
* Protect red zone.
*/
#ifdef RED_ZONE
MACH_CALL(vm_protect(mach_task_self(), base + vm_page_size, vm_page_size, FALSE, VM_PROT_NONE), r);
#endif RED_ZONE
/*
* Store self pointer.
*/
*(cproc_t *)((char *)(base | cthread_stack_mask) - 3) = p;
}
vm_offset_t
addr_range_check(start_addr, end_addr, desired_protection)
vm_offset_t start_addr, end_addr;
vm_prot_t desired_protection;
{
register vm_offset_t addr;
addr = start_addr;
while (addr < end_addr) {
vm_offset_t r_addr;
vm_size_t r_size;
vm_prot_t r_protection,
r_max_protection;
vm_inherit_t r_inheritance;
boolean_t r_is_shared;
memory_object_name_t r_object_name;
vm_offset_t r_offset;
r_addr = addr;
if (vm_region(mach_task_self(),
&r_addr,
&r_size,
&r_protection,
&r_max_protection,
&r_inheritance,
&r_is_shared,
&r_object_name,
&r_offset)
!= KERN_SUCCESS
||
r_addr > addr /* gap */
||
(r_protection & desired_protection)
!= desired_protection
/* not readable */
)
{
return (0);
}
addr = r_addr + r_size;
}
return (addr);
}
/*
* Probe for bottom and top of stack.
* Assume:
* 1. stack grows DOWN
* 2. There is an unallocated region below the stack.
*/
void
probe_stack(stack_bottom, stack_top)
vm_offset_t *stack_bottom;
vm_offset_t *stack_top;
{
/*
* Since vm_region returns the region starting at
* or ABOVE the given address, we cannot use it
* directly to search downwards. However, we
* also want a size that is the closest power of
* 2 to the stack size (so we can mask off the stack
* address and get the stack base). So we probe
* in increasing powers of 2 until we find a gap
* in the stack.
*/
vm_offset_t start_addr, end_addr;
vm_offset_t last_start_addr, last_end_addr;
vm_size_t stack_size;
/*
* Start with a page
*/
start_addr = cthread_sp() & ~(vm_page_size - 1);
end_addr = start_addr + vm_page_size;
stack_size = vm_page_size;
/*
* Increase the tentative stack size, by doubling each
* time, until we have exceeded the stack (some of the
* range is not valid).
*/
do {
/*
* Save last addresses
*/
last_start_addr = start_addr;
last_end_addr = end_addr;
/*
* Double the stack size
*/
stack_size <<= 1;
start_addr = end_addr - stack_size;
/*
* Check that the entire range exists and is writable
*/
} while (end_addr = (addr_range_check(start_addr,
end_addr,
VM_PROT_READ|VM_PROT_WRITE)));
/*
* Back off to previous power of 2.
*/
*stack_bottom = last_start_addr;
*stack_top = last_end_addr;
}
vm_offset_t
stack_init(p)
cproc_t p;
{
vm_offset_t stack_bottom,
stack_top,
start;
vm_size_t size;
kern_return_t r;
void alloc_stack();
/*
* Probe for bottom and top of stack, as a power-of-2 size.
*/
probe_stack(&stack_bottom, &stack_top);
cthread_stack_size = stack_top - stack_bottom;
#ifdef STACK_GROWTH_UP
cthread_stack_mask = ~(cthread_stack_size - 1);
#else STACK_GROWTH_UP
cthread_stack_mask = cthread_stack_size - 1;
#endif STACK_GROWTH_UP
/*
* Guess at first available region for stack.
*/
next_stack_base = 0;
/*
* Set up stack for main thread.
*/
alloc_stack(p);
/*
* Delete rest of old stack.
*/
#ifdef STACK_GROWTH_UP
start = (cthread_sp() | (vm_page_size - 1) + vm_page_size + 1);
size = stack_top - start;
#else STACK_GROWTH_UP
start = stack_bottom;
size = (cthread_sp() & ~(vm_page_size - 1)) - stack_bottom -
vm_page_size;
#endif STACK_GROWTH_UP
MACH_CALL(vm_deallocate(mach_task_self(),start,size),r);
/*
* Return new stack; it gets passed back to the caller
* of cthread_init who must switch to it.
*/
#ifdef STACK_GROWTH_UP
return (p->stack_base + sizeof(int));
#else STACK_GROWTH_UP
return (p->stack_base + p->stack_size - sizeof(int));
#endif STACK_GROWTH_UP
}
/*
* Allocate a stack segment for a thread.
* Stacks are never deallocated.
*
* The variable next_stack_base is used to align stacks.
* It may be updated by several threads in parallel,
* but mutual exclusion is unnecessary: at worst,
* the vm_allocate will fail and the thread will try again.
*/
void
alloc_stack(p)
cproc_t p;
{
vm_address_t base = next_stack_base;
for (base = next_stack_base;
vm_allocate(mach_task_self(), &base, cthread_stack_size, FALSE) != KERN_SUCCESS;
base += cthread_stack_size)
;
next_stack_base = base + cthread_stack_size;
setup_stack(p, base);
}
int cproc_stack_base(cproc, offset)
register cproc_t cproc;
register int offset;
{
#ifdef STACK_GROWTH_UP
return (cproc->stack_base + offset);
#else STACK_GROWTH_UP
return (cproc->stack_base + cproc->stack_size - offset);
#endif STACK_GROWTH_UP
}
void stack_fork_child()
/*
* Called in the child after a fork(). Resets stack data structures to
* coincide with the reality that we now have a single cproc and cthread.
*/
{
next_stack_base = 0;
}
!= KERN_SUCCESS
||
r_addr > addr /* gap */
||
(r_protection & desired_protection)
!= desired_protection
/* not readable */
)
{
return (0);
}
addr = r_addr + r_size;
}
return (addr);
./user/threads/sync.c 444 146 0 3711 4756610013 7747 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: sync.c,v $
* Revision 2.5 91/02/14 14:21:38 mrt
* Added new Mach copyright
* [91/02/13 12:41:42 mrt]
*
* Revision 2.4 90/11/05 14:38:08 rpd
* Fix casting. Use new macros.
* [90/10/31 rwd]
*
* Revision 2.3 90/08/07 14:31:50 rpd
* Removed RCS keyword nonsense.
*
* Revision 2.2 89/12/08 19:55:01 rwd
* Changed spin_lock to spin_lock_solid to optimize.
* [89/11/13 rwd]
* Added copyright. Move mutexes to cproc.c. Spin locks are now
* old mutexes.
* [89/10/23 rwd]
*
*/
/*
* sync.c
*
* Spin locks
*/
#include
#include "cthread_internals.h"
/*
* Spin locks.
* Use test and test-and-set logic on all architectures.
*/
int cthread_spin_count=0;
void
spin_lock_solid(p)
register spin_lock_t *p;
{
while (spin_lock_locked(p) || !spin_try_lock(p)) {
#ifdef STATISTICS
cthread_spin_count++;
#endif
#ifdef SPIN_RESCHED
swtch_pri(0);
#endif
}
}
STACK_GROWTH_UP
/*
* Guess at first available regio./user/threads/i386/ 755 146 0 0 4756607775 7260 ./user/threads/i386/asm.h 444 146 0 6545 4756607765 10305 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: asm.h,v $
* Revision 2.3 91/02/14 14:19:58 mrt
* Changed to new Mach copyright
* [91/02/13 12:15:20 mrt]
*
* Revision 2.2 90/05/03 15:54:33 dbg
* Created.
* [90/04/30 15:39:58 dbg]
*
* Typo on ENTRY if gprof
* [90/03/29 rvb]
* fix SVC for "ifdef wheeze" [kupfer]
* Fix the GPROF definitions.
* ENTRY(x) gets profiled iffdef GPROF.
* Entry(x) (and DATA(x)) is NEVER profiled.
* MCOUNT can be used by asm that intends to build a frame,
* after the frame is built.
* [90/02/26 rvb]
* Add #define addr16 .byte 0x67
* [90/02/09 rvb]
* Added LBi, SVC and ENTRY
* [89/11/10 09:51:33 rvb]
*
* New a.out and coff compatible .s files.
* [89/10/16 rvb]
*
*/
#define S_ARG0 4(%esp)
#define S_ARG1 8(%esp)
#define S_ARG2 12(%esp)
#define S_ARG3 16(%esp)
#define FRAME pushl %ebp; movl %esp, %ebp
#define EMARF leave
#define B_ARG0 8(%ebp)
#define B_ARG1 12(%ebp)
#define B_ARG2 16(%ebp)
#define B_ARG3 20(%ebp)
#ifdef wheeze
#define ALIGN 4
#define EXT(x) x
#define LCL(x) ./**/x
#define LB(x,n) ./**/x
#define LBb(x,n) ./**/x
#define LBf(x,n) ./**/x
#define SVC lcall $7,$0
#define String .string
#define Value .value
#define Times(a,b) [a\*b]
#define Divide(a,b) [a\\b]
#define INB inb (%dx)
#define OUTB outb (%dx)
#define INL inl (%dx)
#define OUTL outl (%dx)
#else wheeze
#define ALIGN 2
#define EXT(x) _/**/x
#define LCL(x) x
#define LB(x,n) n
#define LBb(x,n) n/**/b
#define LBf(x,n) n/**/f
#define SVC .byte 0x9a; .long 0; .word 0x7
#define String .ascii
#define Value .word
#define Times(a,b) (a*b)
#define Divide(a,b) (a/b)
#define INB inb %dx, %al
#define OUTB outb %al, %dx
#define INL inl %dx, %eax
#define OUTL outl %eax, %dx
#endif wheeze
#define data16 .byte 0x66
#define addr16 .byte 0x67
#ifdef GPROF
#define MCOUNT .data; LB(x, 9): .long 0; .text; lea LBb(x, 9),%edx; call mcount
#define ENTRY(x) .globl EXT(x); .align ALIGN; EXT(x): ; \
pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
#define ASENTRY(x) .globl x; .align ALIGN; x: ; \
pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
#else GPROF
#define MCOUNT
#define ENTRY(x) .globl EXT(x); .align ALIGN; EXT(x):
#define ASENTRY(x) .globl x; .align ALIGN; x:
#endif GPROF
#define Entry(x) .globl EXT(x); .align ALIGN; EXT(x):
#define DATA(x) .globl EXT(x); .align ALIGN; EXT(x):
gn stacks.
* It may be updated by several threads in parallel,
* but mutual exclusion is unnecessary: at worst,
* the vm_allocate will fail and the thre./user/threads/i386/csw.s 444 146 0 7270 4756607766 10331 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: csw.s,v $
* Revision 2.4 91/02/14 14:20:02 mrt
* Changed to new Mach copyright
* [91/02/13 12:15:27 mrt]
*
* Revision 2.3 91/01/08 16:46:20 rpd
* Don't use Times - horta doesn't like it for some reason.
* [91/01/06 rpd]
*
* Revision 2.2 90/05/03 15:54:37 dbg
* Created.
* [90/02/05 dbg]
*
*/
#include
/*
* Suspend the current thread and resume the next one.
*
* void cproc_switch(int *cur, int *next, int *lock)
*/
ENTRY(cproc_switch)
pushl %ebp / save ebp
movl %esp,%ebp / set frame pointer to get arguments
pushl %ebx / save ebx
pushl %esi / esi
pushl %edi / edi
movl B_ARG0,%eax / get cur
movl %esp,(%eax) / save current esp
movl B_ARG2,%edx / get address of lock before switching
/ stacks
movl B_ARG1,%eax / get next
movl (%eax),%esp / get new stack pointer
movl $0,(%edx) / clear lock - now old thread can run
popl %edi / restore di
popl %esi / si
popl %ebx / bx
popl %ebp / and bp (don't use "leave" - bp
/ still points to old stack)
ret
/*
* Create a new stack frame for a 'waiting' thread,
* save current thread's frame, and switch to waiting thread.
*
* void cproc_start_wait(int *cur,
* cproc_t child,
* int stackp,
* int *lock)
*/
ENTRY(cproc_start_wait)
pushl %ebp / save ebp
movl %esp,%ebp / set frame pointer
pushl %ebx / save ebx
pushl %esi / esi
pushl %edi / edi
movl B_ARG0,%eax / get cur
movl %esp,(%eax) / save current esp
movl B_ARG1,%eax / get child thread
movl B_ARG3,%edx / point to lock before switching stack
movl B_ARG2,%esp / get new stack
pushl %eax / push child thread as argument
movl $0,%ebp / (clear frame pointer)
movl $0,(%edx) / unlock lock
call _cproc_waiting / call cproc_waiting
/*NOTREACHED*/
/*
* Set up a thread's stack so that when cproc_switch switches to
* it, it will start up as if it called
* cproc_body(child)
*
* void cproc_prepare(cproc_t child, int *context, int stack)
*/
ENTRY(cproc_prepare)
pushl %ebp / save ebp
movl %esp,%ebp / set frame pointer
movl B_ARG2,%edx / get child's stack
subl $28,%edx
/ make room for context:
/ 0 saved edi ()
/ 4 saved esi ()
/ 8 saved ebx ()
/ 12 saved ebp ()
/ 16 return PC from cproc_switch
/ 20 return PC from cthread_body
/ 24 argument to cthread_body
movl $0,12(%edx) / clear frame pointer
movl $_cthread_body,16(%edx)
/ resume at cthread_body
movl $0,20(%edx) / fake return address from cthread_body
movl B_ARG0,%ecx / get child thread pointer
movl %ecx,24(%edx) / set as argument to cthread_body
movl B_ARG1,%ecx / get pointer to context
movl %edx,(%ecx) / save context
leave
ret
size, FALSE) != KERN_SUCCESS;
base += cthread_stack_size)
;
next_stack_base = base + cthread_stack_size;
setup_stack(p, base);
}
int cproc_stack_base(cproc, offset)
register cproc_t cproc;
register int offset;
{
#ifdef STACK_GROWTH_UP
return (cproc->stack_base + offset);
#else STACK_GROWTH_UP
return (cproc->stac./user/threads/i386/cthread_inline.awk 444 146 0 4312 4756607767 13020 #
# Mach Operating System
# Copyright (c) 1991,1990 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
# 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 [email protected]
# 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.
#
#
# HISTORY
# $Log: cthread_inline.awk,v $
# Revision 2.3 91/02/14 14:20:06 mrt
# Added new Mach copyright
# [91/02/13 12:33:05 mrt]
#
# Revision 2.2 90/05/03 15:54:56 dbg
# Created (from 68020 version).
# [90/02/05 dbg]
#
# Revision 2.2 89/12/08 19:54:30 rwd
# Inlines are now spins instead of mutexes.
# [89/10/23 rwd]
#
# Revision 2.1 89/08/04 15:15:14 rwd
# Created.
#
# Revision 1.3 89/05/05 19:00:33 mrt
# Cleanup for Mach 2.5
#
#
# sun/cthread_inline.awk
#
# Awk script to inline critical C Threads primitives on i386
NF == 2 && $1 == "call" && $2 == "_spin_try_lock" {
print "/ BEGIN INLINE spin_try_lock"
print " movl (%esp),%ecx / point at mutex"
print " movl $1,%eax / set locked value in acc"
print " xchg %eax,(%ecx) / locked swap with mutex"
print " xorl $1,%eax / logical complement"
print "/ END INLINE spin_try_lock"
continue
}
NF == 2 && $1 == "call" && $2 == "_spin_unlock" {
print "/ BEGIN INLINE " $2
print " movl (%esp),%ecx"
print " movl $0,(%ecx)"
print "/ END INLINE " $2
continue
}
NF == 2 && $1 == "call" && $2 == "_cthread_sp" {
print "/ BEGIN INLINE cthread_sp"
print " movl %esp,%eax"
print "/ END INLINE cthread_sp"
continue
}
# default:
{
}
ointer)
movl $0,(%edx) / unlock lock
call _cproc_waiting / call cproc_waiting
/*NOTREACHED*/
/*
* Set up a thread's stack so that when cproc_switch switches to
* it, it will start up as if it called
* cproc_body(child)
*
* void cproc_prepare(cproc_t child, int *context, int stack)
*/
ENTRY(cproc_pre./user/threads/i386/cthreads.h 444 146 0 2707 4756607770 11312 /*
* Mach Operating System
* Copyright (c) 1991,1990 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: cthreads.h,v $
* Revision 2.3 91/02/14 14:20:14 mrt
* Changed to new Mach copyright
* [91/02/13 12:20:00 mrt]
*
* Revision 2.2 90/11/05 14:37:23 rpd
* Created.
* [90/11/01 rwd]
*
*
*/
#ifndef _MACHINE_CTHREADS_H_
#define _MACHINE_CTHREADS_H_
typedef int spin_lock_t;
#define SPIN_LOCK_INITIALIZER 0
#define spin_lock_init(s) *(s)=0
#define spin_lock_locked(s) (*(s) != 0)
#endif _MACHINE_CTHREADS_H_
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE ./user/threads/i386/lock.s 444 146 0 3250 4756607772 10454 /*
* Mach Operating System
* Copyright (c) 1991,1990 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: lock.s,v $
* Revision 2.3 91/02/14 14:20:18 mrt
* Changed to new Mach copyright
* [91/02/13 12:20:06 mrt]
*
* Revision 2.2 90/05/03 15:54:59 dbg
* Created.
* [90/02/05 dbg]
*
*/
#include
/*
* boolean_t spin_try_lock(int *m)
*/
ENTRY(spin_try_lock)
movl 4(%esp),%ecx / point at mutex
movl $1,%eax / set locked value in acc
xchg %eax,(%ecx) / swap with mutex
/ xchg with memory is automatically
/ locked
xorl $1,%eax / 1 (locked) => FALSE
/ 0 (locked) => TRUE
ret
/*
* void spin_unlock(int *m)
*/
ENTRY(spin_unlock)
movl 4(%esp),%ecx / point at mutex
movl $0,(%ecx) / zero it
ret
mutex"
print " movl $1,%eax / set locked value in acc"
print " xchg %eax,(%ecx) / locked swap with mutex"
print " xorl $1,%eax / logical complement"
print "/ END INLINE spin_try_lock"
continue
}
NF == 2 && $1 == "call" && $2 == "_spin_unlock" {
print "/ BEGIN INLINE " $2
print " movl (%esp),%ecx"
print " movl $0,(%ecx)"
print "/ EN./user/threads/i386/thread.c 444 146 0 5125 4756607774 10760 /*
* Mach Operating System
* Copyright (c) 1991,1990 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: thread.c,v $
* Revision 2.4 91/02/14 14:20:21 mrt
* Changed to new Mach copyright
* [91/02/13 12:20:10 mrt]
*
* Revision 2.3 90/06/02 15:13:53 rpd
* Added definition of cthread_sp.
* [90/06/02 rpd]
*
* Revision 2.2 90/05/03 15:55:03 dbg
* Created (from 68020 version).
* [90/02/05 dbg]
*
*/
/*
* i386/thread.c
*
*/
#ifndef lint
static char rcs_id[] = "$Header: thread.c,v 2.4 91/02/14 14:20:21 mrt Exp $";
#endif not lint
#include
#include "cthread_internals.h"
#include
/*
* C library imports:
*/
extern bzero();
int
cthread_sp()
{
int x;
return (int) &x;
}
/*
* Set up the initial state of a MACH thread
* so that it will invoke cthread_body(child)
* when it is resumed.
*/
void
cproc_setup(child, thread, routine)
register cproc_t child;
int thread;
int routine;
{
register int *top = (int *) (child->stack_base + child->stack_size);
struct i386_thread_state state;
register struct i386_thread_state *ts = &state;
kern_return_t r;
unsigned int count;
/*
* Set up i386 call frame and registers.
* Read registers first to get correct segment values.
*/
count = i386_THREAD_STATE_COUNT;
MACH_CALL(thread_get_state(thread,i386_THREAD_STATE,(thread_state_t) &state,&count),r);
ts->eip = routine;
*--top = (int) child; /* argument to function */
*--top = 0; /* fake return address */
ts->uesp = (int) top; /* set stack pointer */
ts->ebp = 0; /* clear frame pointer */
MACH_CALL(thread_set_state(thread,i386_THREAD_STATE,(thread_state_t) &state,i386_THREAD_STATE_COUNT),r);
}
BEGIN INLINE cthread_sp"
print " movl %esp,%eax"
print "/ END INLINE cthread_sp"
continue
}
# default:
{
}
ointer)
movl $0,(%edx) / unlock lock
call _cproc_waiting / call cproc_waiting
/*NOTREACHED*/
/*
* Set up a thread's stack so that when cproc_switch switches to
* it, it will start up as if it called
* cproc_body(child)
*
* void cproc_prepare(cproc_t child, int *context, int stack)
*/
ENTRY(cproc_pre./user/threads/i386_mach 755 146 0 0 4756612156 10612 2i386 ./user/threads/mips/ 755 146 0 0 4756613417 7525 ./user/threads/mips/csw.s 444 146 0 10431 4756607777 10623 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: csw.s,v $
* Revision 2.5 91/02/14 14:20:35 mrt
* Added new Mach copyright
* [91/02/13 12:38:39 mrt]
*
* Revision 2.4 90/06/02 15:14:09 rpd
* Added definition of cthread_sp.
* [90/04/24 rpd]
*
* Revision 2.3 89/12/08 19:49:17 rwd
* Changes for new cthreads from af
* [89/12/06 rwd]
*
* Revision 2.2 89/11/29 14:18:59 af
* Created.
* [89/07/06 af]
*
*/
/*
* pmax/csw.s
*
* Context switch and cproc startup for MIPS COROUTINE implementation.
*/
#include
.text
.align 2
#define ARG_SAVE (4*4)
#define SAVED_S0 (4*4)
#define SAVED_S1 (5*4)
#define SAVED_S2 (6*4)
#define SAVED_S3 (7*4)
#define SAVED_S4 (8*4)
#define SAVED_S5 (9*4)
#define SAVED_S6 (10*4)
#define SAVED_S7 (11*4)
#define SAVED_FP (12*4)
#define SAVED_PC (13*4)
#define SAVED_BYTES (14*4)
/*
* Suspend the current thread and resume the next one.
*
* void
* cproc_switch(cur, next, lock)
* int *cur;
* int *next;
* simple_lock *lock;
*/
LEAF(cproc_switch)
subu sp,sp,SAVED_BYTES # allocate space for 10 registers
# Save them registers
sw ra,SAVED_PC(sp)
sw fp,SAVED_FP(sp)
sw s0,SAVED_S0(sp)
sw s1,SAVED_S1(sp)
sw s2,SAVED_S2(sp)
sw s3,SAVED_S3(sp)
sw s4,SAVED_S4(sp)
sw s5,SAVED_S5(sp)
sw s6,SAVED_S6(sp)
sw s7,SAVED_S7(sp)
sw sp,0(a0) # save current sp
lw sp,0(a1) # restore next sp
# Reload them registers
lw ra,SAVED_PC(sp)
lw fp,SAVED_FP(sp)
lw s0,SAVED_S0(sp)
lw s1,SAVED_S1(sp)
lw s2,SAVED_S2(sp)
lw s3,SAVED_S3(sp)
lw s4,SAVED_S4(sp)
lw s5,SAVED_S5(sp)
lw s6,SAVED_S6(sp)
lw s7,SAVED_S7(sp)
# return to next thread
sw zero,0(a2) # clear lock
addu sp,sp,SAVED_BYTES
j ra
END(cproc_switch)
/*
* void
* cproc_start_wait(parent_context, child, stackp, lock)
* int *parent_context;
* cproc_t child;
* int stackp;
* simple_lock *lock;
*/
NESTED(cproc_start_wait, SAVED_BYTES, zero)
subu sp,sp,SAVED_BYTES # allocate space for 10 registers
# Save parent registers
sw ra,SAVED_PC(sp)
sw fp,SAVED_FP(sp)
sw s0,SAVED_S0(sp)
sw s1,SAVED_S1(sp)
sw s2,SAVED_S2(sp)
sw s3,SAVED_S3(sp)
sw s4,SAVED_S4(sp)
sw s5,SAVED_S5(sp)
sw s6,SAVED_S6(sp)
sw s7,SAVED_S7(sp)
sw sp,0(a0) # save parent sp
sw zero,0(a3) # release lock
move sp,a2 # get child sp
subu sp,sp,4*4 # standard regsave
move a0,a1
jal cproc_waiting # cproc_waiting(child)
/*
* Control never returns here.
*/
END(cproc_start_wait)
/*
* void
* cproc_prepare(child, child_context, stack)
* int *child_context;
* int *stack;
*/
LEAF(cproc_prepare)
subu a2,ARG_SAVE # cthread_body's fake frame
sw a0,0(a2) # cthread_body(child)
subu a2,SAVED_BYTES # cproc_switch's ``frame''
sw s0,SAVED_S0(a2)
sw s1,SAVED_S1(a2)
sw s2,SAVED_S2(a2)
sw s3,SAVED_S3(a2)
sw s4,SAVED_S4(a2)
sw s5,SAVED_S5(a2)
sw s6,SAVED_S6(a2)
sw s7,SAVED_S7(a2)
sw fp,SAVED_FP(a2)
sw a2,0(a1) # child context
la v0,1f
sw v0,SAVED_PC(a2)
j ra
/*
* The reason we are getting here is to load
* arguments in registers where they are supposed
* to be. The code above only put the argument(s)
* on the stack, now we'll load them.
*/
1: la v0,cthread_body
lw a0,0(sp)
j v0
END(cproc_prepare)
/*
* int
* cthread_sp()
*
* Returns the current stack pointer.
*/
LEAF(cthread_sp)
move v0, sp
j ra
END(cthread_sp);
ssion 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 SOFT./user/threads/mips/cthread_inline.awk 444 146 0 3520 4756610000 13245 #
# Mach Operating System
# Copyright (c) 1991,1990,1989 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
# 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 [email protected]
# 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.
#
#
# HISTORY
# $Log: cthread_inline.awk,v $
# Revision 2.4 91/02/14 14:20:40 mrt
# Added new Mach copyright
# [91/02/13 12:38:45 mrt]
#
# Revision 2.3 89/12/08 19:49:36 rwd
# Remove mutex_unlock
# [89/12/06 rwd]
#
# Revision 2.2 89/11/29 14:19:05 af
# Oooops, a typo. I mean, this file _really_ is unnecessary..
# [89/10/28 af]
#
# Created.
# [89/07/06 af]
#
# pmax/cthread_inline.awk
#
# Awk script to inline critical C Threads primitives on MIPS.
# This is not really needed, but there it goes anyways.
#
NF == 2 && $1 == "jal" && $2 == "spin_unlock" {
print " # BEGIN INLINE " $2
print " sw $0,0($4)"
print " # END INLINE " $2
continue
}
NF == 2 && $1 == "jal" && $2 == "cthread_sp" {
print " # BEGIN INLINE cthread_sp"
print " move $2,$29"
print " # END INLINE cthread_sp"
continue
}
# default:
{
}
define SAVED_BYTES (14*4)
/*
* Suspend the current thread and resume the next one.
*
* void
* cproc_switch(cur, next, lock)
* int *cur;
* int *next;
* simple_lock *l./user/threads/mips/cthreads.h 444 146 0 2677 4756610001 11554 /*
* Mach Operating System
* Copyright (c) 1991,1990 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: cthreads.h,v $
* Revision 2.3 91/02/14 14:20:50 mrt
* Added new Mach copyright
* [91/02/13 12:38:50 mrt]
*
* Revision 2.2 90/11/05 14:37:42 rpd
* Created.
* [90/11/01 rwd]
*
*/
#ifndef _MACHINE_CTHREADS_H_
#define _MACHINE_CTHREADS_H_
typedef int spin_lock_t;
#define SPIN_LOCK_INITIALIZER 0
#define spin_lock_init(s) *(s)=0
#define spin_lock_locked(s) (*(s) != 0)
#endif _MACHINE_CTHREADS_H_
ghts to redistribute these changes.
#
#
# HISTORY
# $Log: cthread./user/threads/mips/lock.s 444 146 0 44373 4756610002 10742 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: lock.s,v $
* Revision 2.5 91/02/14 14:20:54 mrt
* Added new Mach copyright
* [91/02/13 12:38:54 mrt]
*
* Revision 2.4 90/01/22 23:09:49 af
* Conditionalized timing functions.
* [90/01/20 17:34:21 af]
*
* Revision 2.3 89/12/08 19:49:24 rwd
* Reflected rwd's name changes.
* [89/12/06 af]
*
* Revision 2.2 89/11/29 14:19:08 af
* New name for tas, fixed timing functions.
* [89/10/28 12:11:22 af]
*
* Turned into a piece of literate programming.
* Therefore:
* Copyright (c) 1989 Alessandro Forin
* [89/07/16 af]
*
* Created.
* [89/07/06 af]
*
*/
/*
* File: pmax/lock.s
Test-And-Set instructions for MIPS.
Abstract
The MIPS instruction set does not include any
interlocked instruction to provide synchronization
in parallel programs. We provide two different
implementations of a non-blocking lock/unlock pair
despite this limitation.
1. Introduction
There are basically two possible types of solutions. Either
we invoke help from the Operating System or we find some clever
algorithm that does not require any intelocked instruction.
Obviously, a solution in the second class looks more appealing
for performance reasons. It is unlikely that a solution in the
first class could avoid e.g. trapping in the OS kernel which is
usually a very expensive operation. Note, however, that MIPS
provides a pretty fast trapping mechanism so things are not
all black-and-white and some measurements might be necessary
in order to asses what the best choice is.
The first approach includes, for instance, providing some
proper addition to the MIPS instruction set via software emulation.
The idea is to use some invalid instruction opcode which therefore
generates an Illegal Instruction trap. The OS handler for this trap
checks for the special opcode, and in case it changes the state
of the user program so that the proper semantic of our pseudo-instruction
is realized.
The second approach means a trip to the library to browse through
the literature to see whether some published algorithm does have
the special property we need. Or, inventing a new algorithm if
no suitable one can be found.
The first idea requires a minumum amount of work so it was quickly
realized. It is therefore described at the beginning of this file,
in Chapter 2. The second idea was also pursued with success, albeit
in a little more time. Chapter 3 describes how we found a (presumably)
new algorithm with the necessary properties by modifying an existing one.
2. Sofware Emulation
Since we decide to go for emulation, we can chose basically anything
we please. All is needed, however, is a simple non-blocking lock and
the obvious choice is therefore a Test-And-Set instruction. To make
things as simple as possible (speed comes first) the semantic is the
following. TAS operates on a single register which holds the address
of the lock. The previous content of the lock will be returned in that
same register, and the lock itself will contain some non-zero value.
Since the compiler will never generate this instruction, we'll further
restrict the instruction to only operate on one particular register,
register "a0".
Implementing the user part is trivial. All we need is an assembly
function that uses the new opcode that we will add to the MIPS
instruction set.
*/
#include
#include
/*
The C interface for this function is
boolean_t
spin_try_lock_sw(m)
int * m;
The function has a slightly different semantics than TAS: it will
return a boolean value that indicates whether the lock was acquired
or not. If not, we'll presume that the user will retry after some
appropriate delay.
*/
.text
.align 2
.set noreorder
LEAF(spin_try_lock)
move v0,a0 # preserve a0's content
.word op_tas # do the TAS
j ra # return whether the
xor v0,a0,v0 # lock was acquired
END(spin_try_lock)
LEAF(spin_unlock)
j ra
sw zero,0(a0)
END(spin_unlock)
.set reorder
/*
We make use here of one more piece of information: the value
that TAS puts in the lock is the address of the lock itself.
This makes things fit into four instructions, but adding a
branch instruction would only waste one extra cycle and buy
more generality. A truly general purpose implementation would
also follow a test&TAS scheme, by testing the content of the
lock before executing the (expensive) TAS instruction.
In our case though, it is known that the CThreads wrapping
for this function already does that before calling the function
itself. The unlock primitive is quite strightforward. Note
only that the existing code in the CThreads package already
makes machine-independent assumptions about the value (and size!)
of a lock, so there really is no choice here.
Now we need only to implement the instruction in the kernel, after
deciding which opcode we should employ.
Note that the class of "special" opcodes is the most suitable
one since it already includes instructions like syscall and break
that do not fit in any other general category. Curiously enough, in that
same class there is a sub-opcode for an instruction named "vcall"
which is neither described in [Kane 88] which is our reference book
for the MIPS instruction set, nor appears to do anything but generate
an Illegal Instruction exception when tested on a DECStation 3100.
Our choice then is the very next sub-opcode
#define op_tas 0x0F
which we add to the original "inst.h" file.
The next thing is to write a trap handler for the Illegal Instruction
trap. Currently the VEC_trap() handler is in charge of handling this
exception too. By modifying the dispatch table appropriately
extern VEC_syscall(), VEC_cpfault(), VEC_trap(), VEC_int(), VEC_tlbmod();
extern VEC_tlbmiss(), VEC_breakpoint(), VEC_addrerr(), VEC_ibe(), VEC_dbe();
extern VEC_ill_instr();
extern VEC_unexp();
int (*causevec[16])() = {
-* 0: EXC_INT *- VEC_int,
-* 1: EXC_MOD *- VEC_tlbmod,
-* 2: EXC_RMISS *- VEC_tlbmiss,
-* 3: EXC_WMISS *- VEC_tlbmiss,
-* 4: EXC_RADE *- VEC_addrerr,
-* 5: EXC_WADE *- VEC_addrerr,
-* 6: EXC_IBE *- VEC_ibe,
-* 7: EXC_DBE *- VEC_dbe,
-* 8: EXC_SYSCALL *- VEC_syscall,
-* 9: EXC_BREAK *- VEC_breakpoint,
-* 10: EXC_ILL *- VEC_ill_instr,
-* 11: EXC_CPU *- VEC_cpfault,
-* 12: EXC_OV *- VEC_trap,
-* 13: undefined *- VEC_unexp,
-* 14: undefined *- VEC_unexp,
-* 15: undefined *- VEC_unexp
};
we can easily add our new VEC_ill_instr() handler, which we'll
add to the kernel's file of low-level operations.
The handler proper is as follows.
VECTOR(VEC_ill_instr, M_EXCEPT)
.set reorder
Check whether this is an emulated instruction or not.
lw ra,EF_EPC*4(sp) # get user's PC
li a2,op_tas
lw a0,0(ra) # get the instruction proper
bne a0,a2,truly_ill # is this our TAS
Now that it is clear that it is precisely a TAS instruction,
all we need to do is to keep interrupts disabled while we emulate
it, and guard against faults.
lw a0,EF_A0*4(sp) # Get address of lock
# Protect against malicious uses, like
bgt a0,zero,addr_ok # sneaking into kernel space
sw a0,EF_BADVADDR*4(sp) # Give an exception to
li a1,SEXC_ILL # the sneaker.
b truly_ill
addr_ok:
Use the nofault trick e.g. if we fault on a bad
user address we'll endup (by magic) in uaerror() below
li a2,NF_USERACC
sw a2,nofault
Now it should be safe to proceed.
There is a subtle semantic question about a TAS
if it fails: does it actually write or not ?
For instance, should a user that does a tas
on e.g. his protected text segment get a bus error or not ?
Both choices are easy to provide, so we'll define a
compile time switch to choose among them.
lw a2,0(a0) # .. TEST ..
#ifdef tas_may_not_write
bne a2,zero,1f # .. AND ..
sw a0,0(a0) # .. SET
#else tas_may_not_write
The default behaviour is indeed to perform the write
anyways, which should make it easier for users to
debug their mistakes.
sw a0,0(a0) # .. AND SET
#endif tas_may_not_write
1: sw a2,EF_A0*4(sp) # return the result still in a0
sw zero,nofault
All done, increment PC and return
addiu ra,4 # increment user's PC
sw ra,EF_EPC*4(sp)
b exception_exit
truly_ill:
move a0,sp
b VEC_trap
END(VEC_ill_instr)
LEAF(uaerror)
User gave a bad address. Give him a SEGV in trap()
that stems from a write miss.
li a1,SEXC_SEGV
li a3,EXC_WMISS
sw a3,EF_CAUSE*4(sp)
b truly_ill
END(uaerror)
2.1 Performance
The user side of the primitive costs 4 cycles. This is easy
to see since a call to this function (after checking that
the lock is free) will find the lock in the cache, so we'll
take precisely one cycle per instruction.
The kernel part is instead much more complicated. There we
have to consider the average effects of page faults, misses
in the TLB etc etc. The simplest and most effective measure
is therefore an actual run of some test program. We did that
by repeatedly calling the spin_try_lock_sw() function
and the result is about 9 microseconds per call, or 138 cycles
on a DECStation 3100. Clearly the costs on the user side are
a minor fraction of the total cost.
3 A New Algorithm
A quick look at the literature produced an interesting finding.
Lamport's article [Lamport 88] on formal correctness proofs of
parallel programs contains a small fragment of code which is
very interesting. The example at page ??? provides precisely
mutual exclusion among N processes and without requiring any
hardware support other that atomic load and store operations
on memory, which are available on all sensible memory systems.
There are limits in the code, however, that will have to be
overcome. For instance, as described the code will block
forever all of the processes but the one that acquires the lock,
should conflict arise. We are not overly concerned about
issues such as liveness and fairness: it is most certainly possible
to prove that some scheduling sequences might theoretically
generate livelocks, but these in practice will not arise
because of the large number of factors that affect scheduling
of user programs on a real multiprocessor.
Moreover, our initial target machines are all uniprocessor.
Our first attempt at modifying the code as follows fails.
1 x = me
2 if (y != -1) return FAIL
3 y = me
4 if (x != me) return FAIL
5 return SUCCESS
The idea came from flying on an oversold flight to Pittsburgh:
line 1 is doing the check-in at the gate, line 4 is actually
checking the seat on the airplane. It took six hours to that
flight to get from NewYork to Pittsburgh, and it was not
the algorithm's fault ! But we had time for thinking..
The failure sequence for the algorithm (which does happen about
2 in a million times on a DECStation 3100 running Mach) is
A12 B1 A34
where A and B denote two different processes. This sequence
will leave the lock busy but return FAIL to both processes.
Note that there is still the guarantee, proved by Lamport,
that only one process at a time will ever get to execute 5.
This is because the basic idea is that the last process to
take the reservation at line 1 is the favored one to acquire
the lock. Unfair maybe, but works. Even on airplanes!
Therefore the following variation over the original code
should do the trick for us.
1 x = me
2 if (y != -1) return FAIL
3 z = me
4 if (x != me) return FAIL
5 y = me
6 if (z != me) return FAIL
7 return SUCCESS
Note that we introduced one more variable, which basically
acts as the "reservation for the reservation". So in our
airline methaphor we'd go to the ticket counter to check
our seats (line 1-2), and maybe change flight if it is oversold.
Then we'd go to the gate for control (lines 3-4)
and finally get to our seat in the airplane (lines 5-6).
We can only, however, make guarantees for our computer programs
and not for airline companies, so Caveat User!
As far as the unlocking primitive we will stick to the above
function. This is because of the above mentioned constrain
that CThreads imposes e.g. that a free lock be an integer of
size 32 bits and value 0. This has also another subtle implication
on our algorithm: We cannot just "return FAIL" at lines 4 and 6.
If we did so we would live the lock free allright, but the cover
code would notice that that some reserve field is non-zero and
mistake that for a busy lock! Since those failures are due to
a collision between two processes in the attempt to acquire an
otherwise free lock, it is certainly within the semantics of
"try to acquire the lock" that we only give up when the lock
is really busy. Our fix therefore is to substitute the return
statements with a jump back to line 1, which is what the cover
code should have done anyways.
Coding the function in assembly is quite straightforward,
except for noting that we have to (a) fit everything in a
32 bit word and (b) make a 32 bit "0" the value of an
empty lock. The first requirement is easy to accomodate,
splitting the word as follows:
16 8 8
-------------------------
| y | x | z |
-------------------------
This is because MIPS provides both 8/16/32 bit load and store
operations.
The second requirement is also easy, since the values of the
extra x and z fields do not really matter as long as we do not
allow "0" to be the identifier of any of the processes.
So for our purposes a lock can be defined as
typedef struct {
unsigned int
busy : 16,
res1 : 8,
res2 : 8;
} spin;
*/
# define busy 0
# define res1 2
# define res2 3
.align 2
.set noreorder
/*
Here is our final and preferred implementation for
boolean_t
spin_try_lock(m)
spin * m;
*/
LEAF(spin_try_lock_unsafe)
#define my_id t0
# We need to generate an ID on the fly. Using the stack pointer is
# ok, but note that we can only extract 8bits from it. We think that
# the uppermost 2nd and 3rd nibbles should be a reliable choice, but
# it still is a quite arbitrary one.
sll my_id,sp,4
srl my_id,my_id,24
again:
sb my_id,res1(a0) # line 1
lhu t1,busy(a0) # line 2
nop
beq t1,zero,1f
nop
bne t1,my_id,fail
1:
# The delay slot in this branch can be filled by the
# next instruction.
sb my_id,res2(a0) # line 3
lbu t1,res1(a0) # line 4
nop
bne t1,my_id,again
# Ditto
sh my_id,busy(a0) # line 5
lbu t1,res2(a0) # line 6
nop
bne t1,my_id,again
nop
pass: # line 7
j ra
li v0,1
fail:
j ra
move v0,zero
#undef my_id
END(spin_try_lock_sw)
/*
3.1 Performance
Should be 14 stright cycles in the good outcome,
since we do 3 loads and 3 stores but on the same
cache line, actually the same word. The cache should
not miss, because as explained above the value of the
lock was tested right before invoking this function.
In reality, the cache is write-through rather than
write-back and moreover our 3 store instructions are
nicely separated by 2 intervening instructions each.
Therefore the MIPS write-buffer will not always be
able to shrink them into one single store to memory.
The actually measured number is infact 35 cycles in
the good outcome and 19 on a busy lock.
This still compares very well with the 138 cycles
of the "firmware" solution. Moreover, in case the
lock is actually busy this last implementation takes
less time. On collisions the number of (nominal) cycles is
14 + 7N + 11M, depending on where the collision is detected.
Testing on the DECStation 3100 reveals that collisions are
quite rare (less than one in a million). A true multiprocessor
machine is then needed to asses their frequency and relevance
when processes are really executing concurrently.
4 Conclusions
The problem of providing a mutual exclusion primitive
without hardware support was analyzed. Two different
approaches, namely provide support in the Operating
System or find a user-level suitable algorithm, were both
explored successfully. Two real-word working solutions
were described in detail, and their performance compared.
A new algorithm, derived from one by Lamport, was presented,
implemented on the MIPS processor, and tested.
The algorithmic solution proves to be about 4 times faster
that the one that receives support from the OS.
5. Bibliography
[Kane 88]
Gerry Kane
"mips RISC Architecture"
Prentice Hall, NJ, 1988
[Lamport 88]
Leslie Lamport
"Control Predicatres are Better than Dummy Variables
for Reasoning about Program Control"
ACM TOPLAS, Vol. 10-2, April 1988, pp. 267-281
*/
#ifdef TIMEIT
.set noreorder
#define FRAME (4*4)
NESTED(time_spin_try_lock_sw, FRAME, s0)
move s0,ra
move a2,a0
1: move a0,a2
sw zero,0(a0)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
jal spin_try_lock_sw
subu a1,a1,1
bne a1,zero,1b
nop
move ra,s0
j ra
END(time_spin_try_lock_sw)
NESTED(time_spin_try_lock, FRAME, s0)
move s0,ra
move a2,a0
1: jal spin_try_lock
move a0,a2
sw zero,0(a0)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
subu a1,a1,1
bne a1,zero,1b
nop
move ra,s0
j ra
END(time_spin_try_lock)
#endif TIMEIT
---------------------
| y | x | z |
-------------------------
This is because MIPS provides both 8/16/32 bit load and store
operations.
The second requirement is also easy, since the values of the
extra x and z fields do not really matter./user/threads/mips/thread.c 444 146 0 5334 4756610003 11214 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: thread.c,v $
* Revision 2.4 91/02/14 14:20:59 mrt
* Added new Mach copyright
* [91/02/13 12:39:03 mrt]
*
* Revision 2.3 89/12/08 19:49:44 rwd
* Changed to take an arbitrary starting routine and an arbitrary
* thread, for use with rwd's new merged coroutine/thread kernel
* implementation. Removed conditionals.
* [89/12/06 af]
*
* Revision 2.2 89/11/29 14:19:12 af
* Created.
* [89/07/06 af]
*
*/
/*
* mips/thread.c
*
* Cproc startup for MIPS Cthreads implementation.
*/
#ifndef lint
static char rcs_id[] = "$Header: thread.c,v 2.4 91/02/14 14:20:59 mrt Exp $";
#endif not lint
#include
#include "cthread_internals.h"
#include
/*
* C library imports:
*/
extern bzero();
/*
* Set up the initial state of a MACH thread
* so that it will invoke routine(child)
* when it is resumed.
*/
void
cproc_setup(child, thread, routine)
register cproc_t child;
int thread;
int routine;
{
register int *top = (int *) (child->stack_base + child->stack_size);
struct mips_thread_state state;
register struct mips_thread_state *ts = &state;
kern_return_t r;
extern int _gp; /* ld(1) defines this */
/*
* Set up MIPS call frame and registers.
* See MIPS Assembly Language Reference Book.
*/
bzero((char *) ts, sizeof(struct mips_thread_state));
/*
* Set pc to procedure entry, pass one arg in register,
* allocate the standard 4 regsave stack frame.
* Give as GP value to the thread the same we have.
*/
ts->pc = routine;
ts->r4 = (int) child;
ts->r29 = ((int) top) - 4 * sizeof(int);
ts->r28 = (int) &_gp;
MACH_CALL(thread_set_state(thread,MIPS_THREAD_STATE,(thread_state_t) &state,MIPS_THREAD_STATE_COUNT),r);
}
A new algorithm, derived from one by Lamport, was presented,
implemented on the MIPS processor, and tested.
The algorithmic solution proves to be about 4 times faster
that the one that receives support from the OS.
5. Bibliography
[Kane 88]
Gerry Kane
"mips RISC Architect./user/threads/pmax_mach 755 146 0 0 4756612402 11337 2mips ./MERGE_HISTORY 444 146 0 215524 4756607445 6310
==========================================================================
***** MK Version MK31 (rwd) *****
New features:
--- --------
Debugger has watchpoints. Breakpoints are map specific. New software
reference bit code which is currently turned off by default.
Bug fixes:
--- -----
Yes
[I386] All references to AT386 in makefiles have been duplicated to I386.
Special notes:
------- -----
This merge was done with /afs/cs/project/mach/mach3/tools/bin/m3merge.
mkmerge is dead. long live m3merge.
******** CUT HERE ******** summary of log messages ******** CUT HERE ********
[ ./conf/version.edit ]
31
[ ./Makefile ]
Don't make clean include area.
[90/10/24 rwd]
[ ./kernel/boot_ufs/boot_printf.c ]
Modified boot_gets to allocate arrays from heap, not stack.
[90/10/23 rpd]
[ ./kernel/boot_ufs/file_io.c ]
Modified open_file to allocate arrays from heap, not stack.
[90/10/23 rpd]
[ ./kernel/boot_ufs/load.c ]
Modified boot_load_program and read_emulator_symbols
to allocate arrays from heap, not stack.
[90/10/23 rpd]
[ ./MERGE_HISTORY ]
Created
[ ./kernel/conf/Makefile.template ]
[ ./kernel/conf/files ]
Added ddb/db_watch.c.
[90/10/16 rpd]
[ ./kernel/ddb/db_break.c ]
Added map field to breakpoints.
Added map argument to db_set_breakpoint, db_delete_breakpoint,
db_find_breakpoint. Added db_find_breakpoint_here.
[90/10/18 rpd]
[ ./kernel/ddb/db_break.h ]
Added map field to breakpoints.
[90/10/18 rpd]
[ ./kernel/ddb/db_command.c ]
Changed db_fncall to print the result unsigned.
[90/10/19 rpd]
Added CS_MORE to db_watchpoint_cmd.
[90/10/17 rpd]
Added watchpoint commands: watch, dwatch, show watches.
[90/10/16 rpd]
[ ./kernel/ddb/db_print.c ]
Changed db_show_regs to print unsigned.
[90/10/19 rpd]
Generalized the watchpoint support.
[90/10/16 rwd]
[ ./kernel/ddb/db_run.c ]
Changed db_find_breakpoint to db_find_breakpoint_here.
[90/10/18 rpd]
Fixed db_set_single_step to pass regs to branch_taken.
Added watchpoint argument to db_restart_at_pc.
[90/10/17 rpd]
Generalized the watchpoint support.
[90/10/16 rwd]
Added watchpoint support.
[90/10/16 rpd]
[ ./kernel/ddb/db_sym.c ]
Changed db_printsym to print unsigned.
[90/10/19 rpd]
[ ./kernel/ddb/db_trap.c ]
From rpd.
[90/10/19 17:03:17 rwd]
Generalized the watchpoint support.
[90/10/16 rwd]
Added watchpoint support.
[90/10/16 rpd]
[ ./kernel/ddb/db_watch.c ]
Made db_watchpoint_cmd parse a size argument.
[90/10/17 rpd]
Generalized the watchpoint support.
[90/10/16 rwd]
Created.
[90/10/16 rpd]
[ ./kernel/ddb/db_watch.h ]
Generalized the watchpoint support.
[90/10/16 rwd]
Created.
[90/10/16 rpd]
[ ./kernel/ddb/db_write_cmd.c ]
Changed db_write_cmd to print unsigned.
[90/10/19 rpd]
[ ./kernel/device/ds_routines.c ]
Let ds_device_write proceed w/o a valid reply port. This is used
by the unix server ether_output routine.
[90/10/22 rwd]
Fixed ds_write_done to use ds_device_write_inband_reply
when appropriate.
[90/10/18 rpd]
Check for invalid reply ports.
[90/10/17 rwd]
[ ./kernel/i386/db_interface.c ]
Added watchpoint support.
[90/10/18 rpd]
Created.
[90/07/25 dbg]
[ ./kernel/i386/db_machdep.h ]
Added watchpoint support.
[90/10/18 rpd]
[ ./kernel/i386/trap.c ]
Added watchpoint support.
[90/10/18 rpd]
[ ./kernel/i386/trap.h ]
Added watchpoint support.
[90/10/18 rpd]
[ ./kernel/kern/debug.c ]
Change sun3 debugger invocation.
[90/10/17 rwd]
[ ./kernel/kern/printf.c ]
Purged uprintf.
[90/10/21 rpd]
[ ./kernel/kern/task.c ]
From OSF: Add thread_block() to loop that forcibly terminates
threads in task_terminate() to fix livelock. Also hold
reference to thread when calling thread_force_terminate().
[90/10/19 rpd]
[ ./kernel/kern/thread.c ]
Added host_stack_usage and processor_set_stack_usage.
[90/10/22 rpd]
Removed pausing code in stack_alloc/stack_free.
It was broken and it isn't needed.
Added code to check how much stack is actually used.
[90/10/21 rpd]
[ ./kernel/mach_debug/mach_debug.defs ]
Added processor_set_stack_usage.
[90/10/22 rpd]
[ ./kernel/mach_debug/mach_debug_types.defs ]
Updated vm_info_region_t size.
[90/10/17 rpd]
[ ./kernel/mips/PMAX/devio.h ]
Changed uprintf to printf.
[90/10/21 rpd]
[ ./kernel/mips/db_interface.c ]
Support for watchpoints.
[90/10/16 rpd]
[ ./kernel/mips/db_machdep.h ]
Generalized the watchpoint support.
[90/10/16 rwd]
Added watchpoint support.
[90/10/16 21:09:42 rpd]
[ ./kernel/mips/pmap.c ]
Fixed the OSF pmap_protect fixes.
[90/10/21 rpd]
[ ./kernel/mips/trap.c ]
Removed static from getreg_val.
[90/10/17 rpd]
Generalized the watchpoint support.
[90/10/16 rwd]
Added watchpoint support.
[90/10/16 rpd]
[ ./kernel/sun3/db_interface.c ]
Added watchpoint support.
[90/10/16 rwd]
[ ./kernel/sun3/db_machdep.h ]
Added watchpoint support.
[90/10/16 rwd]
[ ./kernel/sun3/pmap.c ]
Change asm instructions to Debugger().
[90/10/17 rwd]
Added hardware_reference_bits runtime switch.
[90/10/13 rpd]
[ ./kernel/sun3/softint.c ]
Always enable softints when a softcall request is done.
[90/10/17 rwd]
[ ./kernel/sun3/trap.c ]
Fixed the map argument to db_find_watchpoint.
Made the faultaddr argument to pagefault a vm_offset_t.
[90/10/18 rpd]
Added watchpoint support.
[90/10/16 rwd]
[ ./kernel/sun3/trap.h ]
Added watchpoint support.
[90/10/16 rwd]
[ ./kernel/sundev/sd.c ]
Changed uprintf to printf.
[90/10/21 rpd]
Remove excess debugging code.
[90/10/21 rwd]
[ ./kernel/sundev/st.c ]
Changed uprintf to printf.
[90/10/21 rpd]
[ ./kernel/vax/db_interface.c ]
Added watchpoint support.
[90/10/18 rpd]
[ ./kernel/vax/db_machdep.h ]
Added watchpoint support.
[90/10/18 rpd]
[ ./kernel/vax/trap.c ]
Added watchpoint support.
[90/10/18 rpd]
[ ./kernel/vax/trap.h ]
Added watchpoint support.
[90/10/18 rpd]
[ ./kernel/vm/memory_object.c ]
Clean and not flush pages to lock request get moved to the
inactive queue.
[90/10/24 rwd]
[ ./kernel/vm/vm_fault.c ]
Turn software_reference_bits off by default.
[90/10/25 rwd]
Extended software_reference_bits to vm_fault_page.
[90/10/24 rpd]
Fixed vm_fault_page to clear the modify bit on zero-filled pages.
[90/10/23 rpd]
Added watchpoint debugger support.
[90/10/16 rpd]
Added software_reference_bits runtime switch.
[90/10/13 rpd]
Added watchpoint debugger support.
[90/10/16 rpd]
Added software_reference_bits runtime switch.
[90/10/13 rpd]
[ ./kernel/vm/vm_map.c ]
Fixed bug in vm_map_enter that was introduced in 2.13.
[90/10/21 rpd]
[ ./kernel/vm/vm_page.h ]
Removed the max_mapping field of pages.
[90/10/22 rpd]
[ ./kernel/vm/vm_resident.c ]
Made vm_page_alloc_deactivate_behind TRUE.
[90/10/24 rwd]
Removed the max_mapping field of pages.
[90/10/22 rpd]
[ ./user/libmach/Makefile ]
Add I386 fields.
[90/10/24 rwd]
==========================================================================
***** MK Version MK32 (rpd) *****
New features:
--- --------
I added a ddb command to search memory for a value:
search [/bhl] addr value [mask] [,count]
Randy added cthread_fork_{prepare,child,parent}.
I added a patchable boolean, zone_check, that causes
zfree to check the consistency of zone free lists.
I changed the IPC reference-counting functions/macros
to make it easier to debug reference-count problems.
[SUN3] Picked up ie and xy drivers from NCSC.
[I386] Picked up various goodies from Bob.
The pc586 driver works now on both 386 and 486.
The first 640K of memory is available now.
The kernel tells DOS to warm boot upon reboot.
The debugger prints five arguments to functions in traces.
Bug fixes:
--- -----
I picked up dlb's vm_object_deallocate fix for a nasty race.
I fixed vm_page_deactivate to not deactivate busy pages.
(It can find busy pages on the active list when software_reference_bits
is enabled.) Now vm_page_deactivate requires that the page's
object is locked.
I ripped out vm_region_old_behavior. Now vm_region() has the same
semantics as in Mach 2.5.
I fixed memory_object_terminate in the device pager
to return a value.
I fixed crt0.o so that it is usable by non-standalone programs.
I fixed the assert macro so that it doesn't try to drop into ddb
when already in ddb.
I unified untimeout and untimeout_try, and fixed the related MP bugs.
[PMAX] Fixed jmp_buf to have the standard size.
Organizational changes:
-------------- -------
Randy fixed the Makefiles for STUMP. This means you must use
the alpha/beta make and cpp on non-386 machines.
Randy added spin_lock_t and associated changes to cthreads.
Special notes:
------- -----
The ddb search command might fail in interesting ways if it doesn't
find the searched-for value. This is because ddb doesn't always
recover from touching bad memory. The optional count argument
limits the search.
The cthread_fork_* functions aren't tested.
[ ./conf/version.edit ]
32
[ ./user/libmach/Makefile ]
Added start_float.s, for the Sun-3.
[90/11/01 rpd]
Added exit.c.
[90/10/30 rpd]
[ ./include/Makeconf ]
Added REG_EXP.
[90/10/29 rwd]
[ ./include/Makefile ]
Added machine/cthreads.h include file from libthreads.
[90/11/01 rwd]
Added REG_EXP.
[90/10/29 rwd]
[ ./kernel/Makeconf ]
SUN->SUN3.
[90/10/31 rwd]
Added REG_EXP.
[90/10/29 rwd]
Change MACHINE to TARGET_MACHINE.
[90/10/29 rwd]
[ ./kernel/Makefile ]
SUN->SUN3.
[90/10/31 rwd]
Change MACHINE to TARGET_MACHINE.
[90/10/29 rwd]
[ ./kernel/conf/MASTER.sun3 ]
Added BWS.
[90/10/26 17:01:06 rwd]
[ ./kernel/conf/Makefile.template ]
Added REG_EXP.
[90/10/29 rwd]
[ ./kernel/conf/buildconf.sun3 ]
First use for 3.0
[90/10/26 rwd]
[ ./kernel/ddb/db_break.c ]
Initialize db_breakpoints_inserted to TRUE.
[90/11/04 rpd]
[ ./kernel/ddb/db_watch.c ]
Initialize db_watchpoints_inserted to TRUE.
[90/11/04 rpd]
[ ./kernel/device/dev_pager.c ]
Fixed memory_object_terminate to return KERN_SUCCESS.
[90/10/29 rpd]
[ ./kernel/i386/bcopy.s ]
Introduce bcopy16. For 16bit copies to bus memory
[90/11/02 rvb]
[ ./kernel/i386/db_trace.c ]
If we can not guess the number of args to a function, use 5 vs 0.
[90/11/02 rvb]
[ ./kernel/i386/i386_init.c ]
Start first_addr at 0x1000 and define first available page
after the kernel's end as first_avail.
Flush EXL.
[90/09/05 rvb]
[ ./kernel/i386/pmap.c ]
Replace (va < vm_first_phys || va > vm_last_phys) with test
using valid page. Otherwise, video buffer memory is treated as
valid memory and setting dirty bits leads to disasterous results.
[90/11/05 rvb]
Define pmap_valid_page: [0x1000..cnvmem * 1024) and
[first_avail..)
as useable memory
[90/09/05 rvb]
[ ./kernel/i386/start.s ]
Since we steal pages after esym for page tables, use first_avail
to record the last page +1 that we stole.
Tell bios to warm boot on reboot.
[90/09/05 rvb]
[ ./kernel/i386at/i82586.h ]
Document error bits in Xmt and Rcv.
[90/10/08 rvb]
[ ./kernel/i386at/if_pc586.c ]
Convert for pure kernel
[90/11/02 rvb]
Init scb and reset as per spec. Use bcopy16 vs pc586copy as per spec.
Accumulate counters at hwrst. Add counters everywhere.
Editing and style and consistency cleanup.
Flush NOP's: this required major mods to hwrst and everything it
called -- testing OK is not correct if the command is not COMPLETE.
Lot's of code clean up in xmt, rcv, reqfd.
Flush pc_softc_t "address" and pc586ehcpy.
Handle loopback of our ownbroadcast.
The rcv and xmt loops have been rewriten not copy sram
to the t_packet buffer. This yields a teriffic thruput
improvement.
Add Notes and sram map.
[90/09/28 rvb]
[ ./kernel/i386at/if_pc586.h ]
Create 18 TBD's so that we can copy up a chain of
mbuf's.
[90/10/03 rvb]
[ ./kernel/ipc/ipc_kmsg.c ]
Changed ip_reference to ipc_port_reference.
Changed ip_release to ipc_port_release.
Use new io_reference and io_release.
Use new ip_reference and ip_release.
[90/10/29 rpd]
[ ./kernel/ipc/ipc_mqueue.c ]
Use new io_reference and io_release.
Use new ip_reference and ip_release.
[90/10/29 rpd]
[ ./kernel/ipc/ipc_object.c ]
Removed ipc_object_reference_macro, ipc_object_release_macro.
Use new io_reference and io_release.
Use new ip_reference and ip_release.
[90/10/29 rpd]
[ ./kernel/ipc/ipc_object.h ]
Removed ipc_object_reference_macro, ipc_object_release_macro.
Created new io_reference, io_release macros.
[90/10/29 rpd]
[ ./kernel/ipc/ipc_port.c ]
Changed ip_release to ipc_port_release.
Use new ip_reference and ip_release.
[90/10/29 rpd]
[ ./kernel/ipc/ipc_port.h ]
Added ipc_port_reference, ipc_port_release.
[90/10/29 rpd]
[ ./kernel/ipc/ipc_pset.c ]
Use new ips_reference and ips_release.
[90/10/29 rpd]
[ ./kernel/ipc/ipc_pset.h ]
Added ipc_pset_reference, ipc_pset_release.
[90/10/29 rpd]
[ ./kernel/ipc/ipc_right.c ]
Changed io_release to ipc_object_release.
Changed ip_release to ipc_port_release.
Use new ip_reference and ip_release.
[90/10/29 rpd]
[ ./kernel/ipc/ipc_space.c ]
Use new ip_reference and ip_release.
[90/10/29 rpd]
[ ./kernel/ipc/mach_msg.c ]
Removed ipc_object_release_macro.
Changed ip_reference to ipc_port_reference.
Changed ip_release to ipc_port_release.
Changed io_release to ipc_object_release.
Use new io_reference and io_release.
Use new ip_reference and ip_release.
[90/10/29 rpd]
[ ./kernel/kern/assert.h ]
Changed assert to use Assert instead of Debugger.
[90/11/04 rpd]
[ ./kernel/kern/debug.c ]
Added Assert.
[90/11/04 rpd]
[ ./kernel/kern/ipc_mig.c ]
Changed ip_reference to ipc_port_reference.
Changed ip_release to ipc_port_release.
Removed ipc_object_release_macro.
Use new ip_reference and ip_release.
[90/10/29 rpd]
[ ./kernel/kern/ipc_tt.c ]
Changed ip_reference to ipc_port_reference.
Use new ip_reference and ip_release.
[90/10/29 rpd]
[ ./kernel/kern/lock.h ]
Added simple_lock_taken.
[90/11/04 rpd]
[ ./kernel/kern/mach_clock.c ]
Unified untimeout and untimeout_try.
[90/10/29 rpd]
[ ./kernel/kern/syscall_subr.c ]
Restored missing multiprocessor untimeout failure code.
[90/10/29 rpd]
[ ./kernel/kern/thread.c ]
Unified untimeout and untimeout_try.
[90/10/29 rpd]
[ ./kernel/kern/time_out.h ]
Changed untimeout to return boolean.
[90/10/29 rpd]
[ ./kernel/kern/zalloc.c ]
Added zone_check option to zfree.
[90/10/29 rpd]
[ ./kernel/mips/PMAX/pm_tty.c ]
Fixed untimeout usage.
[90/10/29 rpd]
[ ./kernel/src/mig/Makefile ]
SUN->SUN3.
[90/10/31 rwd]
Change MACHINE to TARGET_MACHINE.
[90/10/29 rwd]
[ ./kernel/sun/conf.c ]
Added ie and xy from NCSC.
[90/10/26 rwd]
[ ./kernel/sundev/mbvar.h ]
Change from NCSC for xydriver.
[90/10/26 rwd]
Altered for MACH_KERNEL.
[88/03/22 dbg]
[ ./kernel/sundev/xy.c ]
change to use kalloc, kfree instead of sun_kmem_alloc, sun_kmem_free
from NCSC.
[90/10/26 rwd]
[ ./kernel/sundev/xy_conf.c ]
3.0 changes from NCSC.
[90/10/26 rwd]
[ ./kernel/sunif/if_ie.c ]
Changes for 3.0 from NCSC.
[90/10/26 rwd]
[ ./kernel/sunif/if_iereg.h ]
Changes for 3.0 from NCSC.
[90/10/26 rwd]
[ ./kernel/sunif/if_ievar.h ]
Changes for 3.0 from NCSC.
[90/10/26 rwd]
[ ./kernel/sunif/if_mie.h ]
First Checkin.
[90/10/26 rwd]
[ ./kernel/sunif/if_obie.h ]
First checkin.
[90/10/26 rwd]
[ ./kernel/sunif/if_tie.h ]
First Checkin.
[90/10/26 rwd]
[ ./kernel/vm/vm_map.c ]
Removed vm_region_old_behavior.
[90/11/02 rpd]
[ ./kernel/vm/vm_object.h ]
Added vm_object_lock_taken.
[90/11/04 rpd]
[ ./kernel/vm/vm_pageout.c ]
Modified vm_pageout_scan for new vm_page_deactivate protocol.
[90/11/04 rpd]
[ ./kernel/vm/vm_resident.c ]
Changed vm_page_deactivate to remove busy pages from the page queues.
Now it requires that the page's object be locked.
[90/11/04 rpd]
[ ./user/libmach/Makefile ]
SUN->SUN3.
[90/10/31 rwd]
Change MACHINE to TARGET_MACHINE.
[90/10/29 rwd]
[ ./user/libmach/exit.c ]
Created.
[90/10/30 rpd]
[ ./user/libmach/i386/crt0.c ]
Removed the definition of exit.
[90/10/30 rpd]
[ ./user/libmach/mips/crt0.cv ]
Removed the definition of exit.
[90/10/30 rpd]
[ ./user/libmach/mips/crt0.ss ]
Removed the definition of exit.
[90/10/30 rpd]
[ ./user/libmach/setjmp.h ]
Changed the mips jmp_buf definition to the normal size.
[90/10/30 rpd]
[ ./user/libmach/sun3/crt0.s ]
Restored call to _exit if exit returns.
Restored call to start_float.
[90/11/01 rpd]
Call exit instead of task_terminate.
[90/10/30 rpd]
[ ./user/libmach/sun3/start_float.s ]
Created.
[90/11/01 rpd]
[ ./user/libmach/vax/crt0.cc ]
Removed the definition of exit.
[90/10/30 rpd]
[ ./user/threads/Makefile ]
Change MACHINE to TARGET_MACHINE.
[90/10/29 rwd]
[ ./user/threads/cprocs.c ]
Added cproc_fork_{prepare,parent,child}.
[90/11/02 rwd]
Fix for positive stack growth.
[90/11/01 rwd]
Add spin_lock_t.
[90/10/31 rwd]
[ ./user/threads/cthread_internals.h ]
Added spin_lock_t.
[90/10/31 rwd]
[ ./user/threads/cthreads.c ]
Added cthread_fork_{prepare,parent,child}.
[90/11/02 rwd]
Add spin_lock_t.
[90/10/31 rwd]
[ ./user/threads/cthreads.h ]
Include machine/cthreads.h. Added spin_lock_t.
[90/10/31 rwd]
[ ./user/threads/i386/cthreads.h ]
Created.
[90/11/01 rwd]
[ ./user/threads/malloc.c ]
Added malloc_fork* code.
[90/11/02 rwd]
Add spin_lock_t.
[90/10/31 rwd]
[ ./user/threads/mips/cthreads.h ]
Created.
[90/11/01 rwd]
[ ./user/threads/stack.c ]
Fixed addr_range_check for new vm_region semantics.
[90/11/02 rpd]
[ ./user/threads/sun3/cthreads.h ]
Created.
[90/11/01 rwd]
[ ./user/threads/sync.c ]
Fix casting. Use new macros.
[90/10/31 rwd]
[ ./user/threads/vax/cthreads.h ]
Created.
[90/11/01 rwd]
[ ./kernel/conf/version.variant ]
Changed XMK to MK.
[ ./user/threads/stack.c ]
Added cproc_stack_base. Add stack_fork_child().
[90/11/01 rwd]
[ ./kernel/vm/vm_object.c ]
From [email protected]:
If pager initialization is in progress (object->pager_created &&
!object->pager_initialized), then vm_object_deallocate must wait
for it to complete before terminating the object. Because anything
can happen in the interim, it must recheck its decision to terminate
after the wait completes.
[ ./kernel/ddb/db_command.c ]
Added search.
[90/11/06 rpd]
[ ./kernel/ddb/db_examine.c ]
Added db_search_cmd, db_search.
[90/11/06 rpd]
==========================================================================
***** MK Version MK33 (jsb) *****
New features:
--- --------
[I386] Added cnp ethernet driver for i386ipsc2 (Intel Hypercube).
Bug fixes:
--- -----
[I386] Fixed changes in MK32 which prevented STD+NORMA+iPSC2 from building.
==========================================================================
***** MK Version MK34 (jsb) *****
New features:
--- --------
Added i860 build support (for the hypercube). Details follow.
The i860 and i860ipsc2 source directories will be added in a future merge.
Added support to conf/Makefile.template for cross-compilation.
I borrowed the not-otherwise-used KCC technology so that $(KCC)
is used to build kernel files (and thus would be the cross
compiler), whereas $(CC) is used to build things like genassym
which run on the host (in this case, a i386). I fixed a couple
cases in Makefile.template that didn't conform to this convention:
vers.o is now compiled with $(KCC), and genassym is now compiled
with $(CC). I also added work-arounds for the fact that we don't
have a cross-ranlib or a cross-size.
[I860] Added conf/MASTER.i860{,.local}, conf/{Makefile,files}.i860,
and added i860 support to config, mach/machine.h, and
sys/varargs.h.
==========================================================================
***** MK Version MK35 (rvb) *****
This is an I386 architecture release only. It has been tested
on an AT as well as the hypercube.
No New features:
--- --------
Except possibly that the if_pc586.c is not timing dependent
any more.
The big deal about this release is that all the files in the
i386at directory and the files in Mach2.5 I386q are identical --
that is all improvements in the mainline have been merged to
the 3.0 code and vice versa. NOTE: the 3.0 com driver has
not been tested cause I did not have any hardware. Also I
have lpr and if_par drivers that I did not even install for
the same reason. (I needed to install com.c for the mouse
support code.)
ALSO, this release has the Prime copyrights changed to something
less threatening, courtesy of Prime Computer Inc.
Bug fix:
The panic that rfr reported with the ram_to_ptr is no longer
possible.
==========================================================================
***** MK Version MK36 (jsb) *****
New features:
--- --------
Merged in i860 support for iPSC Intel hypercube.
Merged i860 and i386 pmap.{c,h} into new intel directory.
Merged i860 and i386 ipsc support into new ipsc directory.
Added ATSYS variable which can be used to override use of @sys
in OBJECTDIR when cross-compiling.
Changed ipsc2 references to ipsc386 or simply ipsc, as appropriate.
Removed libmig.a workaround from conf/Makefile.template since the same
thing can be acheived entirely within conf/Makefile.{machine}.
==========================================================================
***** MK Version MK37 (af) *****
New features:
--- --------
This merge brings freedom to PMAXen, there is now only one single file
left in the kernel with a MIPSco Copyright on it: mips/softfp.s which
is optional. No DEC Copyright in sight, we only loose support for the
2D/3D boxes [actually only the 2D, I have never seen a 3D].
The entire mips/PMAX subdir is new, the only pieces I recovered are
the code Joe wrote for the terminal emulator and the in-kernel ether
driver that Bob & I wrote/rewrote/rewrote.... Everything else is new.
The various drivers are in various stages of "maturity": the ether is
rock-solid, the screen&serial line is quite robust.
The SCSI driver is the one likely to need most fixes and additions.
Among the missing features are:
- true SCSI-2 support and adherence to the standard
- disconnect/reconnect capability when more than one
drive is on the bus
In the PMAX case then there are still various misteries to be solved,
one most annoying: if you do not tell the prom to "init" before rebooting
it will get locked up in bus-error interrupts at the first synchronous
data transfer. Beats me why. It also seems to me it is much slower than it
needs to, but I won't measure it until I understand it.
Added BSD/OSF labels to kernel.
New cute font, and related tools.
New 16 sec bootstrap: shows that you do not need two levels of boots
to be flexible. With this one you can boot any file on disk, follow
symlinks, even cross-device links (but of a very weird type..) and
all fits in 15 sectors. Mostly C code.
Added new header file for TAPE devices. Not that it really works yet,
but we'll get around that too.
Enabled mapped ether by default.
Added missing code to make the pmap pcache work.
Changed pmap_reference_bits array encoding, saves a cycle in tlb_umiss
as suggested by dbg.
Bug fixes:
--- -----
MP-Bug fix from DLB to thread_suspend/resume.
[i386]
Fixed syscall_sw.h to be palatable to the GNU preproc.
[PMAX]
Fixed rpd's register leak. Added optional code to locore to zero temporary
registers out of a syscall.
Fix from Larry Allen: kernel thread were started with interrupts disabled.
Fixed off-by-one in syscall emulation table size: Ultrix code does use
syscall 257 too.
Fixed memory sizing routine for 3max to clear memory: this way we won't
get those misterious "dropped because of previous paging-errors".
Various minor spot clean for new 3max proms.
Organizational changes:
-------------- -------
[PMAX]
The new 16 sector bootstrap is built make-ing in kernel/mips/boot.
Be careful with this: with Berkeley labels you cannot anymore just
dd any file in there: it now knows about partitioning. See the
Makefile for more info.
Special notes:
------- -----
Booted on pmax(unnamed), 3max(testarossa), vax(nova), sun3(rocky)
and i386(intel2)
***************************************************
The following files have been Defuncted:
[ ./kernel/mips/symbols.raw ]
[ ./kernel/mips/PMAX/ascreg.h ]
[ ./kernel/mips/PMAX/cfb.c ]
[ ./kernel/mips/PMAX/cfbreg.h ]
[ ./kernel/mips/PMAX/dc7085cons.h ]
[ ./kernel/mips/PMAX/dc_hdw.c ]
[ ./kernel/mips/PMAX/dc_modem.c ]
[ ./kernel/mips/PMAX/dc_tty.c ]
[ ./kernel/mips/PMAX/devio.h ]
[ ./kernel/mips/PMAX/ga.c ]
[ ./kernel/mips/PMAX/ga.h ]
[ ./kernel/mips/PMAX/gq.c ]
[ ./kernel/mips/PMAX/gq.h ]
[ ./kernel/mips/PMAX/gx.c ]
[ ./kernel/mips/PMAX/gx.h ]
[ ./kernel/mips/PMAX/fudge.h ]
[ ./kernel/mips/PMAX/pm.h ]
[ ./kernel/mips/PMAX/pm_graphics.c ]
[ ./kernel/mips/PMAX/pm_hdw.h ]
[ ./kernel/mips/PMAX/pm_lk201.c ]
[ ./kernel/mips/PMAX/pm_lk201.h ]
[ ./kernel/mips/PMAX/pm_ms.c ]
[ ./kernel/mips/PMAX/pm_ms.h ]
[ ./kernel/mips/PMAX/pm_switch.c ]
[ ./kernel/mips/PMAX/pm_switch.h ]
[ ./kernel/mips/PMAX/pm_tty.c ]
[ ./kernel/mips/PMAX/pmax.c ]
[ ./kernel/mips/PMAX/pmevent.h ]
[ ./kernel/mips/PMAX/pmioctl.h ]
[ ./kernel/mips/PMAX/qfont.c ]
[ ./kernel/mips/PMAX/rzdisk.h ]
[ ./kernel/mips/PMAX/scsi_asc.c ]
[ ./kernel/mips/PMAX/scsi_data.c ]
[ ./kernel/mips/PMAX/scsi_debug.h ]
[ ./kernel/mips/PMAX/scsi_sii.c ]
[ ./kernel/mips/PMAX/scsireg.h ]
[ ./kernel/mips/PMAX/siireg.h ]
[ ./kernel/mips/PMAX/stamp.h ]
[ ./kernel/mips/PMAX/super.c ]
[ ./kernel/mips/PMAX/scsivar.h ]
The following files are new
[ ./kernel/mips/PMAX/boot/Makefile ]
[ ./kernel/mips/PMAX/boot/asm_misc.h ]
[ ./kernel/mips/PMAX/boot/asm_misc.s ]
[ ./kernel/mips/PMAX/boot/c_misc.c ]
[ ./kernel/mips/PMAX/boot/dev.h ]
[ ./kernel/mips/PMAX/boot/dir.h ]
[ ./kernel/mips/PMAX/boot/disk_inode.h ]
[ ./kernel/mips/PMAX/boot/fs.h ]
[ ./kernel/mips/PMAX/boot/label.b ]
[ ./kernel/mips/PMAX/boot/mkboot.c ]
[ ./kernel/mips/PMAX/boot/primary_boot.c ]
[ ./kernel/mips/PMAX/boot/start.s ]
[ ./kernel/mips/PMAX/boot/test.c ]
[ ./kernel/mips/PMAX/boot/ufs.c ]
[ ./kernel/mips/PMAX/boot/ufs.h ]
[ ./kernel/mips/PMAX/bt459.c ]
[ ./kernel/mips/PMAX/bt459.h ]
[ ./kernel/mips/PMAX/bt478.c ]
[ ./kernel/mips/PMAX/bt478.h ]
[ ./kernel/mips/PMAX/build_font.c ]
[ ./kernel/mips/PMAX/cfb_hdw.c ]
[ ./kernel/mips/PMAX/cfb_misc.c ]
[ ./kernel/mips/PMAX/dc503.c ]
[ ./kernel/mips/PMAX/dc503.h ]
[ ./kernel/mips/PMAX/dz_7085.h ]
[ ./kernel/mips/PMAX/dz_defs.h ]
[ ./kernel/mips/PMAX/dz_hdw.c ]
[ ./kernel/mips/PMAX/dz_tty.c ]
[ ./kernel/mips/PMAX/ga_hdw.c ]
[ ./kernel/mips/PMAX/gq_hdw.c ]
[ ./kernel/mips/PMAX/gx_misc.c ]
[ ./kernel/mips/PMAX/kernel_font.c ]
[ ./kernel/mips/PMAX/kernel_font.data ]
[ ./kernel/mips/PMAX/kn01.c ]
[ ./kernel/mips/PMAX/kn01.h ]
[ ./kernel/mips/PMAX/kn02.c ]
[ ./kernel/mips/PMAX/kn02.h ]
[ ./kernel/mips/PMAX/lk201.c ]
[ ./kernel/mips/PMAX/lk201.h ]
[ ./kernel/mips/PMAX/mapped_scsi.c ]
[ ./kernel/mips/PMAX/mapped_scsi.h ]
[ ./kernel/mips/PMAX/mouse.c ]
[ ./kernel/mips/PMAX/pm_defs.h ]
[ ./kernel/mips/PMAX/pm_hdw.c ]
[ ./kernel/mips/PMAX/pm_misc.c ]
[ ./kernel/mips/PMAX/pmad_aa.h ]
[ ./kernel/mips/PMAX/pmag_ba.h ]
[ ./kernel/mips/PMAX/pmaz_aa.h ]
[ ./kernel/mips/PMAX/rz.c ]
[ ./kernel/mips/PMAX/rz.h ]
[ ./kernel/mips/PMAX/rz_disk.c ]
[ ./kernel/mips/PMAX/rz_labels.h ]
[ ./kernel/mips/PMAX/rz_tape.c ]
[ ./kernel/mips/PMAX/screen.c ]
[ ./kernel/mips/PMAX/screen.h ]
[ ./kernel/mips/PMAX/screen_defs.h ]
[ ./kernel/mips/PMAX/screen_switch.c ]
[ ./kernel/mips/PMAX/screen_switch.h ]
[ ./kernel/mips/PMAX/scsi.c ]
[ ./kernel/mips/PMAX/scsi.h ]
[ ./kernel/mips/PMAX/scsi2.h ]
[ ./kernel/mips/PMAX/scsi_53C94.h ]
[ ./kernel/mips/PMAX/scsi_53C94_hdw.c ]
[ ./kernel/mips/PMAX/scsi_7061.h ]
[ ./kernel/mips/PMAX/scsi_7061_hdw.c ]
[ ./kernel/mips/PMAX/scsi_alldevs.c ]
[ ./kernel/mips/PMAX/scsi_comm.c ]
[ ./kernel/mips/PMAX/scsi_cpu.c ]
[ ./kernel/mips/PMAX/scsi_defs.h ]
[ ./kernel/mips/PMAX/scsi_disk.c ]
[ ./kernel/mips/PMAX/scsi_jukebox.c ]
[ ./kernel/mips/PMAX/scsi_optical.c ]
[ ./kernel/mips/PMAX/scsi_printer.c ]
[ ./kernel/mips/PMAX/scsi_rom.c ]
[ ./kernel/mips/PMAX/scsi_scanner.c ]
[ ./kernel/mips/PMAX/scsi_tape.c ]
[ ./kernel/mips/PMAX/scsi_worm.c ]
The following files have been modified:
[ ./Directories/ALL ]
[ ./Directories/mips ]
[ ./include/Makefile ]
[ ./kernel/conf/MASTER.mips ]
[ ./kernel/conf/files.mips ]
[ ./kernel/device/param.h ]
[ ./kernel/device/tape_status.h ]
[ ./kernel/device/tty_status.h ]
[ ./kernel/kern/syscall_emulation.c ]
[ ./kernel/kern/thread.c ]
[ ./kernel/mach/i386/syscall_sw.h ]
[ ./kernel/mips/PMAX/if_se.c ]
[ ./kernel/mips/PMAX/if_se.h ]
[ ./kernel/mips/PMAX/if_se_mapped.c ]
[ ./kernel/mips/PMAX/mc_clock.c ]
[ ./kernel/mips/PMAX/mips_box.c ]
[ ./kernel/mips/PMAX/mips_box.h ]
[ ./kernel/mips/PMAX/model_dep.c ]
[ ./kernel/mips/PMAX/tc.c ]
[ ./kernel/mips/PMAX/tc.h ]
[ ./kernel/mips/autoconf.c ]
[ ./kernel/mips/busses.c ]
[ ./kernel/mips/busses.h ]
[ ./kernel/mips/coff.h ]
[ ./kernel/mips/conf.c ]
[ ./kernel/mips/context.s ]
[ ./kernel/mips/db_interface.c ]
[ ./kernel/mips/db_mips_sym.c ]
[ ./kernel/mips/exec.c ]
[ ./kernel/mips/locore.s ]
[ ./kernel/mips/mips_init.c ]
[ ./kernel/mips/mips_misc.c ]
[ ./kernel/mips/pcb.c ]
[ ./kernel/mips/pmap.c ]
[ ./kernel/mips/prom_interface.h ]
[ ./kernel/mips/start.s ]
[ ./kernel/mips/tlb.s ]
[ ./kernel/mips/trap.c ]
[ ./user/libmach/Makefile ]
==========================================================================
***** MK Version MK38 (jsb) *****
New features:
--- --------
Replaced uses of @sys in Makefiles and Makeconf with $(atsys).
atsys is set to ATSYS if defined, @sys if not.
[MACH_CLPORT] Support for complex inter-node messages.
[MACH_CLBOOT] Support for transparent inter-node device access.
[iPSC] New dcm interface for MACH_CLPORT support.
[iPSC] Finished merge of i860 and i386 console driver (usm.c).
==========================================================================
***** MK Version MK39 (jeffreyh) *****
New features:
--- --------
Zone gc code has been picked up from OSF/1. All zones in the system
are now collected. zchange now takes an extra argument for
collectable. This is so you could turn collection off for a zone.
[I386] The 386 is now buildable using the gcc-cpp from MtXinu.
Several additions to the code for __STDC__ have been made.
Due to this work mig no longer generates prototypes for ansi C
and C++ in the generated header files. This is because the
prototypes in the headers were for the the client side only.
Kernel files that were including these headers would fail
to compile as the types and number of arguments to the
functions was wrong. If prototypes are wanted for mig
headers, mig must be made to generate both client and server
header files with apropriate prototypes.
Bug fixes:
--- -----
[PMAX] scsi disk fixes from af
A few others
******** CUT HERE ******** summary of log messages ******** CUT HERE ********
[ ./conf/version.edit ]
39
[ ./kernel/boot_ufs/def_pager_setup.c ]
Added init for default_partition_lock
[90/12/11 jeffreyh]
[ ./kernel/i386/asm.h ]
changes for __STDC__
[90/12/06 jeffreyh]
[ ./kernel/i386/cswitch.s ]
Changes for __STDC__
Changes for __STDC__
[90/12/07 15:45:37 jeffreyh]
[ ./kernel/i386/interrupt.s ]
Changes for __STDC__
[90/12/07 15:43:38 jeffreyh]
[ ./kernel/i386/locore.s ]
Changes for __STDC__
[90/12/07 15:43:29 jeffreyh]
[ ./kernel/i386/pio.h ]
changes for __STDC__
[90/12/07 jeffreyh]
[ ./kernel/i386/spl.s ]
Changes for __STDC__
[90/12/07 jeffreyh]
[ ./kernel/i386/start.s ]
Changes for __STDC__
[90/12/07 15:43:21 jeffreyh]
[ ./kernel/i386at/blit.c ]
Changes for __STDC__
[90/12/07 jeffreyh]
[ ./kernel/i386at/if_pc586.c ]
Changes for __STDC__
[90/12/07 jeffreyh]
[ ./kernel/ipc/ipc_init.c ]
Changes to zchange to account for new collectable field. Made all
ipc zones collectable.
[90/12/11 jeffreyh]
[ ./kernel/ipc/ipc_marequest.c ]
Change zchange to match new number of arguments. Made zone collectable.
[90/12/11 jeffreyh]
[ ./kernel/kern/zalloc.c ]
[90/12/19 10:36:55 jeffreyh]
[ ./kernel/kern/zalloc.h ]
Merged in changes done by jvs@osf from OSF/1
[90/12/10 jeffreyh]
[ ./kernel/mips/PMAX/rz.c ]
Do not use minphys(), we do not need to trim requests.
[90/12/11 af]
[ ./kernel/mips/PMAX/rz_disk.c ]
Bug in strategy routine: for xfers larger than
max_dma was not setting the io_count right at
the end of the transfer. Now new fsck works.
[90/12/10 17:26:47 af]
[ ./kernel/mips/locore.s ]
Fixed gimmeabreak() to let you sstep out of it.
Long overdue, but I had this habit of putting a breakpoint
where I wanted to stop anyways.
[90/12/13 af]
[ ./kernel/mips/PMAX/scsi_7061_hdw.c ]
More hacks to understand rz55, and now hitachis boot.
There is still one problem for hitachis at large,
will fix in the next merge.
[90/12/19 15:17:48 af]
[ ./kernel/src/mig/header.c ]
Commented out code for prototype generation. This is a temporary solution
to the longer term problem of the need
for the generation of both a client and a server header file
that have correct prototypes for strict ansi c and c++. The
prototypes generated before anly were for the client and broke kernel
files that included them if compiled under standard gcc
[90/12/07 jeffreyh]
[ ./kernel/vm/vm_external.c ]
Change zchange to accept new argument. Made zones collectable.
[90/12/11 jeffreyh]
==========================================================================
***** MK Version MK40 (rpd) *****
New features:
--- --------
Kernel stack discarding and related optimizations.
Currently a thread's kernel stack is discarded
when it is created, when it is suspended,
when it waits in a message receive, and when
it waits for a reply to an exception_raise upcall.
Threads without kernel stacks are "swapped".
All runnable threads have kernel stacks.
The vax and sun3 don't discard kernel stacks.
In fact, they don't even unwire kernel stacks.
MI code uses a KEEP_STACKS conditional (temporary,
I hope) to support unconverted architectures.
The i386 discards kernel stacks, but the implementation
is suboptimal. locore still saves user state on the
kernel stack, so stack_switch() must copy user state
to and from the kernel stack.
[I386] I picked up Bob's v86 support.
The IO permission bit implementation is suboptimal.
It copies the IO permission bits into the kernel's TSS
at every context-switch to a thread with bits set.
I added a ddb command, continue-with-count (c/c).
It continues, counting instructions, until a breakpoint is hit.
On the pmax, loads and stores are also counted.
I added a debugging call, host_virtual_physical_table_info,
to return information about the VP hash table.
The hash_info program in the USER tree uses it.
I enabled software reference bits (again) and
disabled TLB reference bits on the pmax (again).
Bug fixes:
--- -----
I revised the way the network code allocates message buffers.
It should drop fewer packets now. This improves network
performance significantly on some machines.
I changed the zone package to make zones non-collectable by default.
The only collectable zones now are the large kalloc zones.
Numerous minor fixes, including stuff from Sandro & Bob...
[ ./conf/version.edit ]
40
[ ./include/Makefile ]
Added mach_debug/hash_info.h.
[91/01/04 rpd]
[ ./kernel/conf/MASTER ]
Removed FAST_CSW (tag fast_csw).
[90/12/08 rpd]
Removed MACH_IPC_GENNOS (tag ipc_gennos).
[90/11/08 rpd]
[ ./kernel/conf/MASTER.mips ]
Disabled ref_bits. Again.
[91/01/04 rpd]
[ ./kernel/conf/files ]
Removed ./mach/exc_user.c.
[90/12/26 rpd]
Removed FAST_CSW.
[90/12/08 rpd]
Removed MACH_IPC_GENNOS.
[90/11/08 rpd]
[ ./kernel/ddb/db_break.c ]
Added db_map_equal, db_map_current, db_map_addr.
[90/11/10 rpd]
[ ./kernel/ddb/db_run.c ]
Fixed bug in db_restart_at_pc.
[90/12/07 rpd]
Added STEP_COUNT and count option to db_continue_cmd.
Changed db_stop_at_pc to return (modified) is_breakpoint.
Fixed db_stop_at_pc to print newlines in the right places.
[90/11/27 rpd]
[ ./kernel/ddb/db_trap.c ]
Changed db_stop_at_pc's arguments.
Print db_inst_count, db_load_count, db_store_count.
[90/11/27 rpd]
[ ./kernel/ddb/db_watch.c ]
Use db_map_equal, db_map_current, db_map_addr.
[90/11/10 rpd]
[ ./kernel/device/dev_master.h ]
Added continuation argument to thread_block.
[90/12/08 rpd]
[ ./kernel/device/ds_routines.c ]
Added continuation argument to thread_block.
[90/12/08 rpd]
[ ./kernel/device/net_io.c ]
Replaced NET_KMSG_GET, NET_KMSG_FREE
with net_kmsg_get, net_kmsg_put, net_kmsg_collect.
Increased net_kmsg_ilist_min to 4.
[91/01/05 rpd]
Fixed net_rcv_msg_thread to round message sizes up to an int multiple.
[90/12/07 rpd]
Fixed net_rcv_msg_thread to not set vm_privilege.
[90/11/29 rpd]
[ ./kernel/device/net_io.h ]
Replaced NET_KMSG_GET, NET_KMSG_FREE
with net_kmsg_get, net_kmsg_put, net_kmsg_collect.
[91/01/05 rpd]
[ ./kernel/device/subrs.c ]
Added continuation argument to thread_block.
[90/12/08 rpd]
[ ./kernel/i386/cswitch.s ]
Minor cleanup.
[90/12/31 rpd]
Added switch_task_context, switch_thread_context.
[90/12/12 rpd]
Reorganized the pcb.
[90/12/11 rpd]
[ ./kernel/i386/db_machdep.h ]
Added dummy inst_load/inst_store macros.
[90/12/11 rpd]
[ ./kernel/i386/db_trace.c ]
Reorganized the pcb.
[90/12/11 rpd]
[ ./kernel/i386/fpu.c ]
Split i386_machine_state off of i386_kernel_state.
[90/12/31 rpd]
Reorganized the pcb.
[90/12/11 rpd]
[ ./kernel/i386/genassym.c ]
Reorganized the pcb.
[90/12/11 rpd]
[ ./kernel/i386/init.c ]
Initialize the new pcb zone in machine_init.
[90/12/11 rpd]
[ ./kernel/i386/locore.s ]
Replaced thread_bootstrap_user, thread_bootstrap_kernel
with thread_exception_return, thread_syscall_return.
Updated mach_trap_table indexing for new layout.
[90/12/17 rpd]
Renamed thread_bootstrap to thread_bootstrap_user.
Added thread_bootstrap_kernel.
[90/12/14 rpd]
Reorganized the pcb.
Added copyinmsg, copyoutmsg synonyms for copyin, copyout.
[90/12/11 rpd]
[ ./kernel/i386/pcb.c ]
Removed pcb_synch. Added pcb_collect.
[91/01/03 rpd]
Split i386_machine_state off of i386_kernel_state.
Set k_stack_top correctly for V8086 threads.
[90/12/31 rpd]
Added stack_switch. Moved stack_alloc_try, stack_alloc,
stack_free, stack_statistics to kern/thread.c.
[90/12/14 rpd]
Reorganized the pcb.
Added stack_attach, stack_alloc, stack_alloc_try,
stack_free, stack_statistics.
[90/12/11 rpd]
[ ./kernel/i386/read_fault.c ]
Changed VM_WAIT to VM_PAGE_WAIT.
[90/12/11 rpd]
[ ./kernel/i386/thread.h ]
Added i386_machine_state.
[91/01/03 22:05:01 rpd]
Reorganized the pcb.
[90/12/11 rpd]
[ ./kernel/i386/trap.c ]
Only need csw_needed in AST exit path.
[90/12/27 rpd]
Replaced thread_doexception with new exception interface.
[90/12/21 rpd]
Added continuation argument to thread_block.
[90/12/08 rpd]
[ ./kernel/i386at/if_3c501.c ]
Changed NET_KMSG_GET, NET_KMSG_FREE to net_kmsg_get, net_kmsg_put.
[91/01/05 rpd]
[ ./kernel/i386at/if_pc586.c ]
Changed NET_KMSG_GET, NET_KMSG_FREE to net_kmsg_get, net_kmsg_put.
[91/01/05 rpd]
[ ./kernel/i386at/if_wd8003.c ]
Changed NET_KMSG_GET, NET_KMSG_FREE to net_kmsg_get, net_kmsg_put.
[91/01/05 rpd]
[ ./kernel/i386ipsc/if_cnp.c ]
Changed NET_KMSG_GET, NET_KMSG_FREE to net_kmsg_get, net_kmsg_put.
[91/01/05 rpd]
[ ./kernel/intel/pmap.c ]
Changed pmap_collect to ignore the kernel pmap.
[91/01/03 rpd]
[ ./kernel/ipc/ipc_entry.c ]
Removed MACH_IPC_GENNOS.
[90/11/08 rpd]
[ ./kernel/ipc/ipc_entry.h ]
Removed MACH_IPC_GENNOS, IE_BITS_UNUSEDC, IE_BITS_UNUSEDG.
[90/11/08 rpd]
[ ./kernel/ipc/ipc_hash.c ]
Changed ipc_info_bucket_t to hash_info_bucket_t.
[91/01/02 rpd]
[ ./kernel/ipc/ipc_hash.h ]
Changed ipc_info_bucket_t to hash_info_bucket_t.
[91/01/02 rpd]
[ ./kernel/ipc/ipc_init.c ]
Changed zchange calls to make the IPC zones non-collectable.
[90/12/29 rpd]
[ ./kernel/ipc/ipc_kmsg.c ]
Added ipc_kmsg_free.
[91/01/05 rpd]
Optimized ipc_kmsg_copyout_object for send rights.
[90/12/21 rpd]
Changed to use new copyinmsg/copyoutmsg operations.
Changed ipc_kmsg_get to check that the size is multiple of four.
[90/12/05 rpd]
Removed MACH_IPC_GENNOS.
[90/11/08 rpd]
[ ./kernel/ipc/ipc_kmsg.h ]
Added ipc_kmsg_free. Generalized the notion of special message sizes.
[91/01/05 rpd]
Added declarations of ipc_kmsg_copyout_object, ipc_kmsg_copyout_body.
[90/12/21 rpd]
[ ./kernel/ipc/ipc_marequest.c ]
Changed ipc_info_bucket_t to hash_info_bucket_t.
[91/01/02 rpd]
Changed zchange calls to make the IPC zones non-collectable.
[90/12/29 rpd]
[ ./kernel/ipc/ipc_marequest.h ]
Changed ipc_info_bucket_t to hash_info_bucket_t.
[91/01/02 rpd]
[ ./kernel/ipc/ipc_mqueue.c ]
Changed continuation argument to (void (*)()).
[90/12/18 rpd]
Reorganized ipc_mqueue_receive.
[90/11/22 rpd]
Minor cleanup.
[90/11/11 rpd]
[ ./kernel/ipc/ipc_mqueue.h ]
Changed continuation argument and IMQ_NULL_CONTINUE to (void (*)()).
[90/12/18 rpd]
Reorganized ipc_mqueue_receive.
[90/11/22 rpd]
[ ./kernel/ipc/ipc_space.c ]
Removed MACH_IPC_GENNOS.
[90/11/08 rpd]
[ ./kernel/ipc/mach_debug.c ]
Changed ipc_info_bucket_t to hash_info_bucket_t.
[91/01/02 rpd]
Removed MACH_IPC_GENNOS.
[90/11/08 rpd]
[ ./kernel/ipc/mach_msg.c ]
Added KEEP_STACKS support.
[91/01/07 rpd]
Changed to use thread_syscall_return.
Added msg_receive_continue.
[90/12/18 rpd]
Added mach_msg_continue, mach_msg_receive_continue.
Changes to support kernel stack discarding/hand-off.
[90/12/09 17:29:04 rpd]
Removed MACH_IPC_GENNOS.
[90/11/08 rpd]
[ ./kernel/ipc/mach_msg.h ]
Created.
[90/11/22 rpd]
[ ./kernel/ipc/port.h ]
Removed MACH_IPC_GENNOS.
[90/11/08 rpd]
[ ./kernel/kern/exception.c ]
Added KEEP_STACKS support.
[91/01/08 14:11:40 rpd]
Replaced thread_doexception with new, optimized exception path.
[90/12/22 rpd]
[ ./kernel/kern/ipc_mig.c ]
Don't need mach_msg_rpc_from_kernel.
[90/12/26 rpd]
Updated ipc_mqueue_receive calls.
[90/11/21 rpd]
Removed MACH_IPC_GENNOS.
[90/11/09 rpd]
[ ./kernel/kern/ipc_sched.c ]
Added KEEP_STACKS support.
[91/01/06 rpd]
Added ipc_thread_switch_hits, ipc_thread_switch_misses counters.
[91/01/03 22:07:15 rpd]
Modified ipc_thread_switch to deal with pending timeouts.
[90/12/20 rpd]
Removed ipc_thread_go_and_block.
Added ipc_thread_switch.
[90/12/08 rpd]
[ ./kernel/kern/ipc_sched.h ]
Removed ipc_thread_go_and_block.
Added ipc_thread_switch.
Added continuation argument to ipc_thread_block.
[90/12/08 rpd]
[ ./kernel/kern/ipc_tt.c ]
Added retrieve_task_self_fast, retrieve_thread_self_fast.
[90/12/27 rpd]
[ ./kernel/kern/ipc_tt.h ]
Added retrieve_task_self_fast, retrieve_thread_self_fast.
[90/12/27 rpd]
[ ./kernel/kern/mach_clock.c ]
Added continuation argument to thread_block.
[90/12/08 rpd]
[ ./kernel/kern/machine.c ]
Added continuation argument to thread_block.
[90/12/08 rpd]
[ ./kernel/kern/sched_prim.c ]
Added KEEP_STACKS support.
[91/01/06 rpd]
Added thread_continue_calls counter.
[91/01/03 22:07:43 rpd]
Added continuation argument to thread_run.
[90/12/11 rpd]
Added continuation argument to thread_block/thread_continue.
Removed FAST_CSW conditionals.
[90/12/08 rpd]
Removed thread_swap_tick.
[90/11/11 rpd]
[ ./kernel/kern/startup.c ]
Swapin the startup thread and idle threads.
[90/11/20 rpd]
Removed swapout_thread.
[90/11/11 rpd]
[ ./kernel/kern/syscall_subr.c ]
Added continuation argument to thread_run.
[90/12/11 rpd]
Added continuation argument to thread_block.
[90/12/08 rpd]
[ ./kernel/kern/syscall_sw.c ]
Changed to use MACH_TRAP_STACK appropriately.
[90/12/27 21:20:57 rpd]
[ ./kernel/kern/syscall_sw.h ]
Added mach_trap_stack, MACH_TRAP_STACK.
[90/12/18 rpd]
[ ./kernel/kern/task.c ]
Added consider_task_collect, task_collect_scan.
[91/01/03 rpd]
Added continuation argument to thread_block.
[90/12/08 rpd]
[ ./kernel/kern/thread.c ]
Added KEEP_STACKS support.
[91/01/06 rpd]
Added consider_thread_collect, thread_collect_scan.
[91/01/03 rpd]
Added locking to the stack package. Added stack_collect.
[90/12/31 rpd]
Changed thread_dowait to discard the stacks of suspended threads.
[90/12/22 rpd]
Added continuation argument to thread_block.
[90/12/08 rpd]
Changed thread_create to make new threads be swapped.
Changed kernel_thread to swapin the threads.
[90/11/20 rpd]
Removed stack_free/stack_alloc/etc.
[90/11/12 rpd]
Changed thread_create to let pcb_init handle all pcb initialization.
[90/11/11 rpd]
[ ./kernel/kern/thread.h ]
Added saved-state fields for exceptions.
[90/12/23 rpd]
Added swap_func.
[90/11/20 rpd]
[ ./kernel/kern/thread_swap.c ]
Added continuation argument to thread_block.
[90/12/08 rpd]
Removed swapout_thread, swapout_threads,
swapout_scan, thread_swapout.
[90/11/11 rpd]
[ ./kernel/kern/zalloc.c ]
Added zalloc_wasted_space.
[91/01/06 rpd]
Removed COLLECT_ZONE_GARBAGE.
[91/01/03 rpd]
Changed zinit to make zones by default *not* collectable.
[90/12/29 rpd]
Added consider_zone_gc.
[90/11/11 rpd]
[ ./kernel/kern/zalloc.h ]
Removed COLLECT_ZONE_GARBAGE. Added consider_zone_gc.
[91/01/03 rpd]
[ ./kernel/mach/mips/asm.h ]
Changed EF prefix to MSS.
[90/12/30 rpd]
[ ./kernel/mach/mips/vm_param.h ]
Reduced kernel stack size to one page.
[90/11/12 rpd]
[ ./kernel/mach_debug/hash_info.h ]
Created.
[91/01/02 rpd]
[ ./kernel/mach_debug/ipc_info.h ]
Moved ipc_info_bucket_t to mach_debug/hash_info.h.
[91/01/02 rpd]
[ ./kernel/mach_debug/mach_debug.defs ]
Added host_virtual_physical_table_info.
[91/01/02 rpd]
[ ./kernel/mach_debug/mach_debug_types.h ]
Added
[91/01/02 rpd]
[ ./kernel/mips/PMAX/if_se.c ]
Changed NET_KMSG_GET, NET_KMSG_FREE to net_kmsg_get, net_kmsg_put.
[91/01/05 rpd]
[ ./kernel/mips/PMAX/mouse.c ]
Mouse events are now accounted for by the screen saver.
[91/01/04 15:35:30 af]
[ ./kernel/mips/PMAX/screen.c ]
Added compress_mouse_events, by default FALSE.
[91/01/08 14:14:03 rpd]
[ ./kernel/mips/PMAX/scsi_53C94_hdw.c ]
Added continuation argument to thread_block.
[90/12/27 rpd]
[ ./kernel/mips/PMAX/scsi_7061_hdw.c ]
Catched hitachi's problem: spurious interrupt _before_
dmain/out even got started.
[90/12/29 af]
Added continuation argument to thread_block.
[90/12/27 rpd]
[ ./kernel/mips/autoconf.c ]
Added pcb_zone.
[90/12/09 17:34:12 rpd]
[ ./kernel/mips/context.h ]
Removed TLB_SAFE_KSTACK, TLB_SAFE_KSTACK1.
[90/12/08 rpd]
[ ./kernel/mips/context.s ]
Added mips_stack_base.
[91/01/02 rpd]
Split mips_machine_state off of mips_kernel_state.
Moved stack_switch to mips/pcb.c.
[90/12/30 rpd]
Removed load_context_ipc, save_context.
Added switch_task_context, switch_thread_context.
[90/12/08 rpd]
Added stack_switch, load_context_ipc.
[90/11/29 rpd]
Changed save_context/load_context for pcb reorganization.
Removed stack wiring code from load_context.
Disabled pmap_pcache code.
[90/11/12 rpd]
[ ./kernel/mips/db_interface.c ]
Changed kdb_trap to return TRUE if it actually enters kdb.
[90/12/23 rpd]
Fixed to use kdbsplhigh/kdbsplx.
[90/11/26 rpd]
[ ./kernel/mips/db_machdep.h ]
Added inst_load, inst_store.
[90/11/27 rpd]
[ ./kernel/mips/db_trace.c ]
Quit tracing after hitting a zero pc.
[90/12/31 rpd]
Changed for new pcb organization.
[90/11/12 rpd]
[ ./kernel/mips/genassym.c ]
Added mips_stack_base.
[91/01/02 rpd]
Changed to consistent MKS_, MSS_, MEL_, MMS_ prefixes.
Split mips_machine_state off of mips_kernel_state.
[90/12/30 rpd]
Added PCB_SIZE.
[90/11/12 rpd]
[ ./kernel/mips/locore.s ]
Fixed gimmeabreak to allow the user to single-step out of it.
[91/01/06 rpd]
Added mips_stack_base.
[91/01/02 rpd]
Split mips_machine_state off of mips_kernel_state.
[90/12/30 rpd]
Moved thread_exception_return to mips/trap.c.
[90/12/23 rpd]
Replaced thread_bootstrap_user, thread_bootstrap_kernel
with thread_exception_return, thread_syscall_return.
Updated native syscall processing for new mach_trap_table layout.
[90/12/18 rpd]
Changed the exception frame/pcb layout.
[90/11/19 rpd]
[ ./kernel/mips/mips_copyin.s ]
Added copyinmsg, copyoutmsg.
Fixed copyin to check correctly for user space violations.
[90/12/05 rpd]
[ ./kernel/mips/mips_cpu.s ]
Updated for new symbolic field names.
[91/01/03 22:10:08 rpd]
Replaced thread_doexception with exception.
[90/12/27 21:22:32 rpd]
Added kdbsplhigh and kdbsplx.
[90/11/26 rpd]
Changed disable_fpa for new pcb organization.
[90/11/12 rpd]
[ ./kernel/mips/mips_init.c ]
Changed for pcb reorganization.
[90/11/12 rpd]
[ ./kernel/mips/mips_instruction.c ]
Added isa_load, isa_store.
[90/11/27 rpd]
[ ./kernel/mips/pcb.c ]
Removed pcb_synch. Added pcb_collect.
[91/01/03 rpd]
Added mips_stack_base.
[91/01/02 rpd]
Split mips_machine_state off of mips_kernel_state.
Moved stack_switch here from mips/context.s.
[90/12/30 rpd]
Eliminated thread_bootstrap_user, thread_bootstrap_kernel.
[90/12/19 rpd]
Added pcb_alloc/pcb_free. Use vm_page_grab/vm_page_free
for kernel stacks. Reorganized the pcb layout.
Removed thread_private.
[90/11/11 rpd]
[ ./kernel/mips/thread.h ]
Added mips_stack_base.
[91/01/02 rpd]
Split mips_machine_state off of mips_kernel_state.
Changed mips_exception_state to mips_exception_link.
[90/12/30 rpd]
Added definition of MACHINE_STACK.
[90/12/14 rpd]
Added mips_exception_state, USER_LINK.
[90/11/13 rpd]
Changed pcb to include both mips_kernel_state and mips_saved_state.
[90/11/11 rpd]
[ ./kernel/mips/tlb.s ]
Removed tlb_probe_and_wire.
[90/11/12 rpd]
[ ./kernel/mips/trap.c ]
Added a couple counters to tlb_miss.
[91/01/08 14:15:03 rpd]
Disabled pcache code.
[90/12/29 rpd]
Replaced thread_doexception with new exception interface.
Moved thread_exception_return here from mips/locore.s.
It must install single-step breakpoints in the user.
Added thread_kdb_return.
[90/12/23 rpd]
Added continuation argument to thread_block.
[90/12/08 rpd]
Added support for copymsgin, copymsgout.
[90/12/05 rpd]
Changed for new pcb organization.
[90/11/12 rpd]
[ ./kernel/sun3/db_machdep.h ]
Added dummy inst_load/inst_store macros.
[91/01/06 rpd]
[ ./kernel/sun3/locore.s ]
Added copyinmsg, copyoutmsg aliases.
Updated for new mach_trap_table layout.
[91/01/06 rpd]
[ ./kernel/sun3/pcb.c ]
Added KEEP_STACKS support.
[91/01/06 rpd]
Added empty frame on thread start for tracing.
[89/05/25 rwd]
Converted for MACH kernel.
[88/11/03 dbg]
[ ./kernel/sun3/thread.h ]
Added KEEP_STACKS support.
[91/01/06 rpd]
[ ./kernel/sun3/trap.c ]
Added KEEP_STACKS support.
[91/01/07 rpd]
Added continuation argument to thread_block.
[90/12/08 rpd]
[ ./kernel/sundev/cgtwo.c ]
Added continuation argument to thread_block.
[90/12/08 rpd]
[ ./kernel/sundev/mb.c ]
Added continuation argument to thread_block.
[90/12/08 rpd]
Modified for MACH_KERNEL.
[89/03/22 dbg]
[ ./kernel/sundev/sd.c ]
Added continuation argument to thread_block.
[90/12/08 rpd]
[ ./kernel/sundev/st.c ]
Added continuation argument to thread_block.
[90/12/08 rpd]
[ ./kernel/sundev/xy.c ]
Added continuation argument to thread_block.
[90/12/08 rpd]
[ ./kernel/sundev/zs_async.c ]
Added continuation argument to thread_block.
[90/12/08 rpd]
[ ./kernel/sunif/if_ie.c ]
Changed NET_KMSG_GET, NET_KMSG_FREE to net_kmsg_get, net_kmsg_put.
[91/01/05 rpd]
[ ./kernel/sunif/if_le.c ]
Changed NET_KMSG_GET, NET_KMSG_FREE to net_kmsg_get, net_kmsg_put.
[91/01/05 rpd]
[ ./kernel/vax/db_machdep.h ]
Added dummy inst_load/inst_store macros.
[91/01/06 rpd]
[ ./kernel/vax/inline/langpats.c ]
Added copyinmsg, copyoutmsg.
[91/01/06 rpd]
[ ./kernel/mach_debug/mach_debug_types.defs ]
Changed ipc_info_bucket_t to hash_info_bucket_t.
[91/01/02 rpd]
[ ./kernel/mips/PMAX/dz_hdw.c ]
Modified dz_param never to use 7bits per char.
Now we can use the serial lines even in non-raw mode,
which means we can login, for instance.
[90/12/31 af]
[ ./kernel/mips/softfp.s ]
Replaced thread_doexception with new exception interface.
[90/12/23 rpd]
[ ./kernel/vax/locore.s ]
Updated for new mach_trap_table layout.
[91/01/06 rpd]
[ ./kernel/vax/model_dep.c ]
Added continuation argument to thread_block.
[90/12/08 rpd]
[ ./kernel/vax/mscp.c ]
Added continuation argument to thread_block.
[90/12/08 rpd]
Changes for MACH_KERNEL.
[88/08/29 dbg]
Compile the error printing code if (NTMSCP > 0) as well as if NET_UDA.
Directly include
won't work (and must be left intact if NET_UDA is not true).
[88/08/29 mwyoung]
Corrected include file references.
[88/08/22 mwyoung]
[ ./kernel/vax/pcb.c ]
Added KEEP_STACKS support.
[91/01/06 rpd]
[ ./kernel/vax/thread.h ]
Added KEEP_STACKS support.
[91/01/06 rpd]
[ ./kernel/vax/trap.c ]
Added KEEP_STACKS support.
[91/01/07 rpd]
Added continuation argument to thread_block.
[90/12/08 rpd]
[ ./kernel/vaxif/if_ni.c ]
Changed NET_KMSG_GET, NET_KMSG_FREE to net_kmsg_get, net_kmsg_put.
[91/01/05 rpd]
[ ./kernel/vaxif/if_uba.c ]
Changed NET_KMSG_GET, NET_KMSG_FREE to net_kmsg_get, net_kmsg_put.
[91/01/05 rpd]
[ ./kernel/vaxuba/qd.c ]
Added continuation argument to thread_block.
[90/12/08 rpd]
[ ./kernel/vaxuba/uba.c ]
Added continuation argument to thread_block.
[90/12/08 rpd]
[ ./kernel/vaxuba/uda_umd.c ]
Added continuation argument to thread_block.
[90/12/08 rpd]
[ ./kernel/vm/memory_object.c ]
Added continuation argument to thread_block.
[90/12/08 rpd]
[ ./kernel/vm/vm_debug.c ]
Added host_virtual_physical_table_info.
[91/01/02 rpd]
[ ./kernel/vm/vm_external.c ]
Changed zchange calls to make the zones non-collectable.
[90/12/29 rpd]
[ ./kernel/vm/vm_fault.c ]
Turned software_reference_bits on.
[90/12/29 rpd]
Added continuation argument to thread_block.
[90/12/08 rpd]
Changed VM_WAIT to VM_PAGE_WAIT.
[90/11/13 rpd]
[ ./kernel/vm/vm_kern.c ]
Changed VM_WAIT to VM_PAGE_WAIT.
[90/11/13 rpd]
[ ./kernel/vm/vm_map.c ]
Added continuation argument to thread_block.
[90/12/08 rpd]
[ ./kernel/vm/vm_object.c ]
Added continuation argument to thread_block.
[90/12/08 rpd]
Fixed vm_object_terminate to give vm_pageout_page busy pages.
[90/11/22 rpd]
Changed VM_WAIT to VM_PAGE_WAIT.
[90/11/13 rpd]
[ ./kernel/vm/vm_page.h ]
Changed to singly-linked VP bucket chains.
[91/01/03 rpd]
Changed vm_wait/VM_WAIT to vm_page_wait/VM_PAGE_WAIT.
[90/11/13 rpd]
[ ./kernel/vm/vm_pageout.c ]
Added net_kmsg_collect.
[91/01/05 rpd]
Added consider_task_collect, consider_thread_collect.
[91/01/03 rpd]
Added stack_collect.
[90/12/31 rpd]
Added continuation argument to thread_block.
[90/12/08 rpd]
Ensure that vm_page_free_target is at least five pages
larger than vm_page_free_min, to avoid vm_page_wait deadlock.
[90/11/19 rpd]
Replaced swapout_threads with consider_zone_gc.
[90/11/11 rpd]
[ ./kernel/vm/vm_resident.c ]
Changed to singly-linked VP bucket chains.
[91/01/03 rpd]
Removed count field from VP buckets.
Added vm_page_info.
[91/01/02 rpd]
Added vm_page_grab, vm_page_release.
Changed vm_wait/VM_WAIT to vm_page_wait/VM_PAGE_WAIT.
[90/12/09 17:41:15 rpd]
[ ./user/threads/i386/csw.s ]
Don't use Times - horta doesn't like it for some reason.
[91/01/06 rpd]
[ ./kernel/conf/MASTER.i386 ]
Switch wd8003 -> ns8390
[91/01/04 12:13:52 rvb]
[ ./kernel/conf/files.i386 ]
Switch wd8003 -> ns8390
[91/01/04 12:14:06 rvb]
[ ./kernel/ddb/db_command.c ]
Forward reference for db_fncall();
[91/01/04 12:35:17 rvb]
Add call as a synonym for ! and match for next
[91/01/04 12:14:48 rvb]
[ ./kernel/i386/hardclock.c ]
EFL_VM => user_mode
[90/12/21 10:50:54 rvb]
[ ./kernel/i386/interrupt.s ]
Need special interrupt_return
[90/12/21 14:36:12 rvb]
[ ./kernel/i386/locore.s ]
interrupt_returns must check for EFL_VM.
[90/12/21 14:37:44 rvb]
Add trapv86 for VM thread.
[90/12/19 17:00:56 rvb]
[ ./kernel/i386/pit.c ]
Flush dead EXL code.
[90/11/27 11:38:08 rvb]
[ ./kernel/i386/trap.c ]
Add v86_hdw_assist().
[91/01/04 09:54:24 rvb]
Basically add trapv86()
[90/12/20 10:21:01 rvb]
[ ./kernel/i386/tss.h ]
Add bit_map
[90/12/20 10:21:17 rvb]
[ ./kernel/i386at/blitvar.h ]
Trim $ header
[90/11/27 11:44:11 rvb]
[ ./kernel/i386at/conf.c ]
Support for get/set status on hd and fd.
Also fd has 64 minor devices per unit.
Switch wd8003 -> ns8390
[91/01/04 12:17:15 rvb]
[ ./kernel/i386at/disk.h ]
Add V_ABS to log absolute address for 3.0 get/set stat version
of V_RDABS AND V_WRABS
[91/01/04 12:18:16 rvb]
[ ./kernel/i386at/hd.c ]
Allow ioctl's
[90/12/19 rvb]
[ ./kernel/i386at/if_3c503.h ]
Etherlink II device specific info.
[91/01/04 12:19:07 rvb]
[ ./kernel/i386at/if_ns8390.c ]
A few bug fixes.
[91/01/08 16:41:04 rvb]
Make this a generic driver for ns8390 from wd8003 because
we now will also support etherlink ii.
[91/01/04 12:25:21 rvb]
[ ./kernel/i386at/if_ns8390.h ]
Restrict to defines for the 8390 only.
[91/01/04 12:25:57 rvb]
[ ./kernel/i386at/if_wd8003.h ]
Flush generic NS8390 defines to an NS8390 header file.
[91/01/04 12:20:35 rvb]
[ ./kernel/i386at/kd_mouse.c ]
Trim $ Header
[90/11/27 11:44:31 rvb]
[ ./kernel/i386at/m765knl.c ]
Add some 3.0 get/set stat stuff.
[91/01/04 12:21:06 rvb]
[ ./kernel/i386at/pic_isa.c ]
Initially, do not allow clock interrupts
[91/01/04 12:21:54 rvb]
[ ./kernel/mach/i386/thread_status.h ]
Two new flavors (from 2.5):
#define i386_FLOAT_STATE 2
Hacked in not presently used, but someday...
#define i386_ISA_PORT_MAP_STATE 3
Used
[90/12/20 10:23:34 rvb]
[ ./kernel/i386at/if_ns8390.c ]
Changed NET_KMSG_GET to net_kmsg_get.
[91/01/08 rpd]
[ ./kernel/i386at/if_wd8003.c ]
Purged.
[ ./include/Makefile ]
Added i386/fp_reg.h.
[91/01/08 rpd]
[ ./include/Makefile ]
Added i386at/disk.h.
[ ./kernel/mach_debug/Makefile ]
Purged.
[ ./kernel/i386at/if_ns8390.c ]
Fixed typo in ns8390probe.
[91/01/09 rpd]
[ ./kernel/mips/PMAX/boot/primary_boot.c ]
For new proms, zero envp because it is bogus. This lets
me boot 2.5 on 3maxen again.
[91/01/09 16:33:38 af]
[ ./kernel/i386/pit.c ]
Fixed clkstart to reset clock interrupt priority, etc.
[91/01/09 rpd]
Flush dead EXL code.
[90/11/27 11:38:08 rvb]
[ ./kernel/mips/PMAX/mips_box.c ]
Defined pmax_memcheck() and related default implementation.
[91/01/03 02:10:32 af]
[ ./kernel/mips/PMAX/mips_box.h ]
Now define mipsbox_memory_check() to cope with bus lockup
caused by pmax SII chip.
[91/01/02 af]
[ ./kernel/mips/PMAX/kn01.c ]
Added kn01_memcheck().
[91/01/03 02:09:21 af]
[ ./kernel/mips/PMAX/model_dep.c ]
Set pmax_memcheck() for pmaxen.
[91/01/03 02:12:58 af]
[ ./kernel/mips/trap.c ]
Check mipsbox_memory_check return value.
[91/01/09 rpd]
[ ./kernel/i386/db_trace.c ]
Fixed stack tracing for threads without kernel stacks.
[91/01/09 rpd]
[ ./kernel/i386at/autoconf.c ]
Converted from wd8003 to ns8390.
[91/01/08 rpd]
[ ./kernel/mips/db_trace.c ]
Fixed stack tracing for threads without kernel stacks.
[91/01/09 rpd]
[ ./kernel/i386/cswitch.s ]
Renamed to Load_context and Switch_task_context.
Removed ktss munging.
[91/01/09 rpd]
[ ./kernel/i386/genassym.c ]
Removed user_regs, k_stack_top.
[91/01/09 rpd]
[ ./kernel/i386/init.c ]
Added ktss zone.
[91/01/09 rpd]
[ ./kernel/i386/locore.s ]
Removed k_user_regs.
[91/01/09 rpd]
[ ./kernel/i386/pcb.c ]
Revised the pcb yet again.
Picked up i386_ISA_PORT_MAP_STATE flavors.
Added load_context, switch_task_context cover functions.
[91/01/09 rpd]
[ ./kernel/i386/thread.h ]
Added dummy switch_thread_context macro.
Added ktss to i386_machine_state.
Removed user_regs, k_stack_top.
[91/01/09 rpd]
[ ./kernel/i386/trap.c ]
Fixed a merge bug.
[91/01/09 rpd]
==========================================================================
***** MK Version MK41 (mrt) *****
Added the new Mach copyright and disclaimer to all the machine
independent files and the i386 and mips files. At this point
we are allowd to distribute freely all the files needed for
the i386 and mips platforms.
Changed personal copyrights to author notices and added author
notices to the files in the devices, ddb and mips directories.
I would encourage people to put author notices on any files
that they created or will create. Please do not put personal
copyrights on files as it casts doubt over the rights of
Carnegie Mellon to distribute the files.
Since we will now be distributing these sources without requiring
any licenses, please be very careful about adding any files with
copyright notices that do not include a permission to distribute
clause like the CMU one. If for some reason it is necessary to
include a copyrighted file, be sure to tell me,so that I can exclude
it from the ftp distribution.
There was no change to code in this release.
==========================================================================
***** MK Version MK42 (mrt) *****
Bug fixes:
--- -----
[I386] Picked up Rich Draves intel/pmap.c fix to keep the i386 version
from hanging
Picked up a number of i386 changes from Bob
[PMAX] Picked up the scsi driver fix from Sandro and lots of other
mips specfic files.
Organizational changes:
-------------- -------
All the libmach, theads and man sections now have the new Mach
permissive copyright
I upgraded the libmach i386 bcopy routine to reno in order to
get a BSD permissive copyright.
******** CUT HERE ******** summary of log messages ******** CUT HERE ********
[ ./conf/version.edit ]
42
Changes from Rich
[ ./kernel/intel/pmap.c ]
Fixed pmap_expand to use vm_page_grab/VM_PAGE_WAIT.
[91/01/12 rpd]
[ ./kernel/ipc/ipc_right.c ]
Fixed bug in ipc_right_copyin_check, following rchen's report.
[91/01/26 rpd]
******************************************************************
Copyright changes
[ ./kernel/conf/copyright ]
New Mach copyright
[ ./kernel/man/* ]
Changed to new Mach copyright
[91/02/12 18:10:12 mrt]
[ ./user/libmach/* ]
Added new Mach copyright
[91/02/13 12:45:25 mrt]
[ ./user/threads/* ]
Added new Mach copyright
[91/02/13 12:40:50 mrt]
[ ./kernel/sys/ioctl.h ]
Changed to new Mach copyright
[ ./kernel/i386/ntoh.s ]
Changed to new Mach copyright
******************************************************************
Mips changes from Sandro
[ ./kernel/mips/PMAX/cfb_hdw.c ]
In interrupt routine, drop priority as now required.
[91/02/12 12:44:36 af]
[ ./kernel/mips/PMAX/dz_hdw.c ]
In interrupt routine, drop priority as now required.
[91/02/12 12:45:12 af]
Modified dz_param never to use 7bits per char.
Now we can use the serial lines even in non-raw mode,
which means we can login, for instance.
[90/12/31 af]
[ ./kernel/mips/PMAX/ga_hdw.c ]
In interrupt routine, drop priority as now required.
[91/02/12 12:43:54 af]
[ ./kernel/mips/PMAX/gq_hdw.c ]
In interrupt routine, drop priority as now required.
[91/02/12 12:44:15 af]
[ ./kernel/mips/PMAX/if_se.c ]
In interrupt routine, drop priority as now required.
Added (optional) loopback of packets sent to ourselves,
this way can run multiple POEs and have them talk to each other.
Same flag lets you run with external hardware loopback terminator
ignoring no-carrier errors.
Fixed bug with multiple ether boards.
Fixed bug with loopback path shifting data incorrectly.
[91/02/12 12:53:29 af]
[ ./kernel/mips/PMAX/if_se_mapped.c ]
In interrupt routine, drop priority as now required.
Also sanity check for spurious interrupts anyways.
[91/02/12 12:41:46 af]
[ ./kernel/mips/PMAX/kn01.c ]
In interrupt routines, drop priority as now required.
[91/02/12 12:54:42 af]
Added kn01_memcheck().
[91/01/03 02:09:21 af]
[ ./kernel/mips/PMAX/kn02.c ]
Pass along the spllevel to interrupt routines.
[91/02/12 12:40:09 af]
[ ./kernel/mips/PMAX/mapped_scsi.c ]
In interrupt routines, drop priority as now required.
Also, sanity check against spurious interrupts.
[91/02/12 13:17:21 af]
[ ./kernel/mips/PMAX/mc_clock.c ]
Factored out delay() function, and made it box-indep.
Added accurate_config_delay() which calls delay()'s
configuration code. Modified ackrtclock() to
invoke it on first call.
Tell the user what the CPU clock speed loks like,
distinguish between DS3100 and DS2100 based on clock speed.
[91/02/12 13:03:16 af]
[ ./kernel/mips/PMAX/mc_clock.h ]
New values for delay() function.
[91/02/12 13:04:04 af]
[ ./kernel/mips/PMAX/mips_box.c ]
In clock interrupt routine, drop priority as now required.
[91/02/12 12:59:26 af]
Defined pmax_memcheck() and related default implementation.
[91/01/03 02:10:32 af]
[ ./kernel/mips/PMAX/mips_box.h ]
Fix macros so that interrupt routines can drop priority as now required.
[91/02/12 12:56:04 af]
[ ./kernel/mips/PMAX/mouse.c ]
Sanity check so that we will never loose synch if the serial line
drops characters.
[91/02/12 12:57:21 af]
Mouse events are now accounted for by the screenm saver.
[91/01/04 15:35:30 af]
[ ./kernel/mips/PMAX/pm_hdw.c ]
In interrupt routine, drop priority as now required.
[91/02/12 12:42:39 af]
[ ./kernel/mips/PMAX/rz_disk.c ]
Added (optional and disabled) code for checksumming.
[91/02/12 12:58:27 af]
Bug in strategy routine: for xfers larger than
max_dma was not setting the io_count right at
the end of the transfer. Now new fsck works.
[90/12/10 17:26:47 af]
[ ./kernel/mips/PMAX/scsi_53C94_hdw.c ]
In interrupt routine, drop priority as now required.
Also, sanity check for spurious interrupts.
Some more debugging tools.
[91/02/12 12:46:38 af]
[ ./kernel/mips/autoconf.c ]
New values for new delay() function.
[91/02/12 12:29:29 af]
[ ./kernel/mips/db_interface.c ]
Added flag not to invoke vm_fault(), used in crashed kernels.
[91/02/12 12:15:09 af]
[ ./kernel/mips/mips_cpu.s ]
Fixed a number of problems in the FPA emulation code.
Added delay() and its autotime function, this way we
can distinguish between DS3100 and DS2100.
[91/02/12 12:37:13 af]
[ ./kernel/mips/mips_instruction.c ]
Added branch_delay() for FPA emulation.
[91/02/12 12:23:19 af]
[ ./kernel/mips/pmap.c ]
Fixed pmap_attribute() to loop through all phys pages while
flushing the cache. If this gets used heavily for large
ranges it will be wise to just flush the whole cache in
one shot, or keep perhaps track of which 'cache pages'
need flushing and which do not.
[91/02/12 12:33:25 af]
[ ./kernel/mips/pmap.h ]
Made sure PTETOPHYS() does not get optimized away.
[91/01/10 af]
[ ./kernel/mips/softfp.s ]
The FPA csr is now passed as third argument.
[91/02/12 12:21:21 af]
[ ./kernel/device/net_io.c ]
Added garbage collection of dead filters.
[91/02/12 12:11:10 af]
[ ./kernel/mips/PMAX/scsi_7061_hdw.c ]
In interrupt routine, drop priority as now required.
[91/02/12 13:18:18 af]
[ ./kernel/mips/db_trace.c ]
Split trace function from ddb interface. Added (optional)
code to walk through a user-mode, optimized CThread program
like the U*x server. Should make it MI someday.
[91/02/12 12:18:59 af]
[ ./kernel/mips/locore.s ]
Reversed the meaning of the booleans in the ref_bits array.
[91/02/12 12:24:39 af]
[ ./kernel/mips/trap.c ]
Pass along the spl level to interrupt routines, which are now
invoked with interrupts DISABLED so that they can defend
themselves from unwarranted multiple invocations. It is
now the routine's responsibility to lower the spl at the indicated
priority level as soon as the interrupt cause has been cleared.
[91/02/12 12:28:43 af]
Activated mipsbox_memory_check() macro.
[91/01/03 02:08:14 af]
*************************************************************
Changes from Bob
[ ./kernel/ddb/db_input.c ]
Add input line editing.
[90/11/11 dbg]
[ ./kernel/i386/trap.c ]
rfr's latest changes to v86 assist
[91/01/28 15:25:30 rvb]
[ ./kernel/i386at/com.c ]
Merge of dbg's latest working com.c onto the old com.c
with the new autoconf and other major changes.
[91/01/28 15:26:13 rvb]
[ ./kernel/i386at/conf.c ]
Allow com driver and distinguish EtherLinkII from wd8003
[91/01/28 15:27:02 rvb]
[ ./kernel/i386at/fd.c ]
This file is the logical contatenation of the previous c765.c,
m765knl.c and m765drv.c, in that order.
[91/01/15 rvb]
[ ./kernel/i386at/fdreg.h ]
New, Improved, compatible with new fd.c
[91/01/28 15:33:58 rvb]
[ ./kernel/i386at/if_ns8390.c ]
Distinguish EtherLinkII vs WD8003 on open. Get packet
size right for statistics. Fix 3.0 buf that sometimes
reported packets too large.
[91/01/28 15:31:22 rvb]
[ ./kernel/i386at/if_pc586.c ]
You must check RBD_SW_EOF for rbd chain termination, a link of 0xffff
does not work. Also we've just seen a status of 0xffff in rcv() with
a bad fd_p->link_offset; we'll now reset.
[91/01/17 rvb]
[ ./kernel/i386at/kd.c ]
Merge cleanup.
[91/01/28 17:14:11 rvb]
Drop priority around display routines in kdstart, so that
scrolling or clearing the screen doesn't block other interrupts
(e.g. com driver).
[91/01/28 15:29:45 rvb]
[ ./kernel/i386at/kdasm.s ]
Follow dbg's lead.
[91/01/15 rvb]
r.
[91/01/04 15:35:30 af]
[ ./kernel/mips/PMAX/pm_hdw.c ]
In interrupt routine, drop priority as now required.
[91/02/12 12:42:39 af]
[ ./kernel/mips/PMAX/rz_disk.c ]
A./Makeconf 644 146 0 0 4466106640 5577 ./Makefile 444 146 0 2137 4711632630 5660 #
# Mach Operating System
# Copyright (c) 1989 Carnegie-Mellon University
# All rights reserved. The CMU software License Agreement specifies
# the terms and conditions for use and redistribution.
#
# HISTORY
# $Log: Makefile,v $
# Revision 2.8 90/10/25 14:41:25 rwd
# Don't make clean include area.
# [90/10/24 rwd]
#
# Revision 2.7 90/09/09 14:30:48 rpd
# Added install : all
# [90/08/20 rwd]
#
# Revision 2.6 90/06/02 14:44:48 rpd
# Release mig before building the include directory.
# [90/03/26 21:21:20 rpd]
#
# Revision 2.5 89/12/08 19:51:53 rwd
# Fix thread make
# [89/11/30 rwd]
#
# Revision 2.4 89/10/16 15:21:47 rwd
# Change include file make
# [89/10/05 rwd]
#
# Revision 2.3 89/08/09 14:32:59 rwd
# Make clean libmach
# [89/08/07 rwd]
#
# Revision 2.2 89/08/05 16:20:46 rwd
# First version
# [89/08/05 16:18:56 rwd]
#
#
install: all
all:
cd kernel;$(MAKE)
cd kernel/src/mig;$(MAKE) release
cd include;$(MAKE)
cd user/libmach;$(MAKE) clean;$(MAKE)
cd user/threads;$(MAKE)
cd user;$(MAKE) install
w required.
[91/02/12 13:18:18 af]
[ ./kernel/mips/db_trace.c ]
Split trace function from ddb interface. Added (optional)
code to walk through a user-mode, optimized CThread program
like the U*x server. Should make it MI someday.
[91/02/12 12:18:59 af]
[ ./kernel/mips/locore.s ]
Reversed the meaning of the booleans in the ref_bits array.
[91/02/12 12:24:39 af]
[ ./kernel/mips/trap.c ]
Pass along the spl le./kernel/ 755 146 0 0 4754041062 5412 ./kernel/boot_ufs/ 755 146 0 0 4754020333 7230 ./kernel/boot_ufs/boot_printf.c 444 146 0 10274 4754020313 12026 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: boot_printf.c,v $
* Revision 2.6 91/02/05 17:00:25 mrt
* Changed to new copyright
* [91/01/28 14:54:14 mrt]
*
* Revision 2.5 90/10/25 14:41:34 rwd
* Modified boot_gets to allocate arrays from heap, not stack.
* [90/10/23 rpd]
*
* Revision 2.4 90/08/27 21:44:20 dbg
* Pass extra argument to _doprnt.
* [90/08/21 dbg]
*
* Revision 2.3 90/06/02 14:45:13 rpd
* Converted to new IPC and new host port mechanism.
* [90/03/26 21:28:27 rpd]
*
* Revision 2.2 90/01/11 11:40:53 dbg
* Created.
* [89/12/20 dbg]
*
*/
/*
* Printf from bootstrap task - use device interface.
*/
#include
#include
#include
#include
#include
#include
#include
mach_port_t console_port;
extern mach_port_t bootstrap_master_device_port;
void
boot_printf_init()
{
(void) device_open(bootstrap_master_device_port,
0,
"console",
&console_port);
}
#define BOOT_PRINTF_BUFMAX 128
char boot_printf_buf[BOOT_PRINTF_BUFMAX + 1]; /* extra for '\r\n' */
unsigned int boot_printf_index = 0;
boot_putchar(c)
int c;
{
boot_printf_buf[boot_printf_index] = c;
boot_printf_index++;
if (c == '\n') {
boot_printf_buf[boot_printf_index] = '\r';
boot_printf_index++;
}
if (boot_printf_index >= BOOT_PRINTF_BUFMAX) {
int amt;
(void) device_write_inband(console_port, 0, 0,
boot_printf_buf, boot_printf_index, &amt);
boot_printf_index = 0;
}
}
/*VARARGS1*/
boot_printf(fmt, va_alist)
char * fmt;
va_dcl
{
va_list listp;
va_start(listp);
_doprnt(fmt, &listp, boot_putchar, 0);
va_end(listp);
if (boot_printf_index != 0) {
int amt;
(void) device_write_inband(console_port, 0, 0,
boot_printf_buf, boot_printf_index, &amt);
boot_printf_index = 0;
}
}
boot_gets(str, maxlen)
char *str;
int maxlen;
{
register char *lp;
register int c;
char *inbuf;
unsigned int count;
register char *ip;
char *strmax = str + maxlen - 1; /* allow space for trailing 0 */
inbuf = (char *) kalloc(128);
lp = str;
for (;;) {
(void) device_read_inband(console_port, 0, 0,
128, inbuf, &count);
for (ip = inbuf; ip < &inbuf[count]; ip++) {
c = *ip;
switch (c) {
case '\n':
case '\r':
boot_printf("\n");
*lp++ = 0;
kfree((vm_offset_t)inbuf, 128);
return;
case '\b':
case '#':
case '\177':
if (lp > str) {
boot_printf("\b \b");
lp--;
}
continue;
case '@':
case 'u'&037:
lp = str;
boot_printf("\n\r");
continue;
default:
if (c >= ' ' && c < '\177') {
if (lp < strmax) {
*lp++ = c;
boot_printf("%c", c);
}
else {
boot_printf("%c", '\007'); /* beep */
}
}
}
}
}
}
/*VARARGS1*/
boot_panic(s, va_alist)
char *s;
va_dcl
{
va_list listp;
boot_printf("panic: ");
va_start(listp);
_doprnt(s, &listp, boot_putchar, 0);
va_end(listp);
boot_printf("\n");
/*
* XXX - use internal form of host_reboot,
* since I am not exporting a 'host_internal'
* file yet.
*/
(void) host_reboot(realhost.host_priv_self, RB_DEBUGGER);
}
nsfer. Now new fsck works.
[90/12/10 17:26:47 af]
[ ./kernel/mips/PMAX/scsi_53C94_hdw.c ]
In interrupt routine, drop priority as now required.
Also, sanity check for spurious interrupts.
Some more debugging tools.
[91/02/12 12:46:38 af]
[ ./kernel/mips/autoconf.c ]
New values for new delay() function.
[91/02/12 12:29./kernel/boot_ufs/boot_printf.h 444 146 0 2622 4754020314 12012 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: boot_printf.h,v $
* Revision 2.3 91/02/05 17:00:29 mrt
* Changed to new copyright
* [91/01/28 14:54:25 mrt]
*
* Revision 2.2 90/01/11 11:40:58 dbg
* Created.
* [89/12/20 dbg]
*
*/
/*
* Redefine print routines for bootstrap task to use the boot_ print
* routines.
*/
#define printf boot_printf
#define gets boot_gets
#define panic boot_panic
t_t bootstrap_master_device_port;
void
boot_printf_init()
{
(void) device_open(bootstrap_master_device_port,./kernel/boot_ufs/def_pager_setup.c 444 146 0 16035 4754020316 12641 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: def_pager_setup.c,v $
* Revision 2.7 91/02/05 17:00:34 mrt
* Changed to new copyright
* [91/01/28 14:54:27 mrt]
*
* Revision 2.6 90/12/20 16:35:09 jeffreyh
* Added init for default_partition_lock
* [90/12/11 jeffreyh]
*
* Revision 2.5 90/08/27 21:44:42 dbg
* Use 'new' file_io package.
* [90/07/18 dbg]
*
* Revision 2.4 90/06/02 14:45:17 rpd
* Converted to new IPC.
* [90/03/26 21:28:45 rpd]
*
* Revision 2.3 90/01/11 11:41:03 dbg
* Use bootstrap_task print routines.
* [89/12/20 dbg]
*
* Revision 2.2 89/09/08 11:22:01 dbg
* Created.
* [89/09/01 17:12:55 dbg]
*
* 31-Aug-89 David Golub (dbg) at Carnegie-Mellon University
* Use new open_file routine.
*
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*
* Set up default pager
*/
char paging_file_name[128] = "\0";
extern void create_default_partition();
decl_simple_lock_data(extern ,default_partition_lock);
void
default_pager_setup(master_device_port, rootname)
mach_port_t master_device_port;
char *rootname;
{
register struct file *fp;
register int result;
int (*p_read)(), (*p_write)();
extern int page_read_file(), page_write_file();
vm_size_t size;
extern char * strbuild();
simple_lock_init(&default_partition_lock);
fp = (struct file *)kalloc(sizeof(struct file));
bzero((char *)fp, sizeof(struct file));
(void) strbuild(paging_file_name,
"/dev/",
rootname,
"/mach_servers/paging_file",
(char *)0);
while (TRUE) {
result = open_file(master_device_port,
paging_file_name,
fp);
if (result == 0)
break;
printf("Can't open paging file %s: %d\n",
paging_file_name,
result);
bzero(paging_file_name, sizeof(paging_file_name));
printf("Paging file name ? ");
gets(paging_file_name, sizeof(paging_file_name));
if (paging_file_name[0] == 0) {
printf("*** WARNING: running without paging area!\n");
return;
}
}
printf("Paging file %s found\n", paging_file_name);
/*
* Wire the buffers, since they will be used by the default pager.
* Set wiring privileges first.
*/
current_task()->map->wiring_allowed = TRUE; /* XXX */
result = file_wire(fp);
if (result) {
panic("Can't wire down file buffers: %d", result);
}
size = fp->i_size;
p_read = page_read_file;
p_write = page_write_file;
/*
* Set up the default paging partition
*/
create_default_partition(size, p_read, p_write, (char *)fp);
/*
* Our caller will become the default pager - later
*/
}
#ifdef notyet
/* do this in separate task - synchronize with messages */
void
default_pager_create(master_host_port, master_device_port)
port_t master_host_port;
port_t master_device_port;
{
pager_task = kernel_task_create(task_self(), PAGING_TASK_MAP_SIZE);
(void) kernel_thread(pager_task, default_pager);
/*
* Wait for the request for the ports
*/
{
struct imsg {
msg_header_t hdr;
msg_type_t port_desc_1;
port_t port_1;
msg_type_t port_desc_2;
port_t port_2;
} imsg;
bzero((char *)&imsg, sizeof(imsg));
imsg.hdr.msg_size = sizeof(imsg_hdr);
(void) task_get_bootstrap_port(task_self, &bootstrap_port);
imsg.hdr.msg_local_port = bootstrap_port;
(void) msg_receive(&imsg.hdr, MSG_OPTION_NONE, 0);
/*
* Send back the host and device ports
*/
imsg.hdr.msg_simple = FALSE;
imsg.hdr.msg_size = sizeof(imsg);
imsg.hdr.msg_type = MSG_TYPE_NORMAL;
/* local port is our bootstrap port */
/* remote port is the reply port */
imsg.hdr.msg_id += 100; /* reply msg */
imsg.port_desc_1.msg_type_name = MSG_TYPE_PORT;
imsg.port_desc_1.msg_type_size = sizeof(port_t) * 8;
imsg.port_desc_1.msg_type_number = 1;
imsg.port_desc_1.msg_type_inline = TRUE;
imsg.port_desc_1.msg_type_longform = FALSE;
imsg.port_desc_1.msg_type_deallocate = FALSE;
imsg.port_1 = master_host_port;
imsg.port_desc_2 = imsg.port_desc_1;
imsg.port_2 = master_device_port;
result = msg_send(&imsg.hdr, MSG_OPTION_NONE, 0);
if (result)
panic("msg_send %d", result);
/*
* Wait for the reply message after startup
*/
bzero((char *)&imsg, sizeof(imsg));
imsg.hdr.msg_size = sizeof(imsg_hdr);
(void) task_get_bootstrap_port(task_self, &bootstrap_port);
imsg.hdr.msg_local_port = bootstrap_port;
(void) msg_receive(&imsg.hdr, MSG_OPTION_NONE, 0);
}
/*
* Done
*/
}
void
device_pager()
{
(void) task_get_bootstrap_port(task_self(), &bootstrap_port);
(void) port_allocate(task_self(), &reply_port);
/*
* Get the host and device ports
*/
{
struct imsg {
msg_header_t hdr;
msg_type_t port_desc_1;
port_t port_1;
msg_type_t port_desc_2;
port_t port_2;
} imsg;
imsg.hdr.msg_simple = TRUE;
imsg.hdr.msg_size = sizeof(imsg.hdr);
imsg.hdr.msg_type = MSG_TYPE_NORMAL;
imsg.hdr.msg_local_port = reply_port;
imsg.hdr.msg_remote_port = bootstrap_port;
imsg.hdr.msg_id = 9999;
result = msg_send(&imsg.hdr, MSG_OPTION_NONE, 0);
if (result)
panic("msg_send: %d", result);
bzero((char *)&imsg, sizeof(imsg));
imsg.hdr.msg_size = sizeof(imsg);
imsg.hdr.msg_local_port = reply_port;
result = msg_receive(&imsg.hdr, MSG_OPTION_NONE, 0);
if (result)
panic("msg_receive: %d", result);
host_port = imsg.port_1;
device_port = imsg.port_2;
}
...
/*
* Send back synchronization message to resume
* the bootstrap
*/
{
msg_header_t imsg;
imsg.msg_simple = TRUE;
imsg.msg_size = sizeof(imsg.hdr);
imsg.msg_type = MSG_TYPE_NORMAL;
imsg.msg_local_port = reply_port;
imsg.msg_remote_port = bootstrap_port;
imsg.msg_id = 99999;
result = msg_send(&imsg, MSG_OPTION_NONE, 0);
if (result)
panic("msg_send: %d", result);
}
device_pager_loop();
}
#endif notyet
_name, sizeof(paging_file_name));
if (paging_file_name[0] == 0) {
printf("*** WARNING: running without paging area!\n");
return;
}
}
printf("Paging file %s found\n", paging_file_name);
/*
* Wire the buffers, since they will be used by the default pager.
* Set wiring privileges first.
*/
current_task()->map->wiring_allowed = TRUE; /* XXX */
result = file_wire(fp);
if (result) {
panic("Can't wire down file buffers: %d", result);
}
size = fp->i_./kernel/boot_ufs/default_pager.c 444 146 0 107431 4754020320 12323 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: default_pager.c,v $
* Revision 2.11 91/02/05 17:00:49 mrt
* Changed to new copyright
* [91/01/28 14:54:31 mrt]
*
* Revision 2.10 90/09/09 14:31:01 rpd
* Use decl_simple_lock_data.
* [90/08/30 rpd]
*
* Revision 2.9 90/08/27 21:44:51 dbg
* Add definitions of NBBY, howmany.
* [90/07/16 dbg]
*
* Revision 2.8 90/06/02 14:45:22 rpd
* Changed default_pager_object_create so the out argument
* is a poly send right.
* [90/05/03 rpd]
* Removed references to keep_wired_memory.
* [90/04/29 rpd]
* Converted to new IPC.
* Removed data-request queue.
* [90/03/26 21:30:57 rpd]
*
* Revision 2.7 90/03/14 21:09:58 rwd
* Call default_pager_object_server and add
* default_pager_object_create
* [90/01/22 rwd]
*
* Revision 2.6 90/01/11 11:41:08 dbg
* Use bootstrap-task print routines.
* [89/12/20 dbg]
*
* De-lint.
* [89/12/06 dbg]
*
* Revision 2.5 89/12/08 19:52:03 rwd
* Turn off CHECKSUM
* [89/12/06 rwd]
*
* Revision 2.4 89/10/23 12:01:54 dbg
* Change pager_read_offset and pager_write_offset to return block
* number as function result. default_read()'s caller must now
* deallocate data if not the same as the data buffer passed in.
* Add register declarations and clean up loops a bit.
* [89/10/19 dbg]
*
* Oops - nothing like having your debugging code introduce bugs...
* [89/10/17 dbg]
*
* Revision 2.3 89/10/16 15:21:59 rwd
* debugging: checksum pages in each object.
* [89/10/04 dbg]
*
* Revision 2.2 89/09/08 11:22:06 dbg
* Wait for default_partition to be set.
* [89/09/01 dbg]
*
* Modified to call outside routines for read and write.
* Removed disk structure. Added part_create.
* Reorganized code.
* [89/07/11 dbg]
*
*/
/*
* Default pager. Pages to paging partition.
*
* MUST BE ABLE TO ALLOCATE WIRED-DOWN MEMORY!!!
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*#define CHECKSUM 1*/
boolean_t default_pager_debug = FALSE;
/*
*/
/*
* 'Partition' structure for each paging area.
* Controls allocation of blocks within paging area.
*/
struct part {
vm_size_t total_size; /* total number of blocks */
vm_size_t free; /* number of blocks free */
unsigned char *bitmap; /* allocation map */
int (*p_read)(); /* Read block from partition */
int (*p_write)(); /* Write block to partition */
char *p_private; /* Pointer to private data for
read/write routines. */
};
typedef struct part *partition_t;
/*
* Bitmap allocation.
*/
#define NBBY 8
#define BYTEMASK 0xff
#define howmany(a,b) (((a) + (b) - 1)/(b))
/*
* Value to indicate no block assigned
*/
#define NO_BLOCK ((vm_offset_t)-1)
/*
* Create a partition descriptor.
* size is in BYTES.
*/
partition_t
part_create(size, p_read, p_write, p_private)
vm_offset_t size; /* size in pages */
int (*p_read)(); /* read routine */
int (*p_write)(); /* write routine */
char * p_private; /* structure used by read/write */
{
register partition_t part;
size = atop(size);
part = (partition_t) kalloc(sizeof(struct part));
part->total_size = size;
part->free = size;
part->bitmap = (unsigned char *)kalloc(howmany(size, NBBY));
part->p_read = p_read;
part->p_write = p_write;
part->p_private = p_private;
bzero((char *)part->bitmap, howmany(size, NBBY));
return (part);
}
/*
* Allocate a page in a paging file
*/
vm_offset_t
pager_alloc_page(part)
register partition_t part;
{
register int byte;
register int bit;
register int limit;
if (part->free == 0)
return (NO_BLOCK); /* out of paging space */
limit = howmany(part->total_size, NBBY);
for (byte = 0; byte < limit; byte++)
if (part->bitmap[byte] != BYTEMASK)
break;
if (byte == limit)
panic("pager_alloc_page: free != 0 but no free blocks");
for (bit = 0; bit < NBBY; bit++)
if ((part->bitmap[byte] & (1<
if (bit == NBBY)
panic("pager_alloc_page: no bits!");
part->bitmap[byte] |= (1<
printf("Default pager is full\n");
return (byte*NBBY+bit);
}
/*
* Deallocate a page in a paging file
*/
void
pager_dealloc_page(part, page)
register partition_t part;
register vm_offset_t page;
{
register int bit, byte;
if (page >= part->total_size)
panic("dealloc_page");
byte = page / NBBY;
bit = page % NBBY;
part->bitmap[byte] &= ~(1<
}
void
no_paging_space()
{
panic("*** PAGING SPACE EXHAUSTED\n");
}
/*
*/
/*
* Allocation info for each paging object.
*/
struct dpager {
partition_t partition; /* allocation area for pager */
vm_offset_t *map; /* block map */
vm_size_t size; /* size of paging object, in pages */
#ifdef CHECKSUM
vm_offset_t *checksum; /* checksum - parallel to block map */
#define NO_CHECKSUM ((vm_offset_t)-1)
#endif CHECKSUM
};
typedef struct dpager *dpager_t;
/*
* A paging object uses either a one- or a two-level map of offsets
* into the associated paging partition.
*/
#define PAGEMAP_ENTRIES 128
/* number of pages in a second-level map */
#define PAGEMAP_SIZE(npgs) ((npgs)*sizeof(vm_offset_t))
#define INDIRECT_PAGEMAP_ENTRIES(npgs) \
((((npgs)-1)/PAGEMAP_ENTRIES) + 1)
#define INDIRECT_PAGEMAP_SIZE(npgs) \
(INDIRECT_PAGEMAP_ENTRIES(npgs) * sizeof(vm_offset_t *))
#define INDIRECT_PAGEMAP(size) \
(size > PAGEMAP_ENTRIES)
/*
* Attach a new paging object to a paging partition
*/
void
pager_alloc(pager, part, size)
register dpager_t pager;
partition_t part;
register vm_size_t size;
{
register int i;
register vm_offset_t * mapptr;
pager->partition = part;
/*
* Convert byte size to number of pages,
* then increase to the nearest power of 2.
*/
size = atop(size);
i = 1;
while (i < size)
i <<= 1;
size = i;
if (INDIRECT_PAGEMAP(size)) {
mapptr = (vm_offset_t *)
kalloc(INDIRECT_PAGEMAP_SIZE(size));
for (i = INDIRECT_PAGEMAP_ENTRIES(size); --i >= 0; )
mapptr[i] = 0;
}
else {
mapptr = (vm_offset_t *)kalloc(PAGEMAP_SIZE(size));
for (i = 0; i < size; i++)
mapptr[i] = NO_BLOCK;
}
pager->map = mapptr;
pager->size = size;
#ifdef CHECKSUM
if (INDIRECT_PAGEMAP(size)) {
mapptr = (vm_offset_t *)
kalloc(INDIRECT_PAGEMAP_SIZE(size));
for (i = INDIRECT_PAGEMAP_ENTRIES(size); --i >= 0; )
mapptr[i] = 0;
}
else {
mapptr = (vm_offset_t *)kalloc(PAGEMAP_SIZE(size));
for (i = 0; i < size; i++)
mapptr[i] = NO_CHECKSUM;
}
pager->checksum = mapptr;
#endif CHECKSUM
}
/*
* Extend the map for a paging object.
*/
void
pager_extend(pager, new_size)
register dpager_t pager;
register vm_size_t new_size; /* in pages */
{
register vm_offset_t * new_mapptr;
register vm_offset_t * old_mapptr;
register int i;
register vm_size_t old_size;
/*
* Double current size until we cover new size.
*/
old_size = pager->size;
i = old_size;
while (i < new_size)
i <<= 1;
new_size = i;
if (INDIRECT_PAGEMAP(old_size)) {
/*
* Pager already uses two levels. Allocate
* a larger indirect block.
*/
new_mapptr = (vm_offset_t *)
kalloc(INDIRECT_PAGEMAP_SIZE(new_size));
old_mapptr = pager->map;
for (i = 0; i < INDIRECT_PAGEMAP_ENTRIES(old_size); i++)
new_mapptr[i] = old_mapptr[i];
for (; i < INDIRECT_PAGEMAP_ENTRIES(new_size); i++)
new_mapptr[i] = 0;
kfree((char *)old_mapptr, INDIRECT_PAGEMAP_SIZE(old_size));
pager->map = new_mapptr;
pager->size = new_size;
#ifdef CHECKSUM
new_mapptr = (vm_offset_t *)
kalloc(INDIRECT_PAGEMAP_SIZE(new_size));
old_mapptr = pager->checksum;
for (i = 0; i < INDIRECT_PAGEMAP_ENTRIES(old_size); i++)
new_mapptr[i] = old_mapptr[i];
for (; i < INDIRECT_PAGEMAP_ENTRIES(new_size); i++)
new_mapptr[i] = 0;
kfree((char *)old_mapptr, INDIRECT_PAGEMAP_SIZE(old_size));
pager->checksum = new_mapptr;
#endif CHECKSUM
return;
}
if (INDIRECT_PAGEMAP(new_size)) {
/*
* Changing from direct map to indirect map.
* Allocate both indirect and direct map blocks,
* since second-level (direct) block must be
* full size (PAGEMAP_SIZE(PAGEMAP_ENTRIES)).
*/
/*
* Allocate new second-level map first.
*/
new_mapptr = (vm_offset_t *)kalloc(PAGEMAP_SIZE(PAGEMAP_ENTRIES));
old_mapptr = pager->map;
for (i = 0; i < old_size; i++)
new_mapptr[i] = old_mapptr[i];
for (; i < PAGEMAP_ENTRIES; i++)
new_mapptr[i] = NO_BLOCK;
kfree((char *)old_mapptr, PAGEMAP_SIZE(old_size));
old_mapptr = new_mapptr;
/*
* Now allocate indirect map.
*/
new_mapptr = (vm_offset_t *)
kalloc(INDIRECT_PAGEMAP_SIZE(new_size));
new_mapptr[0] = (vm_offset_t) old_mapptr;
for (i = 1; i < INDIRECT_PAGEMAP_ENTRIES(new_size); i++)
new_mapptr[i] = 0;
pager->map = new_mapptr;
pager->size = new_size;
#ifdef CHECKSUM
/*
* Allocate new second-level map first.
*/
new_mapptr = (vm_offset_t *)kalloc(PAGEMAP_SIZE(PAGEMAP_ENTRIES));
old_mapptr = pager->checksum;
for (i = 0; i < old_size; i++)
new_mapptr[i] = old_mapptr[i];
for (; i < PAGEMAP_ENTRIES; i++)
new_mapptr[i] = NO_CHECKSUM;
kfree((char *)old_mapptr, PAGEMAP_SIZE(old_size));
old_mapptr = new_mapptr;
/*
* Now allocate indirect map.
*/
new_mapptr = (vm_offset_t *)
kalloc(INDIRECT_PAGEMAP_SIZE(new_size));
new_mapptr[0] = (vm_offset_t) old_mapptr;
for (i = 1; i < INDIRECT_PAGEMAP_ENTRIES(new_size); i++)
new_mapptr[i] = 0;
pager->checksum = new_mapptr;
#endif CHECKSUM
return;
}
/*
* Enlarging a direct block.
*/
new_mapptr = (vm_offset_t *)
kalloc(PAGEMAP_SIZE(new_size));
old_mapptr = pager->map;
for (i = 0; i < old_size; i++)
new_mapptr[i] = old_mapptr[i];
for (; i < new_size; i++)
new_mapptr[i] = NO_BLOCK;
kfree((char *)old_mapptr, PAGEMAP_SIZE(old_size));
pager->map = new_mapptr;
pager->size = new_size;
#ifdef CHECKSUM
new_mapptr = (vm_offset_t *)
kalloc(PAGEMAP_SIZE(new_size));
old_mapptr = pager->checksum;
for (i = 0; i < old_size; i++)
new_mapptr[i] = old_mapptr[i];
for (; i < new_size; i++)
new_mapptr[i] = NO_CHECKSUM;
kfree((char *)old_mapptr, PAGEMAP_SIZE(old_size));
pager->checksum = new_mapptr;
#endif CHECKSUM
}
/*
* Given an offset within a paging object, find the
* corresponding block within the paging partition.
* Return NO_BLOCK if none allocated.
*/
vm_offset_t
pager_read_offset(pager, offset)
register dpager_t pager;
vm_offset_t offset;
{
register vm_offset_t f_page;
f_page = atop(offset);
if (f_page >= pager->size) {
printf("*** PAGER WARNING: offset 0x%x out of range [0..0x%x)\n",
f_page, pager->size);
return (NO_BLOCK);
}
if (INDIRECT_PAGEMAP(pager->size)) {
register vm_offset_t *mapptr;
mapptr = (vm_offset_t *)pager->map[f_page/PAGEMAP_ENTRIES];
if (mapptr == 0)
return (NO_BLOCK);
return (mapptr[f_page%PAGEMAP_ENTRIES]);
}
else {
return (pager->map[f_page]);
}
}
#ifdef CHECKSUM
/*
* Return the checksum for a block.
*/
int
pager_get_checksum(pager, offset)
register dpager_t pager;
vm_offset_t offset;
{
register vm_offset_t f_page;
f_page = atop(offset);
if (f_page >= pager->size) {
printf("*** PAGER WARNING: offset 0x%x out of range [0..0x%x)\n",
f_page, pager->size);
return (NO_CHECKSUM);
}
if (INDIRECT_PAGEMAP(pager->size)) {
register vm_offset_t *mapptr;
mapptr = (vm_offset_t *)pager->checksum[f_page/PAGEMAP_ENTRIES];
if (mapptr == 0)
return (NO_CHECKSUM);
return (mapptr[f_page%PAGEMAP_ENTRIES]);
}
else {
return (pager->checksum[f_page]);
}
}
/*
* Remember the checksum for a block.
*/
int
pager_put_checksum(pager, offset, checksum)
register dpager_t pager;
vm_offset_t offset;
int checksum;
{
register vm_offset_t f_page;
f_page = atop(offset);
if (f_page >= pager->size) {
printf("*** PAGER WARNING: offset 0x%x out of range [0..0x%x)\n",
f_page, pager->size);
panic("pager_put_checksum");
}
if (INDIRECT_PAGEMAP(pager->size)) {
register vm_offset_t *mapptr;
mapptr = (vm_offset_t *)pager->checksum[f_page/PAGEMAP_ENTRIES];
if (mapptr == 0)
panic("pager_put_checksum");
mapptr[f_page%PAGEMAP_ENTRIES] = checksum;
}
else {
pager->checksum[f_page] = checksum;
}
}
/*
* Compute a checksum - XOR each 32-bit word.
*/
int
compute_checksum(addr, size)
vm_offset_t addr;
vm_size_t size;
{
register int checksum = NO_CHECKSUM;
register int *ptr;
register int count;
ptr = (int *)addr;
count = size / sizeof(int);
while (--count >= 0)
checksum ^= *ptr++;
return (checksum);
}
#endif CHECKSUM
/*
* Given an offset within a paging object, find the
* corresponding block within the paging partition.
* Allocate a new block if necessary.
*
* WARNING: paging objects apparently may be extended
* without notice!
*/
vm_offset_t
pager_write_offset(pager, offset)
register dpager_t pager;
vm_offset_t offset;
{
register vm_offset_t block, f_page;
register vm_offset_t *mapptr;
f_page = atop(offset);
if (f_page >= pager->size) {
/*
* Paging object must be extended.
* Remember that offset is 0-based, but size is 1-based.
*/
pager_extend(pager, f_page + 1);
}
if (INDIRECT_PAGEMAP(pager->size)) {
mapptr = (vm_offset_t *)pager->map[f_page/PAGEMAP_ENTRIES];
if (mapptr == 0) {
/*
* Allocate the indirect block
*/
register int i;
mapptr = (vm_offset_t *)kalloc(PAGEMAP_SIZE(PAGEMAP_ENTRIES));
if (mapptr == 0) {
/* out of space! */
printf("*** PAGER ERROR: out of memory\n");
no_paging_space();
return (NO_BLOCK);
}
pager->map[f_page/PAGEMAP_ENTRIES] = (vm_offset_t)mapptr;
for (i = 0; i < PAGEMAP_ENTRIES; i++)
mapptr[i] = NO_BLOCK;
#ifdef CHECKSUM
{
register vm_offset_t *cksumptr;
register int j;
cksumptr = (vm_offset_t *)
kalloc(PAGEMAP_SIZE(PAGEMAP_ENTRIES));
if (cksumptr == 0) {
/* out of space! */
printf("*** PAGER ERROR: out of memory\n");
no_paging_space();
return (FALSE);
}
pager->checksum[f_page/PAGEMAP_ENTRIES]
= (vm_offset_t)cksumptr;
for (j = 0; j < PAGEMAP_ENTRIES; j++)
cksumptr[j] = NO_CHECKSUM;
}
#endif CHECKSUM
}
f_page %= PAGEMAP_ENTRIES;
}
else {
mapptr = pager->map;
}
block = mapptr[f_page];
if (block == NO_BLOCK) {
block = pager_alloc_page(pager->partition);
if (block == NO_BLOCK) {
no_paging_space();
return (NO_BLOCK); /* out of space */
}
mapptr[f_page] = block;
}
return (block);
}
/*
* Deallocate all of the blocks belonging to a paging object.
*/
void
pager_dealloc(pager)
register dpager_t pager;
{
register int i, j;
register vm_offset_t block;
register vm_offset_t *mapptr;
if (INDIRECT_PAGEMAP(pager->size)) {
for (i = INDIRECT_PAGEMAP_ENTRIES(pager->size); --i >= 0; ) {
mapptr = (vm_offset_t *)pager->map[i];
if (mapptr) {
for (j = 0; j < PAGEMAP_ENTRIES; j++) {
block = mapptr[j];
if (block != NO_BLOCK)
pager_dealloc_page(pager->partition, block);
}
kfree((char *)mapptr, PAGEMAP_SIZE(PAGEMAP_ENTRIES));
}
}
kfree((char *)pager->map, INDIRECT_PAGEMAP_SIZE(pager->size));
#ifdef CHECKSUM
for (i = INDIRECT_PAGEMAP_ENTRIES(pager->size); --i >= 0; ) {
mapptr = (vm_offset_t *)pager->checksum[i];
if (mapptr) {
kfree((char *)mapptr, PAGEMAP_SIZE(PAGEMAP_ENTRIES));
}
}
kfree((char *)pager->checksum,
INDIRECT_PAGEMAP_SIZE(pager->size));
#endif CHECKSUM
}
else {
mapptr = pager->map;
for (i = 0; i < pager->size; i++ ) {
block = mapptr[i];
if (block != NO_BLOCK)
pager_dealloc_page(pager->partition, block);
}
kfree((char *)pager->map, PAGEMAP_SIZE(pager->size));
#ifdef CHECKSUM
kfree((char *)pager->checksum, PAGEMAP_SIZE(pager->size));
#endif CHECKSUM
}
}
/*
*/
/*
* Read/write routines.
*/
#define PAGER_SUCCESS 0
#define PAGER_ABSENT 1
#define PAGER_ERROR 2
/*
* Read data from a default pager. Addr is the address of a buffer
* to fill. Out_addr returns the buffer that contains the data;
* if it is different from
*/
int
default_read(ds, addr, size, offset, out_addr)
register dpager_t ds;
vm_offset_t addr; /* pointer to block to fill */
register vm_size_t size;
register vm_offset_t offset;
vm_offset_t *out_addr;
/* returns pointer to data */
{
register vm_offset_t block;
vm_offset_t raddr;
vm_size_t rsize;
register int rc;
boolean_t first_time;
register partition_t part = ds->partition;
#ifdef CHECKSUM
vm_size_t original_size = size;
vm_offset_t original_offset = offset;
#endif CHECKSUM
/*
* Find the block in the paging partition
*/
block = pager_read_offset(ds, offset);
if (block == NO_BLOCK)
return (PAGER_ABSENT);
/*
* Read it, trying for the entire page.
*/
offset = ptoa(block);
first_time = TRUE;
*out_addr = addr;
do {
rc = (*part->p_read)(
part->p_private,
offset,
size,
&raddr,
&rsize);
if (rc != 0)
return (PAGER_ERROR);
/*
* If we got the entire page on the first read, return it.
*/
if (first_time && rsize == size) {
*out_addr = raddr;
break;
}
/*
* Otherwise, copy the data into the
* buffer we were passed, and try for
* the next piece.
*/
first_time = FALSE;
bcopy((char *)raddr, (char *)addr, rsize);
addr += rsize;
offset += rsize;
size -= rsize;
} while (size != 0);
#ifdef CHECKSUM
{
int write_checksum,
read_checksum;
write_checksum = pager_get_checksum(ds, original_offset);
read_checksum = compute_checksum(*out_addr, original_size);
if (write_checksum != read_checksum) {
panic(
"PAGER CHECKSUM ERROR: offset 0x%x, written 0x%x, read 0x%x",
original_offset, write_checksum, read_checksum);
}
if (default_pager_debug)
printf(" checksum 0x%x ok\n", read_checksum);
}
#endif CHECKSUM
return (PAGER_SUCCESS);
}
int
default_write(ds, addr, size, offset)
register dpager_t ds;
register vm_offset_t addr;
register vm_size_t size;
register vm_offset_t offset;
{
vm_offset_t block;
vm_size_t wsize;
register int rc;
/*
* Find block in paging partition
*/
block = pager_write_offset(ds, offset);
if (block == NO_BLOCK)
return (PAGER_ERROR);
#ifdef CHECKSUM
/*
* Save checksum
*/
{
int checksum;
checksum = compute_checksum(addr, size);
pager_put_checksum(ds, offset, checksum);
if (default_pager_debug)
printf(" saving checksum 0x%x\n", checksum);
}
#endif CHECKSUM
offset = ptoa(block);
do {
rc = (*ds->partition->p_write)(
ds->partition->p_private,
offset,
addr,
size,
&wsize);
if (rc != 0) {
printf("*** PAGER ERROR: default_write: ");
printf("ds=0x%x addr=0x%x size=0x%x offset=0x%x resid=0x%x\n",
ds, addr, size, offset, wsize);
return (PAGER_ERROR);
}
addr += wsize;
offset += wsize;
size -= wsize;
} while (size != 0);
return (PAGER_SUCCESS);
}
boolean_t
default_has_page(ds, offset)
dpager_t ds;
vm_offset_t offset;
{
return (pager_read_offset(ds, offset) != NO_BLOCK);
}
/*
*/
/*
* Mapping between pager port and paging object.
*/
struct dstruct {
queue_chain_t links; /* Link in pager-port hash list */
memory_object_t pager; /* Pager port */
mach_port_t pager_request; /* Known request port */
mach_port_t pager_name; /* Known name port */
int errors; /* Pageout error count */
struct dpager dpager; /* Actual pager */
};
typedef struct dstruct * default_pager_t;
#define DEFAULT_PAGER_NULL ((default_pager_t)0)
zone_t dstruct_zone;
#define PAGER_PORT_HASH_COUNT 127
queue_head_t pager_port_hashtable[PAGER_PORT_HASH_COUNT];
#define pager_port_hash(name_port) \
(((int)(name_port) & 0xffffff) % PAGER_PORT_HASH_COUNT)
void pager_port_hash_init()
{
register int i;
for (i = 0; i < PAGER_PORT_HASH_COUNT; i++)
queue_init(&pager_port_hashtable[i]);
}
void pager_port_hash_insert(name_port, ds)
mach_port_t name_port;
default_pager_t ds;
{
ds->pager = name_port;
queue_enter(&pager_port_hashtable[pager_port_hash(name_port)],
ds, default_pager_t, links);
}
default_pager_t pager_port_lookup(name_port)
register mach_port_t name_port;
{
register queue_t bucket;
register default_pager_t entry;
bucket = &pager_port_hashtable[pager_port_hash(name_port)];
for (entry = (default_pager_t)queue_first(bucket);
!queue_end(bucket, (queue_entry_t)entry);
entry = (default_pager_t)queue_next(&entry->links)) {
if (entry->pager == name_port)
return (entry);
}
return (DEFAULT_PAGER_NULL);
}
void pager_port_hash_delete(name_port)
register mach_port_t name_port;
{
register queue_t bucket;
register default_pager_t entry;
bucket = &pager_port_hashtable[pager_port_hash(name_port)];
for (entry = (default_pager_t)queue_first(bucket);
!queue_end(bucket, (queue_entry_t)entry);
entry = (default_pager_t)queue_next(&entry->links)) {
if (entry->pager == name_port) {
queue_remove(bucket, entry, default_pager_t, links);
return;
}
}
}
/*
* Default pager.
* Wired into kernel.
*/
partition_t default_partition = 0; /* Where to allocate new pagers */
decl_simple_lock_data(,
default_partition_lock);
/* lock to set it */
mach_port_t default_pager_self;
mach_port_t default_pager_enabled_set;
mach_port_t default_pager_default;
vm_offset_t default_pager_input_buffer;
/*
* Make all calls involving the kernel interface go through IPC.
*/
#include
#include
/*
* Rename all of the functions in the pager interface,
* to avoid confusing them with the kernel interface
*/
#define memory_object_init default_pager_init_pager
#define memory_object_terminate default_pager_terminate_object
#define memory_object_data_request default_pagein
#define memory_object_data_unlock default_pagein
#define memory_object_data_write default_data_write
#define memory_object_data_initialize default_data_initialize
#define memory_object_create default_pager_create_pager
#define memory_object_copy default_pager_copy
#define memory_object_lock_completed default_pager_lock_completed
int default_pager_pagein_count = 0;
int default_pager_pageout_count = 0;
kern_return_t memory_object_data_request(pager, reply_to, offset,
length, protection_required)
memory_object_t pager;
mach_port_t reply_to;
vm_offset_t offset;
vm_size_t length;
vm_prot_t protection_required;
{
default_pager_t ds;
vm_offset_t addr;
kern_return_t rc;
if (default_pager_debug)
printf("%s: pager=%d, offset=0x%x, length=0x%x\n",
"memory_object_data_request(default_pager)",
pager, offset, length);
if (length != PAGE_SIZE)
panic("default_pagein: bad length");
ds = pager_port_lookup(pager);
assert(ds != DEFAULT_PAGER_NULL);
if (ds->errors) {
printf("(default_pager)data_request: dropping request because of");
printf(" previous paging errors\n");
(void) memory_object_data_error(reply_to,
offset, PAGE_SIZE,
KERN_FAILURE);
return;
}
rc = default_read(&ds->dpager, default_pager_input_buffer,
PAGE_SIZE, offset,
&addr);
switch (rc) {
case PAGER_SUCCESS:
(void) memory_object_data_provided(
reply_to, offset,
addr, PAGE_SIZE,
VM_PROT_NONE);
if (addr != default_pager_input_buffer)
(void) vm_deallocate(default_pager_self, addr, PAGE_SIZE);
break;
case PAGER_ABSENT:
(void) memory_object_data_unavailable(
reply_to,
offset,
PAGE_SIZE);
break;
case PAGER_ERROR:
(void) memory_object_data_error(
reply_to,
offset,
PAGE_SIZE,
KERN_FAILURE);
break;
}
default_pager_pagein_count++;
return(KERN_SUCCESS);
}
/*
* memory_object_data_initialize: check whether we already have each page, and
* write it if we do not. The implementation is far from optimized, and
* also assumes that the default_pager is single-threaded.
*/
kern_return_t memory_object_data_initialize(pager, pager_request,
offset, addr, data_cnt)
memory_object_t pager;
mach_port_t pager_request;
register
vm_offset_t offset;
register
pointer_t addr;
vm_size_t data_cnt;
{
vm_offset_t amount_sent;
default_pager_t ds;
#ifdef lint
pager_request++;
#endif lint
if (default_pager_debug)
printf("%s: pager=%d, offset=0x%x, length=0x%x\n",
"memory_object_data_initialize(default_pager)",
pager, offset, data_cnt);
ds = pager_port_lookup(pager);
for (amount_sent = 0;
amount_sent < data_cnt;
amount_sent += PAGE_SIZE) {
if (!default_has_page(&ds->dpager, offset + amount_sent)) {
if (default_write(&ds->dpager,
addr + amount_sent,
PAGE_SIZE,
offset + amount_sent)
!= PAGER_SUCCESS) {
printf("initialize: write error\n");
ds->errors++;
}
}
}
if (vm_deallocate(default_pager_self, addr, data_cnt) != KERN_SUCCESS)
panic("default_initialize: deallocate failed");
return(KERN_SUCCESS);
}
/*
* memory_object_data_write: split up the stuff coming in from
* a memory_object_data_write call
* into individual pages and pass them off to default_write.
*/
kern_return_t memory_object_data_write(pager, pager_request,
offset, addr, data_cnt)
memory_object_t pager;
mach_port_t pager_request;
register
vm_offset_t offset;
register
pointer_t addr;
vm_size_t data_cnt;
{
register
vm_size_t amount_sent;
default_pager_t ds;
#ifdef lint
pager_request++;
#endif lint
if (default_pager_debug)
printf("%s: pager=%d, offset=0x%x, length=0x%x\n",
"pager_data_write(default_pager)",
pager, offset, data_cnt);
if ((data_cnt % PAGE_SIZE) != 0) {
printf("(default_pager)memory_object_data_write: not a multiple of a page");
data_cnt = round_page(data_cnt);
}
ds = pager_port_lookup(pager);
for (amount_sent = 0;
amount_sent < data_cnt;
amount_sent += PAGE_SIZE) {
register int result;
result = default_write(&ds->dpager,
addr + amount_sent,
PAGE_SIZE,
offset + amount_sent);
if (result != KERN_SUCCESS) {
printf("*** WRITE ERROR on default_pageout:");
printf(" pager=%d, offset=0x%x, length=0x%x, result=%d\n",
pager, offset+amount_sent, PAGE_SIZE, result);
ds->errors++;
}
default_pager_pageout_count++;
}
if (vm_deallocate(default_pager_self, addr, data_cnt) != KERN_SUCCESS)
panic("default_data_write: deallocate failed");
return(KERN_SUCCESS);
}
/*ARGSUSED*/
kern_return_t memory_object_copy(old_memory_object, old_memory_control,
offset, length, new_memory_object)
memory_object_t old_memory_object;
memory_object_control_t
old_memory_control;
vm_offset_t offset;
vm_size_t length;
memory_object_t new_memory_object;
{
panic("(default_pager)memory_object_copy: called");
return KERN_FAILURE;
}
/*
* Routine: memory_object_create
* Purpose:
* Handle requests for memory objects from the
* kernel.
* Notes:
* Because we only give out the default memory
* manager port to the kernel, we don't have to
* be so paranoid about the contents.
*/
kern_return_t memory_object_create(old_pager, new_pager, new_size,
new_pager_request, new_pager_name,
new_page_size)
mach_port_t old_pager;
mach_port_t new_pager;
vm_size_t new_size;
mach_port_t new_pager_request;
mach_port_t new_pager_name;
vm_size_t new_page_size;
{
register default_pager_t ds;
if (default_pager_debug)
printf("%s: new_pager=%d, new_request=%d, new_name=%d\n",
"memory_object_data_create(default_pager)",
new_pager, new_pager_request, new_pager_name);
if (old_pager != default_pager_default) {
printf("memory_object_create(default_pager): non-kernel caller!\n");
/*
* XXX Should throw away spurious port rights --
* use port_status to avoid giving away important ports
*/
return(KERN_FAILURE);
}
if (new_page_size != PAGE_SIZE) {
printf("memory_object_create(default_pager): wrong page size\n");
return(KERN_INVALID_ARGUMENT);
}
ds = (default_pager_t) zalloc(dstruct_zone);
if (ds == DEFAULT_PAGER_NULL) {
printf("memory_object_create(default_pager): unable to allocate");
printf(" a default pager structure [REBOOT SUGGESTED]\n");
return(KERN_RESOURCE_SHORTAGE);
}
pager_alloc(&ds->dpager, default_partition, new_size);
/*
* Set up associations between these ports
* and this default_pager structure
*/
ds->pager = new_pager;
ds->pager_request = new_pager_request;
ds->pager_name = new_pager_name;
pager_port_hash_insert(new_pager, ds);
if (mach_port_move_member(default_pager_self,
new_pager,
default_pager_enabled_set) != KERN_SUCCESS)
panic("memory_object_create: couldn't enable");
return(KERN_SUCCESS);
}
memory_object_copy_strategy_t default_copy_strategy = MEMORY_OBJECT_COPY_DELAY;
kern_return_t memory_object_init(pager, pager_request, pager_name,
pager_page_size)
mach_port_t pager;
mach_port_t pager_request;
mach_port_t pager_name;
vm_size_t pager_page_size;
{
register default_pager_t ds;
if (default_pager_debug)
printf("%s: pager=%d, request=%d, name=%d\n",
"memory_object_data_init(default_pager)",
pager, pager_request, pager_name);
if (pager_page_size != PAGE_SIZE) {
printf("memory_object_init: wrong page size");
return(KERN_FAILURE);
}
if ((ds = pager_port_lookup(pager)) == DEFAULT_PAGER_NULL) {
printf("memory_object_init: bogus pager");
return(KERN_FAILURE);
}
if (ds->pager_request != MACH_PORT_NULL &&
ds->pager_request != pager_request) {
printf("memory_object_init: multiple users");
return(KERN_FAILURE);
}
ds->pager_request = pager_request;
ds->pager_name = pager_name;
memory_object_set_attributes(pager_request,
TRUE,
FALSE, /* do not cache */
default_copy_strategy);
return(KERN_SUCCESS);
}
kern_return_t memory_object_terminate(pager, pager_request, pager_name)
mach_port_t pager;
mach_port_t pager_request;
mach_port_t pager_name;
{
default_pager_t ds = pager_port_lookup(pager);
if (default_pager_debug)
printf("%s: pager=%d, request=%d, name=%d\n",
"memory_object_terminate(default_pager)",
pager, pager_request, pager_name);
/*
* Throw away the port rights, regardless whether this
* request made any sense at all. In order for the
* message to be accepted, they must have been port_all_t's.
* Therefore, they can't be any of the ports we already owned.
*/
if (pager_name != MACH_PORT_NULL)
mach_port_destroy(default_pager_self, pager_name);
if (pager_request != MACH_PORT_NULL)
mach_port_destroy(default_pager_self, pager_request);
if (ds == DEFAULT_PAGER_NULL)
return (KERN_SUCCESS);
/*
* Remove the memory object port association, and then
* the destroy the port itself.
*/
pager_port_hash_delete(ds->pager);
(void) mach_port_destroy(default_pager_self, ds->pager);
pager_dealloc(&ds->dpager);
zfree(dstruct_zone, (vm_offset_t) ds);
return (KERN_SUCCESS);
}
kern_return_t memory_object_lock_completed(memory_object, pager_request_port,
offset, length)
memory_object_t memory_object;
mach_port_t pager_request_port;
vm_offset_t offset;
vm_size_t length;
{
#ifdef lint
memory_object++; pager_request_port++; offset++; length++;
#endif lint
printf("memory_object_lock_completed(inode_pager): called\n");
return(KERN_FAILURE);
}
/*
* Include the server loop
*/
#define SERVER_LOOP default_pager_server_loop
#define SERVER_NAME "default_pager"
#define SERVER_DISPATCH(in,out) \
(default_pager_server(in, out) || \
default_pager_default_server(in, out) || \
default_pager_object_server(in, out))
#include
#define memory_object_server default_pager_server
#include
#define memory_object_default_server default_pager_default_server
#include
#include
int dstruct_max = 1000; /* sb same as number of vm_objects */
void
default_pager(host_port)
mach_port_t host_port;
{
memory_object_t DMM;
register thread_t my_thread = current_thread();
kern_return_t kr;
default_pager_self = mach_task_self();
/*
* Set thread privileges.
*/
thread_swappable(my_thread, FALSE);
my_thread->vm_privilege = TRUE;
/*
* Initialize the name port hashing stuff.
*/
pager_port_hash_init();
dstruct_zone = zinit(sizeof(struct dstruct),
(vm_size_t) sizeof(struct dstruct) * dstruct_max,
PAGE_SIZE,
FALSE,
"default pager structures");
/*
* We are the default pager.
* Initialize the "default pager" port.
*/
kr = mach_port_allocate(default_pager_self, MACH_PORT_RIGHT_RECEIVE,
&default_pager_default);
if (kr != KERN_SUCCESS)
panic("default pager: can't allocate default port");
kr = mach_port_allocate(default_pager_self, MACH_PORT_RIGHT_PORT_SET,
&default_pager_enabled_set);
if (kr != KERN_SUCCESS)
panic("default_pager: can't create enabled port set");
kr = mach_port_move_member(default_pager_self,
default_pager_default,
default_pager_enabled_set);
if (kr != KERN_SUCCESS)
panic("default_pager: can't enable default port");
/*
* Wait for at least the default paging partition to be
* set up.
*/
simple_lock(&default_partition_lock);
while (default_partition == (partition_t)0) {
thread_sleep((int)&default_partition,
simple_lock_addr(default_partition_lock),
FALSE);
simple_lock(&default_partition_lock);
}
simple_unlock(&default_partition_lock);
DMM = default_pager_default;
kr = vm_set_default_memory_manager(host_port, &DMM);
if ((kr != KERN_SUCCESS) || (DMM != MACH_PORT_NULL))
panic("default_pager: can't set default memory manager");
/*
* Allocate the input buffer.
*/
default_pager_input_buffer = kmem_alloc(kernel_map, PAGE_SIZE);
if (default_pager_input_buffer == 0)
panic("default pager: can't allocate input buffer");
SERVER_LOOP(default_pager_enabled_set);
}
/*
* Set up the default paging partition.
*/
void
create_default_partition(size, p_read, p_write, p_private)
vm_size_t size;
int (*p_read)();
int (*p_write)();
char *p_private;
{
default_partition = part_create(size, p_read, p_write, p_private);
simple_lock(&default_partition_lock);
thread_wakeup((int)&default_partition);
simple_unlock(&default_partition_lock);
}
kern_return_t default_pager_object_create(pager, mem_obj, type, size)
mach_port_t pager;
mach_port_t *mem_obj;
mach_msg_type_name_t *type;
vm_size_t size;
{
mach_port_t port;
kern_return_t result;
result = mach_port_allocate(default_pager_self,
MACH_PORT_RIGHT_RECEIVE, &port);
if (result != KERN_SUCCESS) return (result);
result = memory_object_create(pager, port, size,
MACH_PORT_NULL, MACH_PORT_NULL,
PAGE_SIZE);
if (result != KERN_SUCCESS) return (result);
*mem_obj = port;
*type = MACH_MSG_TYPE_MAKE_SEND;
return (KERN_SUCCESS);
}
r);
(void) mach_port_destroy(default_pager_self, ds->pager);
pager_dealloc(&ds->dpager);
zfree(dstruct_zone, (vm_offset_t) ds);
return (KERN_SUCCESS);
}
kern_return_t memory_object_lock_completed(memory_object, pager_reques./kernel/boot_ufs/defs.h 444 146 0 4464 4754020322 10413 /*
* Mach Operating System
* Copyright (c) 1991,1990 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: defs.h,v $
* Revision 2.3 91/02/05 17:01:05 mrt
* Changed to new copyright
* [91/01/28 14:54:37 mrt]
*
* Revision 2.2 90/08/27 21:45:05 dbg
* Created.
* [90/07/16 dbg]
*
*/
/*
* Common definitions for Berkeley Fast File System.
*/
#include
#include
typedef unsigned short uid_t;
typedef unsigned short gid_t;
typedef unsigned long ino_t;
#define NBBY 8
/*
* The file system is made out of blocks of at most MAXBSIZE units,
* with smaller units (fragments) only in the last direct block.
* MAXBSIZE primarily determines the size of buffers in the buffer
* pool. It may be made larger without any effect on existing
* file systems; however, making it smaller may make some file
* systems unmountable.
*
* Note that the disk devices are assumed to have DEV_BSIZE "sectors"
* and that fragments must be some multiple of this size.
*/
#define MAXBSIZE 8192
#define MAXFRAG 8
/*
* MAXPATHLEN defines the longest permissible path length
* after expanding symbolic links.
*
* MAXSYMLINKS defines the maximum number of symbolic links
* that may be expanded in a path name. It should be set
* high enough to allow all legitimate uses, but halt infinite
* loops reasonably quickly.
*/
#define MAXPATHLEN 1024
#define MAXSYMLINKS 8
_LOOP(default_pager_enabled_set);
}
/*
* Set up the default paging partition.
*/
void
create_default_partition(size, p_read, p_write, p_private)
vm_size_t size;
int (*p_read)();
int (*p_write)();
./kernel/boot_ufs/dir.h 444 146 0 12423 4754020323 10263 /*
* Mach Operating System
* Copyright (c) 1991,1990 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: dir.h,v $
* Revision 2.4 91/02/05 17:01:09 mrt
* Changed to new copyright
* [91/01/28 14:54:43 mrt]
*
* Revision 2.3 90/08/27 21:45:12 dbg
* Taken from BSD 4.3 Reno release.
* [90/07/26 dbg]
*
*/
/*
* Copyright (c) 1982, 1986, 1989 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#)dir.h 7.6 (Berkeley) 5/9/89
*/
#ifndef _BOOT_UFS_DIR_H_
#define _BOOT_UFS_DIR_H_
/*
* A directory consists of some number of blocks of DIRBLKSIZ
* bytes, where DIRBLKSIZ is chosen such that it can be transferred
* to disk in a single atomic operation (e.g. 512 bytes on most machines).
*
* Each DIRBLKSIZ byte block contains some number of directory entry
* structures, which are of variable length. Each directory entry has
* a struct direct at the front of it, containing its inode number,
* the length of the entry, and the length of the name contained in
* the entry. These are followed by the name padded to a 4 byte boundary
* with null bytes. All names are guaranteed null terminated.
* The maximum length of a name in a directory is MAXNAMLEN.
*
* The macro DIRSIZ(dp) gives the amount of space required to represent
* a directory entry. Free space in a directory is represented by
* entries which have dp->d_reclen > DIRSIZ(dp). All DIRBLKSIZ bytes
* in a directory block are claimed by the directory entries. This
* usually results in the last entry in a directory having a large
* dp->d_reclen. When entries are deleted from a directory, the
* space is returned to the previous entry in the same directory
* block by increasing its dp->d_reclen. If the first entry of
* a directory block is free, then its dp->d_ino is set to 0.
* Entries other than the first in a directory do not normally have
* dp->d_ino set to 0.
*/
#define DIRBLKSIZ DEV_BSIZE
#define MAXNAMLEN 255
struct direct {
u_long d_ino; /* inode number of entry */
u_short d_reclen; /* length of this record */
u_short d_namlen; /* length of string in d_name */
char d_name[MAXNAMLEN + 1]; /* name with length <= MAXNAMLEN */
};
/*
* The DIRSIZ macro gives the minimum record length which will hold
* the directory entry. This requires the amount of space in struct direct
* without the d_name field, plus enough space for the name with a terminating
* null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
*/
#undef DIRSIZ
#define DIRSIZ(dp) \
((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
#ifdef KERNEL
/*
* Template for manipulating directories.
* Should use struct direct's, but the name field
* is MAXNAMLEN - 1, and this just won't do.
*/
struct dirtemplate {
u_long dot_ino;
short dot_reclen;
short dot_namlen;
char dot_name[4]; /* must be multiple of 4 */
u_long dotdot_ino;
short dotdot_reclen;
short dotdot_namlen;
char dotdot_name[4]; /* ditto */
};
#endif
/*
* The following information should be obtained from
* and is provided solely (and temporarily) for backward compatibility.
*/
#ifndef KERNEL
#define d_fileno d_ino /* compatibility with POSIX */
#ifndef DEV_BSIZE
#define DEV_BSIZE 512
#endif
/*
* Definitions for library routines operating on directories.
*/
typedef struct _dirdesc {
int dd_fd;
long dd_loc;
long dd_size;
char dd_buf[DIRBLKSIZ];
} DIR;
#define dirfd(dirp) ((dirp)->dd_fd)
#ifndef NULL
#define NULL 0
#endif
extern DIR *opendir();
extern struct direct *readdir();
extern long telldir();
extern void seekdir();
#define rewinddir(dirp) seekdir((dirp), (long)0)
extern void closedir();
#endif /* not KERNEL */
#endif /* _BOOT_UFS_DIR_H_ */
e
#include
int dstruct_max = 1000; /* sb same as number of vm_objects */
void
default_pager(host_port)
mach_port_t host_port;
{
memory_object_t DMM;
regist./kernel/boot_ufs/disk_inode.h 444 146 0 11747 4754020324 11626 /*
* Mach Operating System
* Copyright (c) 1991,1990 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: disk_inode.h,v $
* Revision 2.3 91/02/05 17:01:14 mrt
* Changed to new copyright
* [91/01/28 14:54:49 mrt]
*
* Revision 2.2 90/08/27 21:45:18 dbg
* Took new definition from BSD 4.3 Reno release.
* [90/07/16 dbg]
*
*/
/*
* Copyright (c) 1982, 1989 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#)inode.h 7.5 (Berkeley) 7/3/89
*/
#ifndef _BOOT_UFS_DISK_INODE_H_
#define _BOOT_UFS_DISK_INODE_H_
/*
* The I node is the focus of all file activity in the BSD Fast File System.
* There is a unique inode allocated for each active file,
* each current directory, each mounted-on file, text file, and the root.
* An inode is 'named' by its dev/inumber pair. (iget/iget.c)
* Data in icommon is read in from permanent inode on volume.
*/
#define NDADDR 12 /* direct addresses in inode */
#define NIADDR 3 /* indirect addresses in inode */
#define MAX_FASTLINK_SIZE ((NDADDR + NIADDR) * sizeof(daddr_t))
struct icommon {
u_short ic_mode; /* 0: mode and type of file */
short ic_nlink; /* 2: number of links to file */
uid_t ic_uid; /* 4: owner's user id */
gid_t ic_gid; /* 6: owner's group id */
quad ic_size; /* 8: number of bytes in file */
time_t ic_atime; /* 16: time last accessed */
long ic_atspare;
time_t ic_mtime; /* 24: time last modified */
long ic_mtspare;
time_t ic_ctime; /* 32: last time inode changed */
long ic_ctspare;
union {
struct {
daddr_t Mb_db[NDADDR]; /* 40: disk block addresses */
daddr_t Mb_ib[NIADDR]; /* 88: indirect blocks */
} ic_Mb;
char ic_Msymlink[MAX_FASTLINK_SIZE];
/* 40: symbolic link name */
} ic_Mun;
#define ic_db ic_Mun.ic_Mb.Mb_db
#define ic_ib ic_Mun.ic_Mb.Mb_ib
#define ic_symlink ic_Mun.ic_Msymlink
long ic_flags; /* 100: status, currently unused */
#define IC_FASTLINK 0x0001 /* Symbolic link in inode */
long ic_blocks; /* 104: blocks actually held */
long ic_gen; /* 108: generation number */
long ic_spare[4]; /* 112: reserved, currently unused */
} i_ic;
#define i_mode i_ic.ic_mode
#define i_nlink i_ic.ic_nlink
#define i_uid i_ic.ic_uid
#define i_gid i_ic.ic_gid
#if BYTE_MSF
#define i_size i_ic.ic_size.val[1]
#else /* BYTE_LSF */
#define i_size i_ic.ic_size.val[0]
#endif
#define i_db i_ic.ic_db
#define i_ib i_ic.ic_ib
#define i_atime i_ic.ic_atime
#define i_mtime i_ic.ic_mtime
#define i_ctime i_ic.ic_ctime
#define i_blocks i_ic.ic_blocks
#define i_rdev i_ic.ic_db[0]
#define i_symlink i_ic.ic_symlink
#define i_flags i_ic.ic_flags
#define i_gen i_ic.ic_gen
/* modes */
#define IFMT 0170000 /* type of file */
#define IFCHR 0020000 /* character special */
#define IFDIR 0040000 /* directory */
#define IFBLK 0060000 /* block special */
#define IFREG 0100000 /* regular */
#define IFLNK 0120000 /* symbolic link */
#define IFSOCK 0140000 /* socket */
#define ISUID 04000 /* set user id on execution */
#define ISGID 02000 /* set group id on execution */
#define ISVTX 01000 /* save swapped text even after use */
#define IREAD 0400 /* read, write, execute permissions */
#define IWRITE 0200
#define IEXEC 0100
/*
* Same structure, but on disk.
*/
struct dinode {
union {
struct icommon di_com;
char di_char[128];
} di_un;
};
#define di_ic di_un.di_com
#endif /* _BOOT_UFS_DISK_INODE_H_ */
these changes.
*/
/*
* ./kernel/boot_ufs/file_io.c 444 146 0 41670 4754020325 11116 /*
* Mach Operating System
* Copyright (c) 1991,1990 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: file_io.c,v $
* Revision 2.4 91/02/05 17:01:23 mrt
* Changed to new copyright
* [91/01/28 14:54:52 mrt]
*
* Revision 2.3 90/10/25 14:41:42 rwd
* Modified open_file to allocate arrays from heap, not stack.
* [90/10/23 rpd]
*
* Revision 2.2 90/08/27 21:45:27 dbg
* Reduce lint.
* [90/08/13 dbg]
*
* Created from include files, bsd4.3-Reno (public domain) source,
* and old code written at CMU.
* [90/07/17 dbg]
*
*/
/*
* Stand-alone file reading package.
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*
* Read a new inode into a file structure.
*/
int
read_inode(inumber, fp)
ino_t inumber;
register struct file *fp;
{
vm_offset_t buf;
vm_size_t buf_size;
register struct fs *fs;
daddr_t disk_block;
kern_return_t rc;
fs = fp->f_fs;
disk_block = itod(fs, inumber);
rc = device_read(fp->f_dev,
0,
(recnum_t) fsbtodb(fp->f_fs, disk_block),
(int) fs->fs_bsize,
(char **)&buf,
&buf_size);
if (rc != KERN_SUCCESS)
return (rc);
{
register struct dinode *dp;
dp = (struct dinode *)buf;
dp += itoo(fs, inumber);
fp->i_ic = dp->di_ic;
}
(void) vm_deallocate(mach_task_self(), buf, buf_size);
/*
* Clear out the old buffers
*/
{
register int level;
for (level = 0; level < NIADDR; level++) {
if (fp->f_blk[level] != 0) {
(void) vm_deallocate(mach_task_self(),
fp->f_blk[level],
fp->f_blksize[level]);
fp->f_blk[level] = 0;
}
fp->f_blkno[level] = -1;
}
if (fp->f_buf != 0) {
(void) vm_deallocate(mach_task_self(),
fp->f_buf,
fp->f_buf_size);
fp->f_buf = 0;
}
fp->f_buf_blkno = -1;
}
return (0);
}
/*
* Given an offset in a file, find the disk block number that
* contains that block.
*/
int
block_map(fp, file_block, disk_block_p)
struct file *fp;
daddr_t file_block;
daddr_t *disk_block_p; /* out */
{
int level;
int idx;
daddr_t ind_block_num;
kern_return_t rc;
daddr_t *ind_p;
/*
* Index structure of an inode:
*
* i_db[0..NDADDR-1] hold block numbers for blocks
* 0..NDADDR-1
*
* i_ib[0] index block 0 is the single indirect
* block
* holds block numbers for blocks
* NDADDR .. NDADDR + NINDIR(fs)-1
*
* i_ib[1] index block 1 is the double indirect
* block
* holds block numbers for INDEX blocks
* for blocks
* NDADDR + NINDIR(fs) ..
* NDADDR + NINDIR(fs) + NINDIR(fs)**2 - 1
*
* i_ib[2] index block 2 is the triple indirect
* block
* holds block numbers for double-indirect
* blocks for blocks
* NDADDR + NINDIR(fs) + NINDIR(fs)**2 ..
* NDADDR + NINDIR(fs) + NINDIR(fs)**2
* + NINDIR(fs)**3 - 1
*/
if (file_block < NDADDR) {
/* Direct block. */
*disk_block_p = fp->i_db[file_block];
return (0);
}
file_block -= NDADDR;
/*
* nindir[0] = NINDIR
* nindir[1] = NINDIR**2
* nindir[2] = NINDIR**3
* etc
*/
for (level = 0; level < NIADDR; level++) {
if (file_block < fp->f_nindir[level])
break;
file_block -= fp->f_nindir[level];
}
if (level == NIADDR) {
/* Block number too high */
return (FS_NOT_IN_FILE);
}
ind_block_num = fp->i_ib[level];
for (; level >= 0; level--) {
if (ind_block_num == 0) {
*disk_block_p = 0; /* missing */
return (0);
}
if (fp->f_blkno[level] != ind_block_num) {
if (fp->f_blk[level] != 0) {
(void) vm_deallocate(mach_task_self(),
fp->f_blk[level],
fp->f_blksize[level]);
}
rc = device_read(fp->f_dev,
0,
(recnum_t) fsbtodb(fp->f_fs, ind_block_num),
fp->f_fs->fs_bsize,
(char **)&fp->f_blk[level],
&fp->f_blksize[level]);
if (rc != KERN_SUCCESS)
return (rc);
fp->f_blkno[level] = ind_block_num;
}
ind_p = (daddr_t *)fp->f_blk[level];
if (level > 0) {
idx = file_block / fp->f_nindir[level-1];
file_block %= fp->f_nindir[level-1];
}
else
idx = file_block;
ind_block_num = ind_p[idx];
}
*disk_block_p = ind_block_num;
return (0);
}
/*
* Read a portion of a file into an internal buffer. Return
* the location in the buffer and the amount in the buffer.
*/
int
buf_read_file(fp, offset, buf_p, size_p)
register struct file *fp;
vm_offset_t offset;
vm_offset_t *buf_p; /* out */
vm_size_t *size_p; /* out */
{
register struct fs *fs;
vm_offset_t off;
register daddr_t file_block;
daddr_t disk_block;
int rc;
vm_offset_t block_size;
if (offset >= fp->i_size)
return (FS_NOT_IN_FILE);
fs = fp->f_fs;
off = blkoff(fs, offset);
file_block = lblkno(fs, offset);
block_size = blksize(fs, fp, file_block);
if (file_block != fp->f_buf_blkno) {
rc = block_map(fp, file_block, &disk_block);
if (rc != 0)
return (rc);
if (fp->f_buf)
(void)vm_deallocate(mach_task_self(),
fp->f_buf,
fp->f_buf_size);
if (disk_block == 0) {
(void)vm_allocate(mach_task_self(),
&fp->f_buf,
block_size,
TRUE);
fp->f_buf_size = block_size;
}
else {
rc = device_read(fp->f_dev,
0,
(recnum_t) fsbtodb(fs, disk_block),
(int) block_size,
(char **) &fp->f_buf,
&fp->f_buf_size);
}
if (rc)
return (rc);
fp->f_buf_blkno = file_block;
}
/*
* Return address of byte in buffer corresponding to
* offset, and size of remainder of buffer after that
* byte.
*/
*buf_p = fp->f_buf + off;
*size_p = block_size - off;
/*
* But truncate buffer at end of file.
*/
if (*size_p > fp->i_size - offset)
*size_p = fp->i_size - offset;
return (0);
}
/*
* Search a directory for a name and return its
* i_number.
*/
int
search_directory(name, fp, inumber_p)
char * name;
register struct file *fp;
ino_t *inumber_p; /* out */
{
vm_offset_t buf;
vm_size_t buf_size;
vm_offset_t offset;
register struct direct *dp;
int length;
kern_return_t rc;
length = strlen(name);
offset = 0;
while (offset < fp->i_size) {
rc = buf_read_file(fp, offset, &buf, &buf_size);
if (rc != KERN_SUCCESS)
return (rc);
dp = (struct direct *)buf;
if (dp->d_ino != 0) {
if (dp->d_namlen == length &&
!strcmp(name, dp->d_name))
{
/* found entry */
*inumber_p = dp->d_ino;
return (0);
}
}
offset += dp->d_reclen;
}
return (FS_NO_ENTRY);
}
int
mount_fs(fp)
register struct file *fp;
{
int error;
register struct fs *fs;
vm_offset_t buf;
vm_size_t buf_size;
error = device_read(fp->f_dev, 0, (recnum_t) SBLOCK, SBSIZE,
(char **) &buf, &buf_size);
if (error) {
return (error);
}
fs = (struct fs *)buf;
if (fs->fs_magic != FS_MAGIC ||
fs->fs_bsize > MAXBSIZE ||
fs->fs_bsize < sizeof(struct fs)) {
(void) vm_deallocate(mach_task_self(), buf, buf_size);
return (FS_INVALID_FS);
}
/* don't read cylinder groups - we aren't modifying anything */
fp->f_fs = fs;
/*
* Calculate indirect block levels.
*/
{
register int mult;
register int level;
mult = 1;
for (level = 0; level < NIADDR; level++) {
mult *= NINDIR(fs);
fp->f_nindir[level] = mult;
}
}
return (0);
}
/*
* Open a file.
*/
int
open_file(master_device_port, path, fp)
mach_port_t master_device_port;
char * path;
struct file *fp;
{
register char *cp, *ncp;
register int c; /* char */
register int rc;
ino_t inumber, parent_inumber;
int nlinks = 0;
char *namebuf = 0;
char *component = 0;
if (path == 0 || *path == '\0') {
rc = FS_NO_ENTRY;
goto exit;
}
/*
* Allocate buffers.
*/
namebuf = (char *) kalloc(MAXPATHLEN+1);
component = (char *) kalloc(MAXPATHLEN+1);
/*
* Copy name into buffer to allow modifying it.
*/
bcopy(path, namebuf, (unsigned)(strlen(path) + 1));
/*
* Look for '/dev/xxx' at start of path, for
* root device.
*/
if (!strprefix(namebuf, "/dev/")) {
printf("no device name\n");
rc = FS_NO_ENTRY;
goto exit;
}
cp = namebuf + 5; /* device */
ncp = component;
while ((c = *cp) != '\0' && c != '/') {
*ncp++ = c;
cp++;
}
*ncp = 0;
rc = device_open(master_device_port,
D_READ|D_WRITE,
component,
&fp->f_dev);
if (rc)
goto exit;
rc = mount_fs(fp);
if (rc)
goto exit;
inumber = (ino_t) ROOTINO;
if ((rc = read_inode(inumber, fp)) != 0) {
printf("can't read root inode\n");
goto exit;
}
while (*cp) {
/*
* Check that current node is a directory.
*/
if ((fp->i_mode & IFMT) != IFDIR) {
rc = FS_NOT_DIRECTORY;
goto exit;
}
/*
* Remove extra separators
*/
while (*cp == '/')
cp++;
/*
* Get next component of path name.
*/
{
register int len = 0;
ncp = component;
while ((c = *cp) != '\0' && c != '/') {
if (len++ > MAXNAMLEN) {
rc = FS_NAME_TOO_LONG;
goto exit;
}
if (c & 0200) {
rc = FS_INVALID_PARAMETER;
goto exit;
}
*ncp++ = c;
cp++;
}
*ncp = 0;
}
/*
* Look up component in current directory.
* Save directory inumber in case we find a
* symbolic link.
*/
parent_inumber = inumber;
rc = search_directory(component, fp, &inumber);
if (rc) {
printf("%s: not found\n", path);
goto exit;
}
/*
* Open next component.
*/
if ((rc = read_inode(inumber, fp)) != 0)
goto exit;
/*
* Check for symbolic link.
*/
if ((fp->i_mode & IFMT) == IFLNK) {
int link_len = fp->i_size;
int len;
len = strlen(cp) + 1;
if (link_len + len >= MAXPATHLEN - 1) {
rc = FS_NAME_TOO_LONG;
goto exit;
}
if (++nlinks > MAXSYMLINKS) {
rc = FS_SYMLINK_LOOP;
goto exit;
}
ovbcopy(cp, &namebuf[link_len], len);
#ifdef IC_FASTLINK
if ((fp->i_flags & IC_FASTLINK) != 0) {
bcopy(fp->i_symlink, namebuf, (unsigned) link_len);
}
else
#endif IC_FASTLINK
{
/*
* Read file for symbolic link
*/
vm_offset_t buf;
vm_size_t buf_size;
daddr_t disk_block;
register struct fs *fs = fp->f_fs;
(void) block_map(fp, (daddr_t)0, &disk_block);
rc = device_read(fp->f_dev,
0,
(recnum_t) fsbtodb(fs, disk_block),
(int) blksize(fs, fp, 0),
(char **) &buf,
&buf_size);
if (rc)
goto exit;
bcopy((char *)buf, namebuf, (unsigned)link_len);
(void) vm_deallocate(mach_task_self(), buf, buf_size);
}
/*
* If relative pathname, restart at parent directory.
* If absolute pathname, restart at root.
* If pathname begins '/dev/
* restart at root of that device.
*/
cp = namebuf;
if (*cp != '/') {
inumber = parent_inumber;
}
else if (!strprefix(cp, "/dev/")) {
inumber = (ino_t)ROOTINO;
}
else {
ncp = component;
cp += 5;
while ((c = *cp) != '\0' && c != '/') {
*ncp++ = c;
cp++;
}
*ncp = '\0';
rc = device_open(master_device_port,
D_READ,
component,
&fp->f_dev);
if (rc)
goto exit;
rc = mount_fs(fp);
if (rc)
goto exit;
inumber = (ino_t)ROOTINO;
}
if ((rc = read_inode(inumber, fp)) != 0)
goto exit;
}
}
/*
* Found terminal component.
*/
rc = 0;
exit:
if (namebuf) kfree((vm_offset_t)namebuf, MAXPATHLEN+1);
if (component) kfree((vm_offset_t)component, MAXPATHLEN+1);
return (rc);
}
/*
* Copy a portion of a file into kernel memory.
* Cross block boundaries when necessary.
*/
int
read_file(fp, offset, start, size, resid)
register struct file *fp;
vm_offset_t offset;
vm_offset_t start;
vm_size_t size;
vm_size_t *resid; /* out */
{
int rc;
register vm_size_t csize;
vm_offset_t buf;
vm_size_t buf_size;
while (size != 0) {
rc = buf_read_file(fp, offset, &buf, &buf_size);
if (rc)
return (rc);
csize = size;
if (csize > buf_size)
csize = buf_size;
if (csize == 0)
break;
bcopy((char *)buf, (char *)start, csize);
offset += csize;
start += csize;
size -= csize;
}
if (resid)
*resid = size;
return (0);
}
/*
* Special read and write routines for default pager.
* Assume that all offsets and sizes are multiples
* of DEV_BSIZE.
*/
/*
* Read all or part of a data block, and
* return a pointer to the appropriate part.
* Caller must deallocate the block when done.
*/
int
page_read_file(fp, offset, size, addr, size_read)
register struct file *fp;
vm_offset_t offset;
vm_size_t size;
vm_offset_t *addr; /* out */
vm_size_t *size_read; /* out */
{
register struct fs *fs;
vm_offset_t off;
register daddr_t file_block;
daddr_t disk_block;
register int rc;
vm_size_t block_size;
if (offset % DEV_BSIZE != 0 ||
size % DEV_BSIZE != 0)
panic("page_read_file");
if (offset >= fp->i_size)
return (FS_NOT_IN_FILE);
fs = fp->f_fs;
off = blkoff(fs, offset);
file_block = lblkno(fs, offset);
block_size = blksize(fs, fp, file_block);
rc = block_map(fp, file_block, &disk_block);
if (rc != 0)
return (rc);
if (disk_block == 0)
return (FS_NOT_IN_FILE);
if (size > block_size)
size = block_size;
return (device_read(fp->f_dev,
0,
(recnum_t) (fsbtodb(fs, disk_block) + btodb(off)),
(int) size,
(char **) addr,
size_read));
}
/*
* Write all or part of a data block, and
* return the amount written.
*/
int
page_write_file(fp, offset, addr, size, size_written)
register struct file *fp;
vm_offset_t offset;
vm_offset_t addr;
vm_size_t size;
vm_offset_t *size_written; /* out */
{
register struct fs *fs;
vm_offset_t off;
register daddr_t file_block;
daddr_t disk_block;
int rc;
vm_offset_t block_size;
if (offset % DEV_BSIZE != 0 ||
size % DEV_BSIZE != 0)
panic("page_write_file");
if (offset >= fp->i_size)
return (FS_NOT_IN_FILE);
fs = fp->f_fs;
off = blkoff(fs, offset);
file_block = lblkno(fs, offset);
block_size = blksize(fs, fp, file_block);
rc = block_map(fp, file_block, &disk_block);
if (rc != 0)
return (rc);
if (disk_block == 0)
return (FS_NOT_IN_FILE);
if (size > block_size)
size = block_size;
/*
* Write the data. Wait for completion to keep
* reads from getting ahead of writes and reading
* stale data.
*/
return (device_write(
fp->f_dev,
0,
(recnum_t) (fsbtodb(fs, disk_block) + btodb(off)),
(char *) addr,
size,
(int *)size_written));
}
/*
* Wire down file buffers if caller needs wired memory.
*/
int
file_wire(fp)
register struct file *fp;
{
register int rc;
register int i;
/*
* The disk super-block...
*/
rc = vm_pageable(mach_task_self(),
(vm_offset_t) fp->f_fs,
SBSIZE,
VM_PROT_READ|VM_PROT_WRITE);
if (rc != KERN_SUCCESS)
return (rc);
/*
* The inode buffer
*/
if (fp->f_buf) {
rc = vm_pageable(mach_task_self(),
fp->f_buf,
fp->f_buf_size,
VM_PROT_READ|VM_PROT_WRITE);
if (rc != KERN_SUCCESS)
return (rc);
}
/*
* And the data blocks.
*/
for (i = 0; i < NIADDR; i++) {
if (fp->f_blk[i]) {
rc = vm_pageable(mach_task_self(),
fp->f_blk[i],
fp->f_blksize[i],
VM_PROT_READ|VM_PROT_WRITE);
if (rc != KERN_SUCCESS)
return (rc);
}
}
return (0);
}
/*
* Character subroutines
*/
/*
* Concatenate a group of strings together into a buffer.
* Return a pointer to the trailing '\0' character in
* the result string.
* The list of strings ends with a '(char *)0'.
*/
/*VARARGS1*/
char *
strbuild(dest, va_alist)
register char * dest;
va_dcl
{
va_list argptr;
register char * src;
register int c;
va_start(argptr);
while ((src = va_arg(argptr, char *)) != (char *)0) {
while ((c = *src++) != '\0')
*dest++ = c;
}
*dest = '\0';
return (dest);
}
/*
* Return TRUE if string 2 is a prefix of string 1.
*/
boolean_t
strprefix(s1, s2)
register char *s1, *s2;
{
register int c;
while ((c = *s2++) != '\0') {
if (c != *s1++)
return (FALSE);
}
return (TRUE);
}
_size)
csize = buf_size;
if (csize == 0)
break;
bcopy((ch./kernel/boot_ufs/file_io.h 444 146 0 6540 4754020326 11101 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989,1988 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: file_io.h,v $
* Revision 2.3 91/02/05 17:01:33 mrt
* Changed to new copyright
* [91/01/28 14:54:57 mrt]
*
* Revision 2.2 90/08/27 21:45:45 dbg
* Re-create as boot_ufs/file_io.h.
* [90/07/18 dbg]
*
* Add table containing number of blocks mapped by each level of
* indirect block.
* [90/07/17 dbg]
*
* Declare error codes.
* [90/07/16 dbg]
*
* Revision 2.3 90/06/02 14:45:38 rpd
* Converted to new IPC.
* [90/03/26 21:31:55 rpd]
*
* Revision 2.2 89/09/08 11:22:21 dbg
* Put device_port and superblock pointer into inode.
* Rename structure to 'struct file'.
* [89/08/24 dbg]
*
* Version that reads the disk instead of mapping it.
* [89/07/17 dbg]
*
* 26-Oct-88 David Golub (dbg) at Carnegie-Mellon University
* Created.
*/
#ifndef _BOOT_UFS_FILE_IO_H_
#define _BOOT_UFS_FILE_IO_H_
/*
* Read-only file IO.
*/
#include
#include
#include
#include
#include
#include
/*
* In-core open file.
*/
struct file {
mach_port_t f_dev; /* port to mapped device */
struct fs * f_fs; /* pointer to super-block */
struct icommon i_ic; /* copy of on-disk inode */
int f_nindir[NIADDR+1];
/* number of blocks mapped by
indirect block at level i */
vm_offset_t f_blk[NIADDR]; /* buffer for indirect block at
level i */
vm_size_t f_blksize[NIADDR];
/* size of buffer */
daddr_t f_blkno[NIADDR];
/* disk address of block in buffer */
vm_offset_t f_buf; /* buffer for data block */
vm_size_t f_buf_size; /* size of data block */
daddr_t f_buf_blkno; /* block number of data block */
};
/*
* Exported routines.
*/
extern int open_file();
extern int read_file();
extern int page_read_file();
extern int page_write_file();
/*
* Error codes for file system errors.
*/
#define FS_NOT_DIRECTORY 5000 /* not a directory */
#define FS_NO_ENTRY 5001 /* name not found */
#define FS_NAME_TOO_LONG 5002 /* name too long */
#define FS_SYMLINK_LOOP 5003 /* symbolic link loop */
#define FS_INVALID_FS 5004 /* bad file system */
#define FS_NOT_IN_FILE 5005 /* offset not in file */
#define FS_INVALID_PARAMETER 5006 /* bad parameter to
a routine */
#endif /* _BOOT_UFS_FILE_IO_H_ */
le ((c = *s2++) != '\0') {
if (c != *s1++)
return (FALSE);
}
return (TRUE);
}
_size)
csize = buf_size;
if (csize == 0)
break;
bcopy((ch./kernel/boot_ufs/fs.h 444 146 0 44060 4754020327 10123 /*
* Mach Operating System
* Copyright (c) 1991,1990 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: fs.h,v $
* Revision 2.3 91/02/05 17:01:39 mrt
* Changed to new copyright
* [91/01/28 14:55:02 mrt]
*
* Revision 2.2 90/08/27 21:45:51 dbg
* Taken from BSD 4.3-Reno release.
* [90/07/26 dbg]
*
*/
/*
* Copyright (c) 1982, 1986 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#)fs.h 7.7 (Berkeley) 5/9/89
*/
/*
* Each disk drive contains some number of file systems.
* A file system consists of a number of cylinder groups.
* Each cylinder group has inodes and data.
*
* A file system is described by its super-block, which in turn
* describes the cylinder groups. The super-block is critical
* data and is replicated in each cylinder group to protect against
* catastrophic loss. This is done at `newfs' time and the critical
* super-block data does not change, so the copies need not be
* referenced further unless disaster strikes.
*
* For file system fs, the offsets of the various blocks of interest
* are given in the super block as:
* [fs->fs_sblkno] Super-block
* [fs->fs_cblkno] Cylinder group block
* [fs->fs_iblkno] Inode blocks
* [fs->fs_dblkno] Data blocks
* The beginning of cylinder group cg in fs, is given by
* the ``cgbase(fs, cg)'' macro.
*
* The first boot and super blocks are given in absolute disk addresses.
* The byte-offset forms are preferred, as they don't imply a sector size.
*/
#define BBSIZE 8192
#define SBSIZE 8192
#define BBOFF ((off_t)(0))
#define SBOFF ((off_t)(BBOFF + BBSIZE))
#define BBLOCK ((daddr_t)(0))
#define SBLOCK ((daddr_t)(BBLOCK + BBSIZE / DEV_BSIZE))
/*
* Addresses stored in inodes are capable of addressing fragments
* of `blocks'. File system blocks of at most size MAXBSIZE can
* be optionally broken into 2, 4, or 8 pieces, each of which is
* addressible; these pieces may be DEV_BSIZE, or some multiple of
* a DEV_BSIZE unit.
*
* Large files consist of exclusively large data blocks. To avoid
* undue wasted disk space, the last data block of a small file may be
* allocated as only as many fragments of a large block as are
* necessary. The file system format retains only a single pointer
* to such a fragment, which is a piece of a single large block that
* has been divided. The size of such a fragment is determinable from
* information in the inode, using the ``blksize(fs, ip, lbn)'' macro.
*
* The file system records space availability at the fragment level;
* to determine block availability, aligned fragments are examined.
*
* The root inode is the root of the file system.
* Inode 0 can't be used for normal purposes and
* historically bad blocks were linked to inode 1,
* thus the root inode is 2. (inode 1 is no longer used for
* this purpose, however numerous dump tapes make this
* assumption, so we are stuck with it)
*/
#define ROOTINO ((ino_t)2) /* i number of all roots */
/*
* MINBSIZE is the smallest allowable block size.
* In order to insure that it is possible to create files of size
* 2^32 with only two levels of indirection, MINBSIZE is set to 4096.
* MINBSIZE must be big enough to hold a cylinder group block,
* thus changes to (struct cg) must keep its size within MINBSIZE.
* Note that super blocks are always of size SBSIZE,
* and that both SBSIZE and MAXBSIZE must be >= MINBSIZE.
*/
#define MINBSIZE 4096
/*
* The path name on which the file system is mounted is maintained
* in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in
* the super block for this name.
* The limit on the amount of summary information per file system
* is defined by MAXCSBUFS. It is currently parameterized for a
* maximum of two million cylinders.
*/
#define MAXMNTLEN 512
#define MAXCSBUFS 32
/*
* Per cylinder group information; summarized in blocks allocated
* from first cylinder group data blocks. These blocks have to be
* read in from fs_csaddr (size fs_cssize) in addition to the
* super block.
*
* N.B. sizeof(struct csum) must be a power of two in order for
* the ``fs_cs'' macro to work (see below).
*/
struct csum {
long cs_ndir; /* number of directories */
long cs_nbfree; /* number of free blocks */
long cs_nifree; /* number of free inodes */
long cs_nffree; /* number of free frags */
};
/*
* Super block for a file system.
*/
#define FS_MAGIC 0x011954
struct fs
{
struct fs *fs_link; /* linked list of file systems */
struct fs *fs_rlink; /* used for incore super blocks */
daddr_t fs_sblkno; /* addr of super-block in filesys */
daddr_t fs_cblkno; /* offset of cyl-block in filesys */
daddr_t fs_iblkno; /* offset of inode-blocks in filesys */
daddr_t fs_dblkno; /* offset of first data after cg */
long fs_cgoffset; /* cylinder group offset in cylinder */
long fs_cgmask; /* used to calc mod fs_ntrak */
time_t fs_time; /* last time written */
long fs_size; /* number of blocks in fs */
long fs_dsize; /* number of data blocks in fs */
long fs_ncg; /* number of cylinder groups */
long fs_bsize; /* size of basic blocks in fs */
long fs_fsize; /* size of frag blocks in fs */
long fs_frag; /* number of frags in a block in fs */
/* these are configuration parameters */
long fs_minfree; /* minimum percentage of free blocks */
long fs_rotdelay; /* num of ms for optimal next block */
long fs_rps; /* disk revolutions per second */
/* these fields can be computed from the others */
long fs_bmask; /* ``blkoff'' calc of blk offsets */
long fs_fmask; /* ``fragoff'' calc of frag offsets */
long fs_bshift; /* ``lblkno'' calc of logical blkno */
long fs_fshift; /* ``numfrags'' calc number of frags */
/* these are configuration parameters */
long fs_maxcontig; /* max number of contiguous blks */
long fs_maxbpg; /* max number of blks per cyl group */
/* these fields can be computed from the others */
long fs_fragshift; /* block to frag shift */
long fs_fsbtodb; /* fsbtodb and dbtofsb shift constant */
long fs_sbsize; /* actual size of super block */
long fs_csmask; /* csum block offset */
long fs_csshift; /* csum block number */
long fs_nindir; /* value of NINDIR */
long fs_inopb; /* value of INOPB */
long fs_nspf; /* value of NSPF */
/* yet another configuration parameter */
long fs_optim; /* optimization preference, see below */
/* these fields are derived from the hardware */
long fs_npsect; /* # sectors/track including spares */
long fs_interleave; /* hardware sector interleave */
long fs_trackskew; /* sector 0 skew, per track */
long fs_headswitch; /* head switch time, usec */
long fs_trkseek; /* track-to-track seek, usec */
/* sizes determined by number of cylinder groups and their sizes */
daddr_t fs_csaddr; /* blk addr of cyl grp summary area */
long fs_cssize; /* size of cyl grp summary area */
long fs_cgsize; /* cylinder group size */
/* these fields are derived from the hardware */
long fs_ntrak; /* tracks per cylinder */
long fs_nsect; /* sectors per track */
long fs_spc; /* sectors per cylinder */
/* this comes from the disk driver partitioning */
long fs_ncyl; /* cylinders in file system */
/* these fields can be computed from the others */
long fs_cpg; /* cylinders per group */
long fs_ipg; /* inodes per group */
long fs_fpg; /* blocks per group * fs_frag */
/* this data must be re-computed after crashes */
struct csum fs_cstotal; /* cylinder summary information */
/* these fields are cleared at mount time */
char fs_fmod; /* super block modified flag */
char fs_clean; /* file system is clean flag */
char fs_ronly; /* mounted read-only flag */
char fs_flags; /* currently unused flag */
char fs_fsmnt[MAXMNTLEN]; /* name mounted on */
/* these fields retain the current block allocation info */
long fs_cgrotor; /* last cg searched */
struct csum *fs_csp[MAXCSBUFS];/* list of fs_cs info buffers */
long fs_cpc; /* cyl per cycle in postbl */
short fs_opostbl[16][8]; /* old rotation block list head */
long fs_sparecon[56]; /* reserved for future constants */
quad fs_qbmask; /* ~fs_bmask - for use with quad size */
quad fs_qfmask; /* ~fs_fmask - for use with quad size */
long fs_postblformat; /* format of positional layout tables */
long fs_nrpos; /* number of rotaional positions */
long fs_postbloff; /* (short) rotation block list head */
long fs_rotbloff; /* (u_char) blocks for each rotation */
long fs_magic; /* magic number */
u_char fs_space[1]; /* list of blocks for each rotation */
/* actually longer */
};
/*
* Preference for optimization.
*/
#define FS_OPTTIME 0 /* minimize allocation time */
#define FS_OPTSPACE 1 /* minimize disk fragmentation */
/*
* Rotational layout table format types
*/
#define FS_42POSTBLFMT -1 /* 4.2BSD rotational table format */
#define FS_DYNAMICPOSTBLFMT 1 /* dynamic rotational table format */
/*
* Macros for access to superblock array structures
*/
#define fs_postbl(fs, cylno) \
(((fs)->fs_postblformat == FS_42POSTBLFMT) \
? ((fs)->fs_opostbl[cylno]) \
: ((short *)((char *)(fs) + (fs)->fs_postbloff) + (cylno) * (fs)->fs_nrpos))
#define fs_rotbl(fs) \
(((fs)->fs_postblformat == FS_42POSTBLFMT) \
? ((fs)->fs_space) \
: ((u_char *)((char *)(fs) + (fs)->fs_rotbloff)))
/*
* Convert cylinder group to base address of its global summary info.
*
* N.B. This macro assumes that sizeof(struct csum) is a power of two.
*/
#define fs_cs(fs, indx) \
fs_csp[(indx) >> (fs)->fs_csshift][(indx) & ~(fs)->fs_csmask]
/*
* Cylinder group block for a file system.
*/
#define CG_MAGIC 0x090255
struct cg {
struct cg *cg_link; /* linked list of cyl groups */
long cg_magic; /* magic number */
time_t cg_time; /* time last written */
long cg_cgx; /* we are the cgx'th cylinder group */
short cg_ncyl; /* number of cyl's this cg */
short cg_niblk; /* number of inode blocks this cg */
long cg_ndblk; /* number of data blocks this cg */
struct csum cg_cs; /* cylinder summary information */
long cg_rotor; /* position of last used block */
long cg_frotor; /* position of last used frag */
long cg_irotor; /* position of last used inode */
long cg_frsum[MAXFRAG]; /* counts of available frags */
long cg_btotoff; /* (long) block totals per cylinder */
long cg_boff; /* (short) free block positions */
long cg_iusedoff; /* (char) used inode map */
long cg_freeoff; /* (u_char) free block map */
long cg_nextfreeoff; /* (u_char) next available space */
long cg_sparecon[16]; /* reserved for future use */
u_char cg_space[1]; /* space for cylinder group maps */
/* actually longer */
};
/*
* Macros for access to cylinder group array structures
*/
#define cg_blktot(cgp) \
(((cgp)->cg_magic != CG_MAGIC) \
? (((struct ocg *)(cgp))->cg_btot) \
: ((long *)((char *)(cgp) + (cgp)->cg_btotoff)))
#define cg_blks(fs, cgp, cylno) \
(((cgp)->cg_magic != CG_MAGIC) \
? (((struct ocg *)(cgp))->cg_b[cylno]) \
: ((short *)((char *)(cgp) + (cgp)->cg_boff) + (cylno) * (fs)->fs_nrpos))
#define cg_inosused(cgp) \
(((cgp)->cg_magic != CG_MAGIC) \
? (((struct ocg *)(cgp))->cg_iused) \
: ((char *)((char *)(cgp) + (cgp)->cg_iusedoff)))
#define cg_blksfree(cgp) \
(((cgp)->cg_magic != CG_MAGIC) \
? (((struct ocg *)(cgp))->cg_free) \
: ((u_char *)((char *)(cgp) + (cgp)->cg_freeoff)))
#define cg_chkmagic(cgp) \
((cgp)->cg_magic == CG_MAGIC || ((struct ocg *)(cgp))->cg_magic == CG_MAGIC)
/*
* The following structure is defined
* for compatibility with old file systems.
*/
struct ocg {
struct ocg *cg_link; /* linked list of cyl groups */
struct ocg *cg_rlink; /* used for incore cyl groups */
time_t cg_time; /* time last written */
long cg_cgx; /* we are the cgx'th cylinder group */
short cg_ncyl; /* number of cyl's this cg */
short cg_niblk; /* number of inode blocks this cg */
long cg_ndblk; /* number of data blocks this cg */
struct csum cg_cs; /* cylinder summary information */
long cg_rotor; /* position of last used block */
long cg_frotor; /* position of last used frag */
long cg_irotor; /* position of last used inode */
long cg_frsum[8]; /* counts of available frags */
long cg_btot[32]; /* block totals per cylinder */
short cg_b[32][8]; /* positions of free blocks */
char cg_iused[256]; /* used inode map */
long cg_magic; /* magic number */
u_char cg_free[1]; /* free block map */
/* actually longer */
};
/*
* Turn file system block numbers into disk block addresses.
* This maps file system blocks to device size blocks.
*/
#define fsbtodb(fs, b) ((b) << (fs)->fs_fsbtodb)
#define dbtofsb(fs, b) ((b) >> (fs)->fs_fsbtodb)
/*
* Cylinder group macros to locate things in cylinder groups.
* They calc file system addresses of cylinder group data structures.
*/
#define cgbase(fs, c) ((daddr_t)((fs)->fs_fpg * (c)))
#define cgstart(fs, c) \
(cgbase(fs, c) + (fs)->fs_cgoffset * ((c) & ~((fs)->fs_cgmask)))
#define cgsblock(fs, c) (cgstart(fs, c) + (fs)->fs_sblkno) /* super blk */
#define cgtod(fs, c) (cgstart(fs, c) + (fs)->fs_cblkno) /* cg block */
#define cgimin(fs, c) (cgstart(fs, c) + (fs)->fs_iblkno) /* inode blk */
#define cgdmin(fs, c) (cgstart(fs, c) + (fs)->fs_dblkno) /* 1st data */
/*
* Macros for handling inode numbers:
* inode number to file system block offset.
* inode number to cylinder group number.
* inode number to file system block address.
*/
#define itoo(fs, x) ((x) % INOPB(fs))
#define itog(fs, x) ((x) / (fs)->fs_ipg)
#define itod(fs, x) \
((daddr_t)(cgimin(fs, itog(fs, x)) + \
(blkstofrags((fs), (((x) % (fs)->fs_ipg) / INOPB(fs))))))
/*
* Give cylinder group number for a file system block.
* Give cylinder group block number for a file system block.
*/
#define dtog(fs, d) ((d) / (fs)->fs_fpg)
#define dtogd(fs, d) ((d) % (fs)->fs_fpg)
/*
* Extract the bits for a block from a map.
* Compute the cylinder and rotational position of a cyl block addr.
*/
#define blkmap(fs, map, loc) \
(((map)[(loc) / NBBY] >> ((loc) % NBBY)) & (0xff >> (NBBY - (fs)->fs_frag)))
#define cbtocylno(fs, bno) \
((bno) * NSPF(fs) / (fs)->fs_spc)
#define cbtorpos(fs, bno) \
(((bno) * NSPF(fs) % (fs)->fs_spc / (fs)->fs_nsect * (fs)->fs_trackskew + \
(bno) * NSPF(fs) % (fs)->fs_spc % (fs)->fs_nsect * (fs)->fs_interleave) % \
(fs)->fs_nsect * (fs)->fs_nrpos / (fs)->fs_npsect)
/*
* The following macros optimize certain frequently calculated
* quantities by using shifts and masks in place of divisions
* modulos and multiplications.
*/
#define blkoff(fs, loc) /* calculates (loc % fs->fs_bsize) */ \
((loc) & ~(fs)->fs_bmask)
#define fragoff(fs, loc) /* calculates (loc % fs->fs_fsize) */ \
((loc) & ~(fs)->fs_fmask)
#define lblkno(fs, loc) /* calculates (loc / fs->fs_bsize) */ \
((loc) >> (fs)->fs_bshift)
#define numfrags(fs, loc) /* calculates (loc / fs->fs_fsize) */ \
((loc) >> (fs)->fs_fshift)
#define blkroundup(fs, size) /* calculates roundup(size, fs->fs_bsize) */ \
(((size) + (fs)->fs_bsize - 1) & (fs)->fs_bmask)
#define fragroundup(fs, size) /* calculates roundup(size, fs->fs_fsize) */ \
(((size) + (fs)->fs_fsize - 1) & (fs)->fs_fmask)
#define fragstoblks(fs, frags) /* calculates (frags / fs->fs_frag) */ \
((frags) >> (fs)->fs_fragshift)
#define blkstofrags(fs, blks) /* calculates (blks * fs->fs_frag) */ \
((blks) << (fs)->fs_fragshift)
#define fragnum(fs, fsb) /* calculates (fsb % fs->fs_frag) */ \
((fsb) & ((fs)->fs_frag - 1))
#define blknum(fs, fsb) /* calculates rounddown(fsb, fs->fs_frag) */ \
((fsb) &~ ((fs)->fs_frag - 1))
/*
* Determine the number of available frags given a
* percentage to hold in reserve
*/
#define freespace(fs, percentreserved) \
(blkstofrags((fs), (fs)->fs_cstotal.cs_nbfree) + \
(fs)->fs_cstotal.cs_nffree - ((fs)->fs_dsize * (percentreserved) / 100))
/*
* Determining the size of a file block in the file system.
*/
#define blksize(fs, ip, lbn) \
(((lbn) >= NDADDR || (ip)->i_size >= ((lbn) + 1) << (fs)->fs_bshift) \
? (fs)->fs_bsize \
: (fragroundup(fs, blkoff(fs, (ip)->i_size))))
#define dblksize(fs, dip, lbn) \
(((lbn) >= NDADDR || (dip)->di_size >= ((lbn) + 1) << (fs)->fs_bshift) \
? (fs)->fs_bsize \
: (fragroundup(fs, blkoff(fs, (dip)->di_size))))
/*
* Number of disk sectors per block; assumes DEV_BSIZE byte sector size.
*/
#define NSPB(fs) ((fs)->fs_nspf << (fs)->fs_fragshift)
#define NSPF(fs) ((fs)->fs_nspf)
/*
* INOPB is the number of inodes in a secondary storage block.
*/
#define INOPB(fs) ((fs)->fs_inopb)
#define INOPF(fs) ((fs)->fs_inopb >> (fs)->fs_fragshift)
/*
* NINDIR is the number of indirects in a file system block.
*/
#define NINDIR(fs) ((fs)->fs_nindir)
#ifdef KERNEL
struct fs *getfs();
#endif
s_fsbtodb)
/*
* Cylinder group macros to locate things in cylinder groups.
* They calc file system addresses of cylinder group data structures.
*/
#define cgbase(fs, c) ((daddr_t)((fs)->fs_fpg * (c)))
#define cgstart(fs, c) \
(cgbase(fs, c) + (fs)->fs_cgoffset * ((c) & ~((fs)->fs_cgmask)))
#define cgsblock(fs, c) (cgstart(fs, c) + (fs)->fs_sblkno) /* super blk */
#define cgtod(fs, c) (cgstart(fs, c) + (fs)->fs_cblkno) /* cg block */
#define cgimin(fs, c) ./kernel/boot_ufs/load.c 444 146 0 30556 4754020331 10425 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989,1988 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: load.c,v $
* Revision 2.9 91/02/05 17:01:45 mrt
* Changed to new copyright
* [91/01/28 14:55:09 mrt]
*
* Revision 2.8 90/10/25 14:42:05 rwd
* Modified boot_load_program and read_emulator_symbols
* to allocate arrays from heap, not stack.
* [90/10/23 rpd]
*
* Revision 2.7 90/08/27 21:46:02 dbg
* Reduce lint.
* [90/08/13 dbg]
*
* Use new error codes. Use new file_io package.
* [90/07/16 dbg]
*
* Revision 2.6 90/06/02 14:45:31 rpd
* Added read_emulator_symbols.
* [90/05/11 17:08:19 rpd]
*
* From jsb: to support debugging, read in the server's symbol table.
* [90/04/23 rpd]
* Converted to new IPC.
* [90/03/26 21:31:33 rpd]
*
* Revision 2.5 90/01/11 11:41:20 dbg
* Use bootstrap-task print routines.
* [89/12/20 dbg]
*
* Revision 2.4 89/11/14 10:28:13 dbg
* Restore read-only protection for text segment.
* [89/11/01 dbg]
*
* Revision 2.3 89/09/08 11:22:13 dbg
* Use new open_file routine. Change 'struct inode' to
* 'struct file' for new stand-alone IO package.
* [89/08/31 dbg]
*
* 26-May-89 Randall Dean (rwd) at Carnegie-Mellon University
* Fixed separate text/data case. Added copyright to version
* generated by dbg
*
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*
* Loader for a.out format.
* Loads the file into the user space of the specified task,
* and sets up the starting thread's registers.
*/
extern char *set_regs();
extern int ex_get_header();
boolean_t load_protect_text = TRUE;
int load_program_file(fp, user_task, user_thread, arg_size, arg_pos_p)
register struct file * fp;
mach_port_t user_task;
mach_port_t user_thread;
int arg_size;
char * *arg_pos_p; /* out */
{
struct loader_info lp;
kern_return_t result;
vm_offset_t text_page_start,
text_page_end,
data_page_start,
data_page_end,
area_start;
vm_size_t resid;
if ((fp->i_mode & IFMT) != IFREG ||
(fp->i_mode & (IEXEC|IEXEC>>3|IEXEC>>6)) == 0)
return (EX_NOT_EXECUTABLE);
/*
* Read in the header and get the file pointers.
*/
result = ex_get_header(fp, &lp);
if (result)
return (result);
/*
* Allocate space.
*/
text_page_start = trunc_page(lp.text_start);
text_page_end = round_page(lp.text_start + lp.text_size);
data_page_start = trunc_page(lp.data_start);
data_page_end = round_page(lp.data_start + lp.data_size
+ lp.bss_size);
if (text_page_end >= data_page_start) {
/*
* One contiguous area for text and data.
*/
result = vm_allocate(mach_task_self(),
&area_start,
(vm_size_t)(data_page_end - text_page_start),
TRUE);
if (result)
return (result);
result = read_file(fp,
lp.text_offset,
area_start + (lp.text_start - text_page_start),
lp.text_size,
&resid);
if (result)
return (result);
if (resid)
return (EX_NOT_EXECUTABLE);
result = read_file(fp,
lp.data_offset,
area_start + (lp.data_start - text_page_start),
lp.data_size,
&resid);
if (result)
return (result);
if (resid)
return (EX_NOT_EXECUTABLE);
blkclr((char *)(area_start +
(lp.data_start + lp.data_size
- text_page_start)),
lp.bss_size);
result = vm_allocate(user_task,
&text_page_start,
(vm_size_t)(data_page_end - text_page_start),
FALSE);
if (result)
return (result);
result = vm_write(user_task,
text_page_start,
(pointer_t)area_start,
(vm_size_t)(data_page_end - text_page_start));
if (result)
return (result);
result = vm_deallocate(mach_task_self(),
area_start,
(vm_size_t)(data_page_end - text_page_start));
if (result)
return (result);
}
else {
/*
* Separated text and data areas.
*/
/*
* First read in the text
*/
result = vm_allocate(mach_task_self(),
&area_start,
(vm_size_t)(text_page_end - text_page_start),
TRUE);
if (result)
return (result);
result = read_file(fp,
lp.text_offset,
area_start + (lp.text_start - text_page_start),
lp.text_size,
&resid);
if (result)
return (result);
if (resid)
return (EX_NOT_EXECUTABLE);
result = vm_allocate(user_task,
&text_page_start,
(vm_size_t)(text_page_end - text_page_start),
FALSE);
if (result)
return (result);
result = vm_write(user_task,
text_page_start,
(pointer_t)area_start,
(vm_size_t)(text_page_end - text_page_start));
if (result)
return (result);
result = vm_deallocate(mach_task_self(),
area_start,
(vm_size_t)(text_page_end - text_page_start));
if (result)
return (result);
/*
* Then the data
*/
result = vm_allocate(mach_task_self(),
&area_start,
(vm_size_t)(data_page_end - data_page_start),
TRUE);
if (result)
return (result);
result = read_file(fp,
lp.data_offset,
area_start + (lp.data_start - data_page_start),
lp.data_size,
&resid);
if (result)
return (result);
if (resid)
return (EX_NOT_EXECUTABLE);
blkclr((char *)(area_start +
(lp.data_start + lp.data_size
- data_page_start)),
lp.bss_size);
result = vm_allocate(user_task,
&data_page_start,
(vm_size_t)(data_page_end - data_page_start),
FALSE);
if (result)
return (result);
result = vm_write(user_task,
data_page_start,
(pointer_t)area_start,
(vm_size_t)(data_page_end - data_page_start));
if (result)
return (result);
result = vm_deallocate(mach_task_self(),
area_start,
(vm_size_t)(data_page_end - data_page_start));
if (result)
return (result);
}
/*
* Protect the text.
*/
if (load_protect_text) {
result = vm_protect(user_task,
text_page_start,
(vm_size_t)(trunc_page(lp.text_start+lp.text_size)
- text_page_start),
FALSE,
VM_PROT_READ|VM_PROT_EXECUTE);
if (result)
return (result);
}
/*
* Set up the stack and user registers.
*/
*arg_pos_p = set_regs(user_task, user_thread, &lp, arg_size);
return (KERN_SUCCESS);
}
/*VARARGS4*/
int boot_load_program(master_device_port,
user_task,
user_thread,
rootname,
va_alist) /* first component is program name */
mach_port_t master_device_port;
mach_port_t user_thread;
char rootname[];
va_dcl
{
va_list argv_ptr;
char * arg_ptr;
int arg_len;
int arg_count;
char * arg_pos;
unsigned int arg_item_len;
kern_return_t result;
struct file file;
char * file_name;
char * namebuf;
extern char * strbuild();
/*
* Get the target file name
*/
va_start(argv_ptr);
file_name = va_arg(argv_ptr, char *);
va_end(argv_ptr);
/*
* Build file name: "/dev/$rootname/$filename"
*/
namebuf = (char *) kalloc(MAXPATHLEN+1);
(void) strbuild(namebuf, "/dev/",
rootname,
"/",
file_name,
(char *)0);
/*
* Open the file
*/
bzero((char *)&file, sizeof(file));
result = open_file(master_device_port, namebuf, &file);
if (result != 0) {
panic("openi %d", result);
}
/*
* Calculate the size of the argument list.
*/
va_start(argv_ptr);
arg_len = 0;
arg_count = 0;
for (;;) {
arg_ptr = va_arg(argv_ptr, char *);
if (arg_ptr == (char *)0)
break;
arg_count++;
arg_len += strlen(arg_ptr) + 1; /* space for '\0' */
}
va_end(argv_ptr);
/*
* Add space for:
* arg_count
* pointers to arguments
* trailing 0 pointer
* dummy 0 pointer to environment variables
* and align to integer boundary
*/
arg_len += sizeof(int) + (2 + arg_count) * sizeof(char *);
arg_len = (arg_len + (sizeof(int) - 1)) & ~(sizeof(int)-1);
/*
* Load the file
*/
result = load_program_file(&file, user_task, user_thread, arg_len,
&arg_pos);
if (result)
panic("load_program_file %d", result);
#if MACH_KDB
/*
* Read symbols from file
*/
read_symtab_from_file(&file, "unix");
#endif MACH_KDB
/*
* Copy out the arguments.
*/
{
vm_offset_t u_arg_start;
/* user start of argument list block */
vm_offset_t k_arg_start;
/* kernel start of argument list block */
vm_offset_t u_arg_page_start;
/* user start of args, page-aligned */
vm_size_t arg_page_size;
/* page_aligned size of args */
vm_offset_t k_arg_page_start;
/* kernel start of args, page-aligned */
register
char ** k_ap; /* kernel arglist address */
char * u_cp; /* user argument string address */
register
char * k_cp; /* kernel argument string address */
register
int i;
/*
* Get address of argument list in user space
*/
u_arg_start = (vm_offset_t)arg_pos;
/*
* Round to page boundaries, and allocate kernel copy
*/
u_arg_page_start = trunc_page(u_arg_start);
arg_page_size = (vm_size_t)(round_page(u_arg_start + arg_len)
- u_arg_page_start);
(void) vm_allocate(mach_task_self(),
&k_arg_page_start,
(vm_size_t)arg_page_size,
TRUE);
/*
* Set up addresses corresponding to user pointers
* in the kernel block
*/
k_arg_start = k_arg_page_start + (u_arg_start - u_arg_page_start);
k_ap = (char **)k_arg_start;
/*
* Start the strings after the arg-count and pointers
*/
u_cp = (char *)u_arg_start + arg_count * sizeof(char *)
+ 2 * sizeof(char *)
+ sizeof(int);
k_cp = (char *)k_arg_start + arg_count * sizeof(char *)
+ 2 * sizeof(char *)
+ sizeof(int);
/*
* first the argument count
*/
*k_ap++ = (char *)arg_count;
/*
* Then the strings and string pointers for each argument
*/
va_start(argv_ptr);
for (i = 0; i < arg_count; i++) {
arg_ptr = va_arg(argv_ptr, char *);
arg_item_len = strlen(arg_ptr) + 1; /* include trailing 0 */
/* set string pointer */
*k_ap++ = u_cp;
/* copy string */
bcopy(arg_ptr, k_cp, arg_item_len);
k_cp += arg_item_len;
u_cp += arg_item_len;
}
va_end(argv_ptr);
/*
* last, the trailing 0 argument and a null environment pointer.
*/
*k_ap++ = (char *)0;
*k_ap = (char *)0;
/*
* Now write all of this to user space.
*/
(void) vm_write(user_task,
u_arg_page_start,
k_arg_page_start,
arg_page_size);
(void) vm_deallocate(mach_task_self(),
k_arg_page_start,
arg_page_size);
}
kfree((vm_offset_t)namebuf, MAXPATHLEN+1);
return (0);
}
read_emulator_symbols(master_device_port, rootname, file_name)
mach_port_t master_device_port;
char rootname[];
char file_name[];
{
kern_return_t result;
struct file file;
char * namebuf;
extern char * strbuild();
#if MACH_KDB
/*
* Build file name: "/dev/$rootname/$filename"
*/
namebuf = (char *) kalloc(MAXPATHLEN+1);
(void) strbuild(namebuf, "/dev/",
rootname,
"/",
file_name,
(char *)0);
/*
* Open the file
*/
bzero((char *)&file, sizeof(file));
result = open_file(master_device_port, namebuf, &file);
if (result != 0) {
panic("openi %d", result);
}
/*
* Read symbols from file
*/
read_symtab_from_file(&file, "emulator");
kfree((vm_offset_t)namebuf, MAXPATHLEN+1);
#endif MACH_KDB
}
arg_count = 0;
for (;;) {
arg_ptr = va_arg(argv_ptr, char *);
if (arg_ptr == (char *)0)
break;
arg_count++;
arg_len += st./kernel/boot_ufs/loader_info.h 444 146 0 4314 4754020332 11746 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989,1988 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: loader_info.h,v $
* Revision 2.3 91/02/05 17:01:50 mrt
* Changed to new copyright
* [91/01/28 14:55:19 mrt]
*
* Revision 2.2 90/08/27 21:46:12 dbg
* Added error return codes and imported function declarations.
* [90/07/18 dbg]
*
*/
#ifndef _BOOT_UFS_LOADER_INFO_H_
#define _BOOT_UFS_LOADER_INFO_H_
/*
* Data structures for bootstrap program loader.
*/
struct loader_info {
int format; /* load format */
vm_offset_t text_start; /* text start in memory */
vm_size_t text_size;
vm_offset_t text_offset; /* text offset in file */
vm_offset_t data_start; /* data+bss start in memory */
vm_size_t data_size;
vm_offset_t data_offset; /* data offset in file */
vm_size_t bss_size;
vm_offset_t entry_1; /* 2 words for entry address */
vm_offset_t entry_2;
} ;
/*
* Possible executable file formats
*/
#define EX_UNKNOWN 0 /* ? */
#define EX_READIN 1 /* 0407 */
#define EX_SHAREABLE 2 /* 0410 */
#define EX_PAGEABLE 3 /* 0413 */
/*
* Exported routines (from machine-dependent implementation file)
*/
extern int ex_get_header();
extern char * set_regs();
/*
* Error codes
*/
#define EX_NOT_EXECUTABLE 6000
#endif /* _BOOT_UFS_LOADER_INFO_H_ */
he trailing 0 argument and a null environment pointer.
*/
*k_ap++ = (char *)0;
*k_ap = (char *)0;
/*
* Now write all of this to user space.
*/
(void) vm_write(user_task,
u_arg_page_start,
k_arg_page_start,
arg_page_size);
(void) vm_dealloca./kernel/Makeconf 444 146 0 6515 4754020311 7144 #
# Mach Operating System
# Copyright (c) 1991,1990,1989 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
# 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 [email protected]
# 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.
#
#
# HISTORY
# $Log: Makeconf,v $
# Revision 2.11 91/02/05 17:00:15 mrt
# Changed to new copyright
# [91/01/28 14:44:45 mrt]
#
# Revision 2.10 90/12/14 10:58:13 jsb
# Allow ATSYS variable to override @sys in OBJECTDIR.
# [90/12/13 20:55:17 jsb]
#
# Revision 2.9 90/12/04 14:45:27 jsb
# Added ATSYS variable which can be used to override use of @sys
# in OBJECTDIR when cross-compiling.
# [90/12/04 11:35:36 jsb]
#
# Revision 2.8 90/11/25 17:47:11 jsb
# Added i860 support.
# [90/11/25 16:54:28 jsb]
#
# Revision 2.7 90/11/05 14:25:00 rpd
# SUN->SUN3.
# [90/10/31 rwd]
# Added REG_EXP.
# [90/10/29 rwd]
#
# Change MACHINE to TARGET_MACHINE.
# [90/10/29 rwd]
#
# Revision 2.6 90/06/02 14:45:04 rpd
# Changed standard Sun configuration to STD+SWS.
# [90/03/26 21:26:36 rpd]
#
# Revision 2.5 90/05/03 15:14:37 dbg
# Add i386 and at386 configuration.
# [90/02/08 dbg]
#
# Revision 2.4 90/01/22 23:04:17 af
# Pmaxen now have the new MI KDB too.
# [90/01/22 af]
#
# Revision 2.3 89/11/29 14:07:51 af
# Pure kernel does not seem to like EXP yet.
# [89/10/29 af]
# Added PMAX, removed obsolete IBMRT (:-)
# [89/10/28 af]
#
# Revision 2.2 89/08/04 10:52:35 rwd
# Remove VPATH and SRCDIR
# [89/08/04 rwd]
#
# Revision 2.1 89/08/03 17:41:40 rwd
# Created.
#
# Revision 2.7 89/04/10 00:34:59 rpd
# Changed OBJECTDIR name to correspond to new organization.
# [89/04/06 mrt]
#
# Revision 2.6 89/02/25 14:12:18 gm0w
# Changes for cleanup.
#
# Revision 2.5 89/02/25 14:08:30 gm0w
# Changes for cleanup.
#
# Revision 2.4 88/11/14 15:04:01 gm0w
# Changed the standard configurations to correspond
# to the new names.
# [88/11/02 15:45:44 mrt]
#
# Revision 2.3 88/09/07 15:44:43 rpd
# Moved CONFIG macros here from Makefile, so that the user
# can easily customize them by modifying Makeconf.
# [88/09/07 01:52:32 rpd]
#
# Revision 2.2 88/07/15 15:11:46 mja
# Created.
#
atsys=${ATSYS?$(ATSYS):@sys}
OBJECTDIR=../../../obj/$(atsys)/${BCSBBASE?$(BCSBBASE:t):latest}/kernel
VAX_CONFIG=STD+VAX6bb
SUN3_CONFIG=STD+SWS
PMAX_CONFIG=STD+ANY
I386_CONFIG=STD+WS
AT386_CONFIG=STD+WS
I386_REG_EXP=.*
I860_REG_EXP=.*
CONFIG=$(${TARGET_MACHINE}_CONFIG)
REG_EXP=${$(TARGET_MACHINE)_REG_EXP?${$(TARGET_MACHINE)_REG_EXP}:*}
f @sys
# in OBJECTDIR when cross-compiling.
# [90/12/04 11:35:36 jsb]
#
# Revision 2.8 90/11/25 17:47:11 jsb
# Added i860 support.
# [90/11/25 16:54:28 jsb]
#
# Revis./kernel/Makefile 444 146 0 14033 4754020312 7151 #
# Mach Operating System
# Copyright (c) 1991,1990,1989 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
# 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 [email protected]
# 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.
#
#
# HISTORY
# $Log: Makefile,v $
# Revision 2.8 91/02/05 17:00:20 mrt
# Changed to new copyright
# [91/01/28 14:43:17 mrt]
#
# Revision 2.7 90/11/25 17:48:12 jsb
# Added i860 support.
# [90/11/25 16:16:19 jsb]
#
# Revision 2.6 90/11/05 14:25:13 rpd
# SUN->SUN3.
# [90/10/31 rwd]
# Change MACHINE to TARGET_MACHINE.
# [90/10/29 rwd]
#
# Revision 2.5 90/06/02 14:45:08 rpd
# Added rules to build mig.
# [90/03/26 21:27:35 rpd]
#
#
# Condensed history:
# Added rules for lint (dbg).
# Added code to save CONFIG in vers.config file (gm0w).
# Added sun4 support (jjc).
# Use conf/make.template and conf/mkconfig.csh (gm0w).
# Added multimax support (dlb).
# Added pmax and i386 support (af, rvb).
# Added rules for pmake (rvb).
# Much trial & error hacking (mwyoung, rpd).
# Created (mja).
#
#
# Targets of interest:
# doconf Rebuild the configuration file
# config Reconfigure
# kernel Rebuild just the kernel
# pmake Rebuild just the kernel using pmake
# buildconf Build all of the "standard" configurations
# lint Lint the kernel
#
VAX_cpu=vax
IBMRT_cpu=ca
SUN3_cpu=sun3
MMAX_cpu=mmax
PMAX_cpu=mips
I386_cpu=i386
SUN4_cpu=sun4
AT386_cpu=i386
I860_cpu=i860
cpu=$(${TARGET_MACHINE}_cpu)
VAX_OUTPUT=Makefile
SUN3_OUTPUT=Makefile
IBMRT_OUTPUT=Makefile
MMAX_OUTPUT=Makefile
PMAX_OUTPUT=Makefile
I386_OUTPUT=Makefile
SUN4_OUTPUT=Makefile
AT386_OUTPUT=Makefile
I860_OUTPUT=Makefile
MASTER_DIR=conf
MASTER=${MASTER_DIR}/MASTER
MASTER_CPU=${MASTER}.${cpu}
MASTER_LOCAL=${MASTER_DIR}/MASTER.local
MASTER_CPU_LOCAL=${MASTER}.${cpu}.local
CONFIG_INPUT=${CONFIG}/${CONFIG}
CONFIG_OUTPUT=${CONFIG}/$(${TARGET_MACHINE}_OUTPUT)
MAKE_ARGS="REG_EXP=${REG_EXP}"
PMAKE_ARGS= -k -P6 "P=&" all
SOURCE_DIR=..
${CONFIG}.all: ${CONFIG}/make \
${CONFIG}/Makeconf \
${CONFIG}.doconf \
${CONFIG}.config \
${CONFIG}.mig \
${CONFIG}.make
${CONFIG}.make kernel: ${CONFIG}/make ${CONFIG}/Makeconf
@echo "[ making ${CONFIG} ]"
@cd ${CONFIG} && USE_SOURCE_DIR=1 ./make ${MAKE_ARGS}
pmake: ${CONFIG}/make ${CONFIG}/Makeconf
@echo "[ pmaking ${CONFIG} ]"
@cd ${CONFIG} && USE_SOURCE_DIR=1 ./pmake ${PMAKE_ARGS}
${CONFIG}.lint lint: ${CONFIG}/make ${CONFIG}/Makeconf
@echo "[ linting ${CONFIG} ]"
@cd ${CONFIG} && USE_SOURCE_DIR=1 ./make lint ${MAKE_ARGS}
${CONFIG}.doconf doconf: ${CONFIG_INPUT}
${CONFIG}.config config:: ${CONFIG}/make \
${CONFIG}/Makeconf \
${CONFIG}/Makefile.top-level \
./bin/config \
${CONFIG_INPUT} \
conf/files \
conf/files.${cpu} \
conf/Makefile.template \
conf/Makefile.${cpu}
@cd ${CONFIG} && \
./make CONFIG=${CONFIG} \
CONFIG_SUFFIX=${CONFIG_SUFFIX} \
CONFIG_FLAGS=${CONFIG_FLAGS} \
-f Makefile.top-level \
make.config
${CONFIG}.mig mig: ./bin/mig ./lib/migcom
./bin ./lib ../bin ./src ./src/config ./src/mig:
mkdir $@
./bin/config: ./bin ./src ./src/config ALWAYS
@echo "[ generating $@ ]"
cd src/config && ${MAKE} ../../bin/config
./bin/mig: ./bin ./src ./src/mig ALWAYS
@echo "[ generating $@ ]"
cd src/mig && ${MAKE} DDIR=../../bin mig.install
./lib/migcom: ./lib ./src ./src/mig ALWAYS
@echo "[ generating $@ ]"
cd src/mig && ${MAKE} DDIR=../../lib migcom.install
./bin/buildconf: ./bin ./src
@echo "[ generating $@ ]"
cd src && ${MAKE} ../bin/buildconf
${CONFIG}/Makeconf:
@echo "[ generating $@ ]"
@-> $@
${CONFIG}/Makefile.top-level: Makefile
@echo "[ generating $@ ]"
@rm -f $@; cp -p Makefile $@
${CONFIG}/make: Makefile conf/make.template
@echo "[ generating $@ ]"
@-if [ -d ${CONFIG} ]; then true; else mkdir ${CONFIG}; fi
@sed -e 's;@OBJECTDIR@;${OBJECTDIR};g' -e 's;@VPATH@;${VPATH};g' \
< conf/make.template > [email protected]; \
chmod +x [email protected]; \
mv [email protected] $@; \
rm -f ${CONFIG}/pmake; \
ln $@ ${CONFIG}/pmake
${CONFIG_INPUT}: ${MASTER} ${MASTER_CPU} \
${MASTER_LOCAL} ${MASTER_CPU_LOCAL} \
Makefile conf/mkconfig.csh
@echo "[ generating $@ from ${MASTER_DIR}/MASTER{,.${cpu}}{,.local} ]"
@-if [ -d ${CONFIG} ]; then true; else mkdir ${CONFIG}; fi
@csh -f conf/mkconfig.csh ${CONFIG} ${MASTER} ${MASTER_CPU} ${MASTER_LOCAL} ${MASTER_CPU_LOCAL} >${CONFIG_INPUT}.tmp
@-if [ -s ${CONFIG_INPUT}.tmp ]; then \
if [ -f ${CONFIG_INPUT} ]; then \
diff ${CONFIG_INPUT} ${CONFIG_INPUT}.tmp; \
mv ${CONFIG_INPUT} ${CONFIG_INPUT}.old; \
fi; \
mv ${CONFIG_INPUT}.tmp ${CONFIG_INPUT}; \
else \
rm -f ${CONFIG_INPUT}.tmp; \
fi
make.config: ../${CONFIG_OUTPUT}${CONFIG_SUFFIX}
../${CONFIG_OUTPUT}${CONFIG_SUFFIX}: \
../${CONFIG_INPUT} \
$(SOURCE_DIR)/conf/files \
$(SOURCE_DIR)/conf/files.${cpu} \
$(SOURCE_DIR)/conf/Makefile.template \
$(SOURCE_DIR)/conf/Makefile.${cpu} \
./Makefile.top-level
@echo "[ configuring in ${CONFIG} ]"
../bin/config -c $(SOURCE_DIR)/conf ${CONFIG_FLAGS} ${CONFIG}
@echo ${CONFIG} >vers.config
@-if [ -d sys ] ; then true; else mkdir sys; fi
buildconf: ./bin/buildconf conf/buildconf.${cpu}
@-if [ "_${BUILDCONF}_" = "__" ]; then \
argv=`sed
argv=${BUILDCONF}; \
fi; \
exec ./bin/buildconf ${OPTIONS} $$argv
ALWAYS:
-include ${cpu}/Makefile.top-level
Lint the kernel
#
VAX_cpu=vax
IBMRT_cpu=ca
SUN3_cpu=sun3
MMAX_cpu=mmax
PMAX_cpu=mips
I386_cpu=i386
SUN4_cpu=sun4
AT386_cpu=i386
I860_cpu=i860
cpu=$(${TARGET_MACHINE}_cpu)
VAX_OUTPUT=Makefile
SUN3_OUTPUT=Makefile
IBMRT_OUTPUT=Makefile
MMAX_OUTPUT=Makefile
PMAX_OUTPUT=Makefile
I386_OUTPUT=Makefile
SUN4_OUTPUT=Makefile
AT386_OUTPUT=Makefile
I860_OUTPUT=Makefile
MASTER_DIR=conf
MASTER=${MASTER_DIR}/MASTER
MASTER_CPU=${MASTER}.${cpu}
MASTER_LOCAL=${MASTER_DIR}/MASTER.local
MASTER_CP./kernel/conf/ 755 146 0 0 4756607451 6353 ./kernel/conf/copyright 440 146 0 2000 4756607451 10355 /*
* Mach Operating System
* Copyright (c) 1991,1990,1989 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
* 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 [email protected]
* 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.
*/
./kernel/conf/MASTER 444 146 0 13337 4754020333 7365 #
# Mach Operating System
# Copyright (c) 1991,1990,1989,1988,1987,1986 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
# 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 [email protected]
# 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.
#
#
# HISTORY
# $Log: MASTER,v $
# Revision 2.6 91/02/05 17:01:58 mrt
# Changed to new copyright
# [91/01/28 14:45:37 mrt]
#
# Revision 2.5 91/01/08 15:08:42 rpd
# Removed FAST_CSW (tag fast_csw).
# [90/12/08 rpd]
# Removed MACH_IPC_GENNOS (tag ipc_gennos).
# [90/11/08 rpd]
#
# Revision 2.4 90/09/28 16:53:11 jsb
# Added preliminary NORMA support.
# [90/09/28 14:00:51 jsb]
#
# Revision 2.3 90/06/02 14:45:48 rpd
# Added MACH_VM_DEBUG (tag vm_debug) and added it to STD.
# [90/04/20 rpd]
# Converted to new IPC.
# Cleaned up, removing timezone, maxusers, etc.
# [90/03/26 21:33:20 rpd]
#
#
# Condensed history:
# MACH_KERNEL version (dbg).
# Changes for cleanup (gm0w).
# Made STD config be small (mrt).
#
#######################################################################
#
# Master machine independent configuration file.
#
# Specific configuration files are created based on this and
# the machine specific master file using the doconf script.
#
# Any changes to the master configuration files will affect all
# other configuration files based upon it.
#
#######################################################################
#
# To build a configuration, execute "doconf
# Configurations are specified in the "Configurations:" section
# of the MASTER and MASTER.* files as follows:
#
#
#
# Lines in the MASTER and MASTER.* files are selected based on
# the attribute selector list, found in a comment at the end of
# the line. This is a list of attributes separated by commas.
# The "!" operator selects the line if none of the attributes are
# specified.
#
# For example:
#
#
# selects a line if neither "foo" nor "bar" is
# specified.
#
# Lines with no attributes specified are selected for all
# configurations.
#
#######################################################################
#
# STANDARD CONFIGURATION OPTIONS (select any combination)
#
# debug = kernel level debugging support
# mdebug = enable debugging kernel calls
# ldebug = check use of simple locks on uniprocessors
# assert = enable assertions
#
# EXPERIMENTAL CONFIGURATION OPTIONS (select any combination, carefully)
#
# simple = non-rollover clock support
# timing = precision timing support
# host = host resource control support
# pm = paged-out page map hints
# fixpri = fixed priority threads
# clport = cluster ports (netport among cluster of processors)
# clboot = boot cluster of processors via master/slave arrangement
#
# MULTI-PROCESSOR CONFIGURATION (select at most one)
#
# multi16 = enable 16 multi-processors
# multi32 = enable 32 multi-processors
# multi64 = enable 64 multi-processors
#
#######################################################################
#
#
# Standard CMU CS/RI Production Configuration Components:
# -------- --- -- -- ---------- ------------- ----------
#
# STD = [ debug mdebug ipc_compat ipc_debug vm_debug ]
#
# (Optional for multi-processor configurations)
#
# 64 = [ multi64 host ]
# 32 = [ multi32 host ]
# 16 = [ multi16 host ]
#
# (Normally not enabled because of correctness or performance concerns)
#
# EXP = [ pm ]
# NORMA = [ clport clboot ]
#
# (Useful for testing, but may cause significant performance degradation)
#
# TEST = [ assert ldebug ipc_test ]
#
#######################################################################
#
ident CMU
options MACH # Standard Mach features
options MACH_KERNEL # Standalone MACH kernel
options MACH_ASSERT # Compile in assertions #
options MACH_DEBUG # IPC debugging interface #
options MACH_FIXPRI # Fixed priority threads #
options MACH_HOST # Mach host (resource alloc.) #
options MACH_IPC_COMPAT # Enable old IPC interface #
options MACH_IPC_DEBUG # Enable IPC debugging calls #
options MACH_IPC_TEST # Testing code/printfs #
options MACH_KDB # Kernel debugger support #
options MACH_LDEBUG # Sanity-check simple locking #
options MACH_PAGEMAP # Paged-out page map hints #
options MACH_CLPORT # cluster port support #
options MACH_CLBOOT # cluster booting support #
options MACH_VM_DEBUG # Enable VM debugging calls #
options HW_FOOTPRINT # Cache footprint support #
options SIMPLE_CLOCK # no hardware clock rollover #
options STAT_TIME # Use statistical timing #
options XPR_DEBUG # kernel tracing #
#
# Multi-processor selection
#
pseudo-device cpus 64 #
pseudo-device cpus 32 #
pseudo-device cpus 16 #
pseudo-device cpus 1 #
#
TD config be small (mrt).
#
#######################################################################
#
# Master machine independent configuration file.
#
# Specific configuration files are created based on this and
# the machine specific master file using the doconf script.
#
# Any changes./kernel/conf/MASTER.local 440 146 0 3706 4754020340 10427 #
# Mach Operating System
# Copyright (c) 1991,1990,1989,1988,1987,1986 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
# 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 [email protected]
# 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.
#
#
# HISTORY
# $Log: MASTER.local,v $
# Revision 2.3 91/02/05 17:02:20 mrt
# Changed to new copyright
# [91/01/28 14:45:58 mrt]
#
# Revision 2.2 90/06/02 14:45:52 rpd
# Converted to new IPC; cleaned up.
# [90/03/26 21:33:58 rpd]
#
#
# Condensed history:
# Random options come and go. Nothing interesting.
#
#######################################################################
#
# Master machine independent configuration file for a specific site.
#
# This file allows specific sites to easily maintain local
# configuration without touching the official Mach Master configuration
# files. All machine independent local options and configurations can
# (and should) be placed in this file.
#
# This version of the file is specific to the CMU CS/RI Facilities
# and should be replaced at each site.
#
#######################################################################
#
options CMUCS
options CMUCS_DISK # use cmu cs dept. disk partitions #
####################
#
# STANDARD CONFIGURATION OPTIONS (./kernel/conf/Makefile.template 444 146 0 44435 4754020356 11731 #
# Mach Operating System
# Copyright (c) 1991,1990,1989,1988,1987,1986 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
# 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 [email protected]
# 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.
#
#
# HISTORY
# $Log: Makefile.template,v $
# Revision 2.12 91/02/05 17:03:12 mrt
# Changed to new copyright
# [91/01/28 14:47:11 mrt]
#
# Revision 2.11 90/12/14 10:59:15 jsb
# Added rule for building dev_forward.c (for cross-node device support).
# [90/12/13 20:58:23 jsb]
#
# Revision 2.10 90/12/04 14:45:43 jsb
# Removed workaround for libmig.a; this can be worked around entirely
# in Makefile.{machine}.
# [90/12/04 11:37:33 jsb]
#
# Revision 2.9 90/11/25 17:48:22 jsb
# Added support for cross-compilation, using existing KCC technology:
# KCC is used to build images to be run on target machine (machine
# for which kernel is being built), and CC is used to build images
# to be run on host machine (machine upon which compilation is done).
# Use KCC (not CC) to build vers.o. Use CC (not KCC) to build genassym.
# Ignore errors from size command. Add workaround so that machine
# dependent makefile can choose to link kernel with LIBMIG_OBJS instead
# of with libmig.a, in case we don't have a working ranlib.
# This is all in support of building i860 kernels on i386.
# [90/11/25 16:46:51 jsb]
#
# Revision 2.8 90/11/05 14:25:27 rpd
# Added REG_EXP.
# [90/10/29 rwd]
#
# Revision 2.7 90/10/25 14:43:20 rwd
# Added explicit dependency for ds_routines.o.
# [90/10/18 rpd]
#
# Revision 2.6 90/08/27 21:46:33 dbg
# Remove symbols.raw from LDDEPS dependency list. Remove
# symbols.sort make rules. Remove ioconf.c from LINTFILES.
# Remove BSD license - this file was written entirely at CMU,
# using only features from the (public domain) src/config program.
# [90/08/13 dbg]
#
# Revision 2.5 90/06/19 22:57:19 rpd
# Replaced mach_user.c and mach_port_user.c with libmig.a.
# [90/06/03 rpd]
#
# Revision 2.4 90/06/02 14:46:37 rpd
# New style rules for default_pager_object.defs.
# [90/05/03 rpd]
# Don't barf if xstrip fails.
# [90/05/02 rpd]
#
# From jsb: don't rearrange symbols.
# Use xstrip instead of -x.
# [90/04/23 rpd]
# Added explicit rules for running mig.
# Moved generated dependencies to Makedep.
# [90/03/26 21:39:19 rpd]
#
# Revision 2.3 90/03/14 21:10:31 rwd
# Add default_pager_object.defs refs
# [90/01/22 rwd]
#
#
# Condensed history:
# Changes for MACH_KERNEL (dbg).
# Added mach_host.defs and related files (dlb).
# Mucho hacking at Mig rules (rpd).
# Lint hacking (mwyoung).
# New memory_object files (mwyoung).
# CPATH and -I hacking (mja, rpd).
# Running Mig in the build directory (mwyoung).
# VOLATILE hacking (rvb).
# Created from old Makefile.vax (mja).
# Reorganized for simplified config program (mja).
# Introduced new make depend stuff (rvb).
#
#
# This must be here before any rules are possibly defined by the
# machine dependent makefile fragment so that a plain "make" command
# always works. The config program will emit an appropriate rule to
# cause "all" to depend on every kernel configuration it generates.
#
default: all
#
# In order to move the link commands out of config and back into the
# template makefile, config has been changed to emit a dendency rule
# of the form *vmunix.sys: *vmunix.swap for each configuration so that
# the common commands for building each configuration can be placed
# directly in the template in the default rule for the .sys.swap
# dependency.
#
.SUFFIXES: .swap .sys
#
# Make sure we don't remove this by accident if interrupted at the wrong
# time.
#
.PRECIOUS: Makefile
#
# Compilation components
#
CC= cc
CPP= ${CC} -ES
C2= /lib/c2
LD= ld
MD= /usr/mach/bin/md
ENCODE= uuencode
DECODE= uudecode
VOLATILE="-Dvolatile="
FORCE_VOLATILE=
KCC= ${CC}
KCPP= ${KCC} -ES
#
# This changed in the 4.3 CPP from .n to .d
#
MD_SUFFIX=d
#
# Pre-processor environment
#
DEPENDS = -MD
INCLUDES =
DEFINES = $(IDENT) -DKERNEL
ALLOPTS = $(INCLUDES) $(DEFINES)
LINTOPTS = ${ALLOPTS} ${VOLATILE}
#
# Common C-compilation flags
#
COPTS_P = ${DEPENDS} ${ALLOPTS}
COPTS = ${COPTS_P}
CDEBUGFLAGS = -O
CMACHFLAGS =
CFLAGS= $(CDEBUGFLAGS) $(CMACHFLAGS) ${COPTS}
#
# Common assembly flags
#
SFLAGS= ${DEPENDS} ${INCLUDES} ${IDENT} -DKERNEL -DASSEMBLER
#
# Path name of the version identification file.
#
FEATURES=$(SOURCE_DIR)/machine/FEATURES.h
VERSION_FILES= \
$(SOURCE_DIR)/conf/version.major \
$(SOURCE_DIR)/conf/version.minor \
$(SOURCE_DIR)/conf/version.variant \
$(SOURCE_DIR)/conf/version.edit \
$(SOURCE_DIR)/conf/version.patch
#
# LDOBJS is the set of object files which comprise the kernel.
# It is used both in the dependency list for each *vmunix.swap
# rule emitted by config and also in the .sys.swap rule
# below which links the kernel from these objects.
#
# LDOBJS_PREFIX and LDOBJS_SUFFIX are defined in the machine
# dependent Makefile (if necessary).
#
LDOBJS=${LDOBJS_PREFIX} ${OBJS} ${LDOBJS_SUFFIX} libmig.a
#
# LDDEPS is the set of extra dependencies associated with each
# *vmunix.swap rule (in addition to $LDOBJS and the swap*.o file).
#
# LDDEPS_PREFIX is defined in the machine dependent Makefile
# (if necessary).
#
LDDEPS=${LDDEPS_PREFIX} ${VERSION_FILES} \
$(SOURCE_DIR)/conf/newvers.sh $(SOURCE_DIR)/conf/copyright
#
# PRELDDEPS is another set of extra dependencies associated with each
# *vmunix.swap rule (in addition to $LDOBJS and the swap*.o file).
# It is defined in the machine dependent Makefile (if necessary).
#
# The generated rule looks like
# vmunix.sys : ${PRELDDEPS} ${LDOBJS} ${LDDEPS}
#
#
# SWAPDEPS is the set of extra dependencies associated with each
# swap*.o rule emitted by config (in addition to the
# ../machine/swap*.c file).
#
# SWAPDEPS_PREFIX is defined in the machine dependent Makefile
# (if necessary).
#
SWAPDEPS=${SWAPDEPS_PREFIX}
#
# SYSDEPS is the set of extra dependencies associated with each
# *vmunix rule (in addition to *vmunix.sys).
#
# SYSDEPS_PREFIX is defined in the machine dependent Makefile
# (if necessary).
#
SYSDEPS=${SYSDEPS_PREFIX}
#
# Compilation rules to generate *vmunix from *vmunix.sys
#
SYS_RULE_1=@eval `awk 'NR==1{S=$$1;next;}\
END {\
C = "ln [email protected] $@";\
if (S != "") {\
C = C "; ln $@ $@" S; \
printf "rm -f $@%s; ", S; \
}\
printf "echo \"%s\"; %s\n", C, C; \
}' vers.suffix`
SYS_RULE_2=
SYS_RULE_3=
SYS_RULE_4=
#
# Things to be done just before exiting
#
EXIT_RULE=${MD} -u Makedep -f -d `ls *.${MD_SUFFIX}`
#
# Compilation rules to generate .o from .b
#
B_RULE_1A=rm -f $*.o; ${DECODE}
B_RULE_1B=$*.b
#
# Compilation rules to generate .o from .o
#
O_RULE_1A=rm -f $*.o; cp
O_RULE_1B=$*.o .
#
# Compilation rules to generate .o from .s
#
S_RULE_1A=${KCPP} ${SFLAGS}
S_RULE_1B=$*.s >$*.i
S_RULE_2=${AS} -o $*.o $*.i
S_RULE_3=rm -f $*.i
#
# Compilation rules to generate .o from .c for normal files
#
C_RULE_1A=${KCC} -c ${CFLAGS}
C_RULE_1B=$*.c
C_RULE_2=
C_RULE_3=
C_RULE_4=
#
# Compilation rules to generate .o from .c for driver files
#
C_RULE_1A_D=${C_RULE_1A}
C_RULE_1B_D=${C_RULE_1B}
C_RULE_2_D=${C_RULE_2}
C_RULE_3_D=${C_RULE_3}
C_RULE_4_D=${C_RULE_4}
#
# Compilation rules to generate .o from .c for profiling routine files
#
C_RULE_1A_P=${KCC} -c -S ${COPTS_P}
C_RULE_1B_P=${C_RULE_1B}
C_RULE_2_P=ex - $*.s < ${GPROF.EX}
C_RULE_3_P=${AS} -o $*.o $*.s
C_RULE_4_P=rm -f $*.s
gprof: kgmon_on all kgmon_off
kgmon_on:
kgmon -r -b
kgmon_off:
kgmon -h -p
gprof /mach >GPROF
#
# These macros are filled in by the config program depending on the
# current configuration. The MACHDEP macro is replaced by the
# contents of the machine dependent makefile template and the others
# are replaced by the corresponding symbol definitions for the
# configuration.
#
%OBJS
%CFILES
%SFILES
%BFILES
%ORDERED
%MACHDEP
#
# Default rule used to build a *vmunix.sys configuration from the
# object list and a particular *vmunix.swap module. The *vmunix.swap
# module is a normal object file compiled from the appropriate swap*.c
# file and then copied to the *vmunix.swap name to trigger the full
# kernel link using this default rule.
#
.swap.sys:
@/bin/sh $(SOURCE_DIR)/conf/newvers.sh \
$(SOURCE_DIR)/conf/copyright \
`cat ${VERSION_FILES}`
@${KCC} -c vers.c
@rm -f $* $*.sys
@echo loading $*.sys
@${LD} ${LDFLAGS} ${LDOBJS} vers.o $*.swap ${LIBS}
@echo stripping $*.sys
@-xstrip a.out
@-size a.out
@chmod 755 a.out
@-mv a.out $*.sys
#
# OBJSDEPS is the set of files (defined in the machine dependent
# template if necessary) which all objects depend on (such as an
# in-line assembler expansion filter
#
${OBJS}: ${OBJSDEPS}
#
# This macro is replaced by three rules per configuration, plus a
# final definition for the LOAD symbol consisting of all configuration
# names and a dependency of "all" on this symbol (so that the
# "default" rule above will build everything). The three rules in
# each configuration are:
#
# - a *vmunix from *vmunix.sys dependency using the SYS_RULE_* rules,
# - a *vmunix.swap from LDDEPS, swap*.o, and LDDEPS dependency that
# simply copies the swap file to the target name, and
# - a swap*.o from swap*.c and SWAPDEPS dependency using the C_RULE_* rules.
#
%LOAD
#
# Rules for components which are not part of the kernel proper or that
# need to be built in a special manner.
#
genassym.o: $(SOURCE_DIR)/machine/genassym.c
${CC} -c ${COPTS_P} ${VOLATILE} $(SOURCE_DIR)/machine/genassym.c
assym.s: genassym.o
${CC} genassym.o
./a.out > assym.s; rm -f a.out
locore.o: assym.s ${LOCORE_HEADS}
#
# Mach IPC-based interfaces
#
# Explicit dependencies on generated files,
# to ensure that Mig has been run by the time
# these files are compiled.
vm_pageout.o: mach/memory_object_user.h mach/memory_object_default.h
vm_object.o: mach/memory_object_user.h mach/memory_object_default.h
vm_fault.o: mach/memory_object_user.h
memory_object.o: mach/memory_object_user.h
exception.o: mach/exc.h
bootstrap.o: mach/mach_interface.h mach/mach_user_internal.h \
mach/mach_port_internal.h
default_pager.o: device/device.h mach/mach_user_internal.h \
mach/mach_port_internal.h mach/memory_object_server.c \
mach/memory_object_default_server.c \
mach/default_pager_object_server.c
def_pager_setup.o : mach/mach_interface.h mach/mach_user_internal.h \
mach/mach_port_internal.h
load.o : mach/mach_interface.h mach/mach_user_internal.h \
mach/mach_port_internal.h
sasys.o : mach/mach_interface.h mach/mach_user_internal.h device/device.h \
mach/mach_port_internal.h
dev_pager.o : device/device_pager_server.c
boot_printf.o : mach/mach_user_internal.h mach/mach_port_internal.h
ds_routines.o : device/device_reply.h
# The Mig-generated files go into subdirectories.
# These macros create the subdirectories as they are needed.
MAKE_MACH = [ -d mach ] || mkdir mach
MAKE_MACH_DEBUG = [ -d mach_debug ] || mkdir mach_debug
MAKE_DEVICE = [ -d device ] || mkdir device
MIGFLAGS = -DKERNEL
MIGKSFLAGS = $(MIGFLAGS) -DKERNEL_SERVER
MIGKUFLAGS = $(MIGFLAGS) -DKERNEL_USER
MIGDEPS = ../bin/mig ../lib/migcom
MIG = PATH=../bin:$$PATH LPATH=../lib:$$LPATH mig
MACHDIR = mach/
MACH_FUNCS = thread_resume thread_create task_create task_set_special_port \
vm_set_default_memory_manager vm_allocate vm_deallocate \
vm_write vm_protect vm_pageable \
memory_object_data_provided memory_object_data_unavailable \
memory_object_data_error memory_object_set_attributes
MACH_FFILES = $(MACH_FUNCS/$(REG_EXP)/$(MACHDIR)&.c)
MACH_FILES = mach/mach_interface.h mach/mach_user_internal.h \
mach/mach_server.c $(MACH_FFILES)
$(MACH_FILES): $(MIGDEPS) $(SOURCE_DIR)/mach/mach.defs
-$(MAKE_MACH)
$(MIG) -MD $(MIGKSFLAGS) -header mach/mach_interface.h -i mach/ -server mach/mach_server.c -iheader mach/mach_user_internal.h $(SOURCE_DIR)/mach/mach.defs
MACH_PORT_FUNCS = mach_port_allocate mach_port_destroy \
mach_port_insert_right mach_port_move_member
MACH_PORT_FFILES = $(MACH_PORT_FUNCS/$(REG_EXP)/$(MACHDIR)&.c)
MACH_PORT_FILES = mach/mach_port_interface.h mach/mach_port_internal.h \
mach/mach_port_server.c $(MACH_PORT_FFILES)
$(MACH_PORT_FILES): $(MIGDEPS) $(SOURCE_DIR)/mach/mach_port.defs
-$(MAKE_MACH)
$(MIG) -MD $(MIGKSFLAGS) -header mach/mach_port_interface.h -i mach/ -server mach/mach_port_server.c -iheader mach/mach_port_internal.h $(SOURCE_DIR)/mach/mach_port.defs
MEMORY_OBJECT_FILES = mach/memory_object_user.h \
mach/memory_object_user.c mach/memory_object_server.c
$(MEMORY_OBJECT_FILES): $(MIGDEPS) $(SOURCE_DIR)/mach/memory_object.defs
-$(MAKE_MACH)
$(MIG) -MD $(MIGKUFLAGS) -header mach/memory_object_user.h -user mach/memory_object_user.c -server mach/memory_object_server.c $(SOURCE_DIR)/mach/memory_object.defs
MEMORY_OBJECT_DEFAULT_FILES = mach/memory_object_default.h \
mach/memory_object_default_user.c \
mach/memory_object_default_server.c
$(MEMORY_OBJECT_DEFAULT_FILES): $(MIGDEPS) $(SOURCE_DIR)/mach/memory_object_default.defs
-$(MAKE_MACH)
$(MIG) -MD $(MIGKUFLAGS) -header mach/memory_object_default.h -user mach/memory_object_default_user.c -server mach/memory_object_default_server.c $(SOURCE_DIR)/mach/memory_object_default.defs
EXC_FILES = mach/exc.h mach/exc_user.c mach/exc_server.c
$(EXC_FILES): $(MIGDEPS) $(SOURCE_DIR)/mach/exc.defs
-$(MAKE_MACH)
$(MIG) -MD $(MIGKUFLAGS) -header mach/exc.h -user mach/exc_user.c -server mach/exc_server.c $(SOURCE_DIR)/mach/exc.defs
DEVKUSER_FILES = mach/dev_forward.c
$(DEVKUSER_FILES): $(MIGDEPS) $(SOURCE_DIR)/device/device.defs
-$(MAKE_MACH)
$(MIG) -MD $(MIGKUFLAGS) -header mach/dev_forward.h -user mach/dev_forward.c -server /dev/null $(SOURCE_DIR)/device/dev_forward.defs
MACH_HOST_FILES = mach/mach_host_server.c
$(MACH_HOST_FILES): $(MIGDEPS) $(SOURCE_DIR)/mach/mach_host.defs
-$(MAKE_MACH)
$(MIG) -MD $(MIGKSFLAGS) -header /dev/null -user /dev/null -server mach/mach_host_server.c $(SOURCE_DIR)/mach/mach_host.defs
MACH_DEBUG_FILES = mach_debug/mach_debug_server.c
$(MACH_DEBUG_FILES): $(MIGDEPS) $(SOURCE_DIR)/mach_debug/mach_debug.defs
-$(MAKE_MACH_DEBUG)
$(MIG) -MD $(MIGKSFLAGS) -header /dev/null -user /dev/null -server mach_debug/mach_debug_server.c $(SOURCE_DIR)/mach_debug/mach_debug.defs
DEVICE_FILES = device/device.h device/device_server.c device/device_user.c
$(DEVICE_FILES): $(MIGDEPS) $(SOURCE_DIR)/device/device.defs
-$(MAKE_DEVICE)
$(MIG) -MD $(MIGKSFLAGS) -header device/device.h -user device/device_user.c -server device/device_server.c $(SOURCE_DIR)/device/device.defs
DEVICE_REPLY_FILES = device/device_reply.h device/device_reply_user.c
$(DEVICE_REPLY_FILES): $(MIGDEPS) $(SOURCE_DIR)/device/device_reply.defs
-$(MAKE_DEVICE)
$(MIG) -MD $(MIGKUFLAGS) -header device/device_reply.h -user device/device_reply_user.c -server /dev/null $(SOURCE_DIR)/device/device_reply.defs
DEVICE_PAGER_FILES = device/device_pager_server.c
$(DEVICE_PAGER_FILES): $(MIGDEPS) $(SOURCE_DIR)/mach/memory_object.defs
-$(MAKE_DEVICE)
$(MIG) -MD $(MIGKSFLAGS) -header /dev/null -user /dev/null -server device/device_pager_server.c $(SOURCE_DIR)/mach/memory_object.defs
DEFAULT_PAGER_OBJECT_FILES = mach/default_pager_object_server.c
$(DEFAULT_PAGER_OBJECT_FILES): $(MIGDEPS) $(SOURCE_DIR)/mach/default_pager_object.defs
-$(MAKE_MACH)
$(MIG) -MD $(MIGFLAGS) -header /dev/null -user /dev/null -server mach/default_pager_object_server.c $(SOURCE_DIR)/mach/default_pager_object.defs
LIBMIG_OBJS = $(MACH_FUNCS/$(REG_EXP)/&.o) $(MACH_PORT_FUNCS/$(REG_EXP)/&.o)
$(LIBMIG_OBJS): mach/$$(@:r).c
$(KCC) -c $(CFLAGS) mach/$*.c
libmig.a: $(LIBMIG_OBJS)
rm -f libmig.a
ar cq libmig.a $(LIBMIG_OBJS)
ranlib libmig.a
# Update the Makefile when any dependency files exist rather than only
# when they are newer than the makefile (since it often gets touched
# during reconfigurations when dependency files have yet to be
# integrated). The makefile is copied before doing any potential
# integration so that the new and old versions can be compared when
# done (by the SYS_RULE_* rules) to prevent re-building things when no
# dependencies change.
#
# N.B. There is always an empty artificial dependency file M.d
# (created by config) which will never be integrated and simply
# prevents the wild-card expansion below from failing.
#
# The default exit rule now brings the Makefile up to date, so it
# shouldn't be necessary to execute this rule manually.
#
Makedep: *.${MD_SUFFIX}
${EXIT_RULE}
.EXIT:
${EXIT_RULE}
depend:
@echo you don\'t make depend any more.
#
# Permit manually forced checkout of modules when the dependency
# information is not current.
#
checkout: ${USE}
#
# Clean up the current build directory.
#
clean:
@for f in ${LOAD}; do echo rm -f $$f $$f.* && rm -f $$f $$f.*; done
rm -f eddep tags *.o locore.i \
errs linterrs makelinks *.log *LOG* ${CLEAN_EXTRA}
#
# Run "lint" on the current build directory. This will often be done
# with a special configuration that defines the union of all options
# used in all configurations so that all combinations are checked.
# The LINTFILES variable allows lint to be easily run on an optional
# sub-set of files specified on the make command line when this is
# desired.
#
LINTFILES=$(SOURCE_DIR)/machine/Locore.c \
${CFILES} \
$(SOURCE_DIR)/machine/swapgeneric.c
lint: ALWAYS assym.s
@lint -n -hbxn -DGENERIC ${LINTOPTS} ${LINTFILES} | \
egrep -v 'struct/union .* never defined' | \
egrep -v 'possible pointer alignment problem'
ALWAYS:
MACHINEDIR=$(SOURCE_DIR)/machine
#
# This macro is replaced by the set of rules which build everything in
# OBJS. The extra dependencies for each object file are inserted
# following this by md which uses the keys on the sentinel line
# below.
#
%RULES
-include Makedep
rward.defs
MACH_HOST_FILES = mach/mach_host_server.c
$(MACH_HOST_FILES): $(MIGDEPS) $(SOURCE_DIR)/mach/mach_host.defs
-$(MAKE_MACH)
$(MIG) -MD $(MIGKSFLAGS) -header /dev/null -user /dev/null -server mach/mach_host_server.c ./kernel/conf/version.edit 440 146 0 3 4756607447 10704 42
CS/$(REG_EXP)/&.o) $(MACH_PORT_FUNCS/$(REG_EXP)/&.o)
$(LIBMIG_OBJS): mach/$$(@:r).c
$(KCC) -c $(CFLAGS) mach/$*.c
libmig.a: $(LIBMIG_OBJS)
rm -f libmig.a
ar cq libmig.a $(LIBMIG_OBJS)
ranlib libmig.a
# Update the Makefile when any dependency files exist rather than only
# when they are newer than the makefile (since it often gets touched
# during reconfigurations when dependency files have yet to be
# integrated). The makefile is copied before doing any potential
# integration so that the ne./kernel/conf/files 444 146 0 15134 4754020366 7477 #
# Mach Operating System
# Copyright (c) 1991,1990,1989 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
# 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 [email protected]
# 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.
#
#
# HISTORY
# $Log: files,v $
# Revision 2.14 91/02/05 17:05:09 mrt
# Removed /device/subr_rmap.c since it is only
# needed by some machine types.
# [91/01/25 mrt]
#
# Revision 2.13 91/01/08 15:08:55 rpd
# Removed ./mach/exc_user.c.
# [90/12/26 rpd]
# Removed FAST_CSW.
# [90/12/08 rpd]
# Removed MACH_IPC_GENNOS.
# [90/11/08 rpd]
#
# Revision 2.12 90/12/14 10:59:21 jsb
# Added ./mach/dev_forward.c (for cross-node device support).
# [90/12/14 08:26:07 jsb]
#
# Revision 2.11 90/10/25 14:43:27 rwd
# Added ddb/db_watch.c.
# [90/10/16 rpd]
#
# Revision 2.10 90/09/28 16:53:17 jsb
# Added preliminary NORMA support.
# [90/09/28 14:01:11 jsb]
#
# Revision 2.9 90/08/27 21:46:58 dbg
# Add debugger support for multiple symbol tables and different
# formats (ddb/db_aout.c).
# [90/08/17 dbg]
# Switch to new kernel debugger (ddb).
# [90/07/20 dbg]
#
# Remove sasys.c. Add file_io.c.
# [90/07/17 dbg]
#
# Remove clist.c and ufs_dsort.c. Add cirbuf.c.
# [90/07/09 dbg]
#
# Revision 2.8 90/06/19 22:57:29 rpd
# Removed mach_user.c, mach_port_user.c.
# [90/06/03 rpd]
#
# Revision 2.7 90/06/02 14:46:48 rpd
# Added kdb/kdb_aout.c.
# [90/05/11 16:47:17 rpd]
#
# Added MACH_VM_DEBUG, vm/vm_debug.c.
# [90/04/20 rpd]
# Converted to new IPC.
# Removed mdb files.
# Updated options to agree with MASTER.
# [90/03/26 21:40:35 rpd]
#
#
# Condensed history:
# Changes for MACH_KERNEL (dbg, rwd).
# Changes for new scheduling code (dlb).
# Created mach directory (rpd).
# Options cleanup (mwyoung).
# Split up IPC files (rpd).
# Added MACH and CMUCS options (mja).
# Cleaned up, removed old history (avie).
#
#
# N.B. "kern/lock.c" is listed as "optional cpus" so that config will
# create a "cpus.h" file.
#
OPTIONS/cmucs_disk optional cmucs_disk
OPTIONS/dli optional dli
OPTIONS/mach_assert optional mach_assert
OPTIONS/mach_debug optional mach_debug
OPTIONS/mach_clport optional mach_clport
OPTIONS/mach_clboot optional mach_clboot
OPTIONS/mach_fixpri optional mach_fixpri
OPTIONS/mach_host optional mach_host
OPTIONS/mach_ipc_compat optional mach_ipc_compat
OPTIONS/mach_ipc_debug optional mach_ipc_debug
OPTIONS/mach_ipc_test optional mach_ipc_test
OPTIONS/mach_kdb optional mach_kdb
OPTIONS/mach_ldebug optional mach_ldebug
OPTIONS/mach_pagemap optional mach_pagemap
OPTIONS/mach_vm_debug optional mach_vm_debug
OPTIONS/hw_footprint optional hw_footprint
OPTIONS/simple_clock optional simple_clock
OPTIONS/stat_time optional stat_time
OPTIONS/xpr_debug optional xpr_debug
ddb/db_access.c optional mach_kdb
ddb/db_aout.c optional mach_kdb
ddb/db_break.c optional mach_kdb
ddb/db_command.c optional mach_kdb
ddb/db_examine.c optional mach_kdb
ddb/db_expr.c optional mach_kdb
ddb/db_input.c optional mach_kdb
ddb/db_lex.c optional mach_kdb
ddb/db_output.c optional mach_kdb
ddb/db_print.c optional mach_kdb
ddb/db_run.c optional mach_kdb
ddb/db_sym.c optional mach_kdb
ddb/db_trap.c optional mach_kdb
ddb/db_variables.c optional mach_kdb
ddb/db_watch.c optional mach_kdb
ddb/db_write_cmd.c optional mach_kdb
ipc/ipc_clport.c optional mach_clport
ipc/ipc_entry.c standard
ipc/ipc_hash.c standard
ipc/ipc_init.c standard
ipc/ipc_kmsg.c standard
ipc/ipc_marequest.c standard
ipc/ipc_mqueue.c standard
ipc/ipc_notify.c standard
ipc/ipc_object.c standard
ipc/ipc_port.c standard
ipc/ipc_pset.c standard
ipc/ipc_right.c standard
ipc/ipc_space.c standard
ipc/ipc_splay.c standard
ipc/ipc_table.c standard
ipc/ipc_thread.c standard
ipc/mach_debug.c optional mach_ipc_debug
ipc/mach_msg.c standard
ipc/mach_port.c standard
kern/ast.c standard
kern/bootstrap.c standard
kern/debug.c standard
kern/exception.c standard
kern/host.c standard
kern/ipc_host.c standard
kern/ipc_kobject.c standard
kern/ipc_mig.c standard
kern/ipc_sched.c standard
kern/ipc_tt.c standard
kern/kalloc.c standard
kern/lock.c optional cpus
kern/mach_clock.c standard
kern/mach_factor.c standard
kern/machine.c standard
kern/printf.c standard
kern/priority.c standard
kern/processor.c standard
kern/queue.c standard
kern/sched_prim.c standard device-driver |${VOLATILE}
kern/startup.c standard
kern/syscall_emulation.c standard
kern/syscall_subr.c standard
kern/syscall_sw.c standard
kern/task.c standard
kern/thread.c standard
kern/thread_swap.c standard
kern/time_stamp.c standard
kern/timer.c standard
kern/xpr.c optional xpr_debug
kern/zalloc.c standard
./mach/mach_host_server.c standard
./mach/mach_port_server.c standard
./mach/mach_server.c standard
./mach/memory_object_default_user.c standard
./mach/memory_object_user.c standard
./mach_debug/mach_debug_server.c optional mach_debug
./mach/dev_forward.c optional mach_clboot
vm/memory_object.c standard
vm/vm_debug.c optional mach_vm_debug
vm/vm_fault.c standard
vm/vm_init.c standard
vm/vm_kern.c standard
vm/vm_map.c standard
vm/vm_object.c standard
vm/vm_pageout.c standard
vm/vm_resident.c standard
vm/vm_user.c standard
device/blkio.c standard
device/chario.c standard
device/cirbuf.c standard
device/dev_lookup.c standard
device/dev_name.c standard
device/dev_pager.c standard
./device/device_reply_user.c standard
./device/device_server.c standard
./device/device_user.c standard
device/device_init.c standard
device/ds_routines.c standard
device/net_io.c standard
device/subrs.c standard
boot_ufs/boot_printf.c standard
boot_ufs/default_pager.c standard
boot_ufs/def_pager_setup.c standard
boot_ufs/file_io.c standard
boot_ufs/load.c standard
./ioconf.c standard
ptions cleanup (mwyoung).
# Split up IPC files (rpd).
# Added MACH and CMUCS options (mja).
# Cleaned up, removed old history (avie).
#
#
# N.B. "kern/lock.c" is listed as "optional cpus" so that config will
# create a "cpus.h" file.
#
OPTIONS/cmucs_disk optional cmucs_disk
OPTIONS/dli optional dli
OPTIONS/mach_assert optional mach_assert
OPTIONS/mach_debug optional mach_debug
OPTIONS/mach_clport optional mac./kernel/conf/fixsyms 555 146 0 1134 4466402630 10053 #! /bin/sh
#
# fixsyms [file] [outfile]
#
# clean up ncs symbols
#
rmfile=
case "$1" in
"")
file=/tmp/$$fixsym
rmfile="rm -f $file"
cat $1 > $file
;;
*)
file=$1
;;
esac
if egrep -s '_\.' $file
then
awk '
#
# script to fix up the output from nm by replacing
# all symbols _x where a _.x exists.
#
# input is of form
# $1 $2 $3
# address letter symbol
#
#
$2 == "T" && $3 ~ /^_\./ {
name= "_" substr($3,3)
names[name] = $1
next
}
names[$3] != "" {
next
}
{
names[$3] = $1
}
END {
for (i in names)
print names[i], "=", i
}
' $file | sort
else
cat $file
fi >$2
eval "$rmfile"
file=/tmp/$$fixsym
rmfile="rm -f $file"
cat $1 > $file
;;
*)
file=$1
;;
esac
if egrep -s '_\.' $file
then
awk '
#
# script to fix up the output from nm by replacing
# all symbols _x where a _.x exists.
#
# input is of form
# $1 $2 $3
# address letter symbol
#
#
$2 == "T" && $3 ~ /^_\./ {
name= "_" substr($3,3)
names[name] = $1
next
}
names[$3] != "" {
next
}
{
names[$3] = $1
}
END {
for (i ./kernel/conf/make.template 444 146 0 3773 4754020375 11112 #!/bin/csh -f
#
# Mach Operating System
# Copyright (c) 1991,1990,1989 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
# 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 [email protected]
# 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.
#
#
# HISTORY
# $Log: make.template,v $
# Revision 2.2 91/02/05 17:05:33 mrt
# Changed to new copyright
# [91/01/28 14:48:03 mrt]
#
# Revision 2.1 89/08/03 17:37:53 rwd
# Created.
#
# Revision 2.2 89/04/22 15:24:02 gm0w
# Created from root Makefile.
# [89/04/14 gm0w]
#
if ( { \[ -z "@OBJECTDIR@" \] } ) then
set dirs=(`echo ..:@VPATH@ | sed -e "s;:; ;"`)
else
set dirs=(`echo ../@VPATH@ | sed -e "s;:; ;"`)
endif
unsetenv MAKEDIR MAKEPSD MAKECWD OBJECTDIR
if ($#dirs == 1 && $?USE_SOURCE_DIR) then
setenv CPATH ":${dirs}"
unsetenv VPATH
set src="SOURCE_DIR=${dirs}"
else
setenv CPATH ""
setenv VPATH ""
set c=""
foreach d ($dirs)
setenv CPATH "${CPATH}:${d}"
setenv VPATH "${VPATH}${c}${d}/conf"
set c=":"
end
set src=""
endif
set prog=$0
set prog=$prog:t
set makeargs=(-c)
if ("$prog" == "pmake") set makeargs=""
set newprog=(`wh $prog | fgrep -v -x "./$prog" | fgrep -v -x "$prog" | head -1`)
exec $newprog $makeargs:q $src:q $*:q
dent../kernel/conf/mkconfig.csh 444 146 0 5040 4754020377 10723 #!/bin/csh -f
#
# Mach Operating System
# Copyright (c) 1991,1990,1989 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
# 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 [email protected]
# 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.
#
#
# HISTORY
# $Log: mkconfig.csh,v $
# Revision 2.2 91/02/05 17:05:36 mrt
# Changed to new copyright
# [91/01/28 14:48:06 mrt]
#
# Revision 2.1 89/08/03 17:38:16 rwd
# Created.
#
# Revision 2.2 89/04/22 15:24:08 gm0w
# Created from root Makefile.
# [89/04/14 gm0w]
#
set CONFIG="${argv[1]}"
shift argv
echo +${CONFIG} \
| \
cat ${argv} - ${argv} \
| \
sed -n \
-e "/^+/{" \
-e "s;[-+];#&;gp" \
-e 't loop' \
-e ': loop' \
-e 'n' \
-e '/^#/b loop' \
-e '/^$/b loop' \
-e 's;^\([^#]*\).*#[ ]*<\(.*\)>[ ]*$;\2#\1;' \
-e 't not' \
-e 's;\([^#]*\).*;#\1;' \
-e 't not' \
-e ': not' \
-e 's;[ ]*$;;' \
-e 's;^\!\(.*\);\1#\!;' \
-e 'p' \
-e 't loop' \
-e 'b loop' \
-e '}' \
-e "/^[^#]/d" \
-e 's; ; ;g' \
-e "s;^# *\([^ ]*\)[ ]*=[ ]*\[\(.*\)\].*;\1#\2;p" \
| \
awk '-F#' '\
part == 0 && $1 != "" {\
m[$1]=m[$1] " " $2;\
next;\
}\
part == 0 && $1 == "" {\
for (i=NF;i>1;i--){\
s=substr($i,2);\
c[++na]=substr($i,1,1);\
a[na]=s;\
}\
while (na > 0){\
s=a[na];\
d=c[na--];\
if (m[s] == "") {\
f[s]=d;\
} else {\
nx=split(m[s],x," ");\
for (j=nx;j>0;j--) {\
z=x[j];\
a[++na]=z;\
c[na]=d;\
}\
}\
}\
part=1;\
next;\
}\
part != 0 {\
if ($1 != "") {\
n=split($1,x,",");\
ok=0;\
for (i=1;i<=n;i++) {\
if (f[x[i]] == "+") {\
ok=1;\
}\
}\
if (NF > 2 && ok == 0 || NF <= 2 && ok != 0) {\
print $2; \
}\
} else { \
print $2; \
}\
}'
ard
device/blkio.c standard
device/chario.c standard
device/cirbuf.c standard
device/dev_lookup.c standard
device/dev_name.c standard
device/dev_pager.c standard
./device/device_reply_user.c standard
./device/device_server.c standard
./device/device_user.c standard
device/device_init.c standard
device/ds_routines.c standard
device/net_io.c standard
device/subrs.c standard
boot_ufs/boot_printf.c standard
boot_ufs/default_pager.c standard
boot_ufs/def_pager_set./kernel/conf/newvers.sh 444 146 0 4617 4754020400 10450 #!/bin/sh -
#
# Mach Operating System
# Copyright (c) 1991,1990,1989 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
# 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 [email protected]
# 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.
#
#
# HISTORY
# $Log: newvers.sh,v $
# Revision 2.5 91/02/05 17:05:40 mrt
# Changed to new copyright
# [91/01/28 14:48:14 mrt]
#
# Revision 2.4 90/09/14 12:56:01 rwd
# Dont printout major.minor in VERSION string.
# [90/09/14 rwd]
#
# Revision 2.3 90/08/27 21:48:12 dbg
# Document that this file was created at CMU.
# [90/07/13 dbg]
#
# Revision 2.2 89/11/29 14:08:47 af
# Use Mach version id.
#
# Revision 2.1 89/08/03 17:38:33 rwd
# Created.
#
#
# newvers.sh copyright major minor variant edit patch
#
edit="$5"; major="$2"; minor="$3"; variant="$4"; patch="$6"; copyright="$1"
v="VERSION(${variant}${edit}${patch})" d=`pwd` h=`hostname` t=`date`
if [ -z "$d" -o -z "$h" -o -z "$t" ]; then
exit 1
fi
CONFIG=`expr "$d" : '.*/\([^/]*\)$'`
d=`expr "$d" : '.*/\([^/]*/[^/]*\)$'`
(
/bin/echo "int version_major = ${major};" ;
/bin/echo "int version_minor = ${minor};" ;
/bin/echo "char version_variant[] = \"${variant}\";" ;
/bin/echo "char version_patch[] = \"${patch}\";" ;
/bin/echo "int version_edit = ${edit};" ;
/bin/echo "char version[] = \"Mach 3.0 ${v}: ${t}; $d ($h)\\n\";" ;
/bin/echo "char cmu_copyright[] = \"\\" ;
sed <$copyright -e '/^#/d' -e 's;[ ]*$;;' -e '/^$/d' -e 's;$;\\n\\;' ;
/bin/echo "\";";
) > vers.c
if [ -s vers.suffix -o ! -f vers.suffix ]; then
echo ".${variant}${edit}${patch}.${CONFIG}" >vers.suffix
fi
exit 0
'-F#' '\
part == 0 && $1 != "" {\
m[$1]=m[$1] " " $2;\
next;\
}\
part == 0 && $1 == "" {\
for (i=NF;./kernel/conf/version.major 440 146 0 2 4674206002 11043 3
: newvers.sh,v $
# Revision 2.5 91/02/05 17:05:40 mrt
# Changed to new copyright
# [91/01/28 14:48:14 mrt]
#
# Revision 2.4 90/09/14 12:56:01 rwd
# Dont printout major.minor in VERSION string.
# [90/09/14 rwd]
#
# Revision 2.3 90/08/27 21:48:12 dbg
# Document that this file was created at CMU.
# [90/07/13 dbg]
#
# Revision 2.2 89/11/29 14:08:47 af
# Use Mach version id.
#
# Revision 2.1 89/08/03 17:38:33 rwd
# Created.
#
#
# newvers.sh copyright major mi./kernel/conf/version.minor 440 146 0 2 4466402635 11070 0
: newvers.sh,v $
# Revision 2.5 91/02/05 17:05:40 mrt
# Changed to new copyright
# [91/01/28 14:48:14 mrt]
#
# Revision 2.4 90/09/14 12:56:01 rwd
# Dont printout major.minor in VERSION string.
# [90/09/14 rwd]
#
# Revision 2.3 90/08/27 21:48:12 dbg
# Document that this file was created at CMU.
# [90/07/13 dbg]
#
# Revision 2.2 89/11/29 14:08:47 af
# Use Mach version id.
#
# Revision 2.1 89/08/03 17:38:33 rwd
# Created.
#
#
# newvers.sh copyright major mi./kernel/conf/version.patch 440 146 0 0 4466402640 11035 ./kernel/conf/version.variant 440 146 0 3 4716106164 11405 MK
newvers.sh,v $
# Revision 2.5 91/02/05 17:05:40 mrt
# Changed to new copyright
# [91/01/28 14:48:14 mrt]
#
# Revision 2.4 90/09/14 12:56:01 rwd
# Dont printout major.minor in VERSION string.
# [90/09/14 rwd]
#
# Revision 2.3 90/08/27 21:48:12 dbg
# Document that this file was created at CMU.
# [90/07/13 dbg]
#
# Revision 2.2 89/11/29 14:08:47 af
# Use Mach version id.
#
# Revision 2.1 89/08/03 17:38:33 rwd
# Created.
#
#
# newvers.sh copyright major mi./kernel/conf/MASTER.i386 444 146 0 12730 4754020334 10052 #
# Mach Operating System
# Copyright (c) 1991,1990,1989 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
# 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 [email protected]
# 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.
#
#
# HISTORY
# $Log: MASTER.i386,v $
# Revision 2.10 91/02/05 17:02:04 mrt
# Changed to new copyright
# [91/01/28 14:45:43 mrt]
#
# Add 3com 3c501 ether [bernadat]
# Add @ to
# [90/02/28 rvb]
# You must "config" vmunix, mach has nasty side effects.
# SWAPSYS must be @ not to have (null command) complaint.
# [90/01/23 rvb]
# SWAPSYS is not coff only.
# [90/01/02 13:55:45 rvb]
#
# Flush makevariables LIBS=...-gnulib
# [89/12/26 rvb]
# Define WS configuration.
# Make "coff" configuration for kernel vs a.out.
# [89/12/21 17:10:46 rvb]
#
# Bring back optimization.
# [89/09/26 rvb]
#
# Revision 2.9 91/01/08 17:31:45 rpd
# Switch wd8003 -> ns8390
# [91/01/04 12:13:52 rvb]
#
# Revision 2.8 90/12/04 14:45:30 jsb
# Eliminated ipsc2 in favor of ipsc or ipsc386 where appropriate.
# [90/12/04 11:38:51 jsb]
#
# Revision 2.7 90/11/26 14:48:29 rvb
# Put com back. kd_mouse needs it.
# [90/11/26 11:20:42 rvb]
#
# Revision 2.6 90/11/24 15:14:36 jsb
# Added support for i386ipsc2 cnp ethernet driver.
# [90/11/24 12:05:34 jsb]
#
# Revision 2.5 90/10/01 14:22:34 jeffreyh
# Added wd8003 ethernet driver
# [90/09/27 18:24:50 jeffreyh]
#
# Revision 2.4 90/09/23 17:45:05 jsb
# Added ipsc2 support.
# [90/09/21 16:36:01 jsb]
#
# Revision 2.3 90/06/19 22:56:30 rpd
# Added -x to LDFLAGS.
# [90/06/03 rpd]
#
# Revision 2.2 90/05/03 15:16:48 dbg
# Config mach_kernel for pure kernel.
# [90/03/30 dbg]
#
# Revision 2.9 89/09/25 15:46:36 rvb
# fp defaults off for now.
# [89/09/25 rvb]
#
# Revision 2.8 89/09/25 12:20:05 rvb
# fp configurable and qt -> wt
# [89/09/23 rvb]
#
# Revision 2.7 89/09/20 17:26:12 rvb
# Don't optimize during compiles for now.
# [89/09/20 rvb]
#
# Revision 2.6 89/09/09 15:19:02 rvb
# Allow blit device and make more devices configureable
# [89/09/07 rvb]
#
# Revision 2.5 89/07/17 10:34:36 rvb
# New Devices: pccom and qd.
# [89/07/10 rvb]
#
# Revision 2.4 89/04/05 12:57:04 rvb
# Must define AT386 now in X78
# Add
# [89/03/04 rvb]
#
# Revision 2.3 89/02/25 17:37:51 gm0w
# Changes for cleanup.
#
# Revision 2.2 89/01/23 22:11:06 af
# Created.
#
#
# Master I386 configuration file (see the master machine independent
# configuration file for a description of the file format).
#
#
# #####################################################################
#
# I386 (PSEUDO-)DEVICES (select any combination)
#
# CPU TYPE (select exactly one)
# AT at bus
# MBII multibus II bus
#
# #####################################################################
#
# Standard Mach Research Configurations:
# -------- ---- -------- ---------------
#
# BOOT = [ hd bsmall ]
#
# STD = [ gcc ]
#
# MACH = [ en ]
#
# WS = [ at hd com blit fd pc586 qd wt 3c wd]
#
# iPSC = [ ipsc sd usm dcm cnp ]
#
# #####################################################################
#
machine "i386" #
cpu "AT386" #
options "AT386" #
cpu "iPSC386" #
options "iPSC386" #
cpu EXL #
options EXL #
config mach_kernel swap generic
options MACH_LOAD #
#
# Devices
#
pseudo-device blit #
device hd0 #
device fd0 #
device sd0 #
device usm0 #
device dcm0 #
device cnp0 #
pseudo-device fp #
pseudo-device "pc586" #
pseudo-device "at3c501" # <3c,eli>
pseudo-device "ns8390" #
device com0 #
device com1 #
device com2 #
device com3 #
##device qd0 #
##device qd1 #
##device wt0 #
#
# OVERRIDES FOR GCC
#
makevariables CC=" gcc" #
makevariables GAS=" gas" #
makevariables LDFLAGS="-x -e _pstart -T c0100000" #
makevariables SWAPSYS="@" #
makevariables INCLUDES="-Dwheeze" #
makevariables CC=" fgcc" #
makevariables AS=" /lib/fgcc-as" #
makevariables LD=" /lib/fgcc-ld" #
makevariables LDFLAGS="-e pstart ../i386/vuifile" #
makevariables SWAPSYS="@echo add debugging symbols; unixsyms a.out" #
makevariables VOLATILE= #
makevariables FORCE_VOLATILE="-fvolatile " #
makevariables "C_RULE_1A"="${KCC} -c ${CFLAGS} -fno-function-cse " #
makevariables "C_RULE_2"= #
makevariables "C_RULE_3"= #
makevariables "C_RULE_4"= #
_debug
OPTIONS/mach_clport optional mac./kernel/conf/MASTER.i386.local 444 146 0 3161 4754020335 11122 #
# Mach Operating System
# Copyright (c) 1991,1990,1989 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
# 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 [email protected]
# 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.
#
#
# HISTORY
# $Log: MASTER.i386.local,v $
# Revision 2.3 91/02/05 17:02:09 mrt
# Changed to new copyright
# [91/01/28 14:45:51 mrt]
#
# Revision 2.2 90/05/03 15:17:57 dbg
# First checkin.
#
# Revision 2.4.1.1 89/10/22 11:29:02 rvb
# FLush ec and ln from STD.
# [89/10/21 rvb]
#
# Revision 2.4 89/09/20 17:26:16 rvb
# Added ln and ec devices for ORC.
# [89/09/20 rvb]
#
# Revision 2.3 89/02/25 17:37:58 gm0w
# Changes for cleanup.
#
# Revision 2.2 89/01/23 22:13:21 af
# .
#
# Revision 2.1.1.1 89/01/16 16:59:04 af
# Created empty.
#
# STD = [ ]
#
device ln0 #
device ec0 #
#
# #####################################################################
#
# Standard Mach Research Configurations:
# -------- ---- -------- ---------------
#
# BOOT = [ hd bsmall ]
#
# STD = [ gcc ]
#
# MACH = [ en ]
#
# WS = [ at hd com blit fd pc586 qd wt 3c wd]
#
# iPSC = [ ipsc sd usm dcm cnp ]
#
# #########################################################./kernel/conf/Makefile.i386 444 146 0 6316 4754020352 10557 #
# Mach Operating System
# Copyright (c) 1991,1990,1989 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
# 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 [email protected]
# 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.
#
#
# HISTORY
# $Log: Makefile.i386,v $
# Revision 2.3 91/02/05 17:02:51 mrt
# Changed to new copyright
# [91/01/28 14:46:50 mrt]
#
# Revision 2.2 90/05/03 15:18:09 dbg
# Fix locore build rule - add space before '-DLOCORE'.
# [90/02/14 dbg]
#
# Revision 2.6.1.5 90/02/01 13:33:48 rvb
# Don't play with SYS_RULE_1. And stub out SYS_RULE{2,3,4}
# to @ to not to have (null command) complaint.
# And, the .s's files should be in $(SOURCE_DIR) not ..
# [90/01/23 rvb]
#
# Revision 2.6.1.4 90/01/02 13:55:27 rvb
# SWAPSYS is now coff only.
#
# Revision 2.6.1.3 89/12/21 17:11:24 rvb
# a.out vs coff now handled by MASTER.i386
#
# Revision 2.6.1.2 89/11/21 12:55:09 rvb
# md is no longer in /usr/mach/bin
#
#
# Revision 2.6.1.1 89/10/22 11:29:04 rvb
# Indicate coff vs a.out
# [89/10/21 rvb]
#
# Revision 2.6 89/09/25 12:20:10 rvb
# uprt.s -> start.s
# [89/09/23 rvb]
#
# Revision 2.5 89/04/07 14:58:25 rvb
# We don't need INCLUDES any more.
# [89/04/07 rvb]
#
# Revision 2.4 89/04/05 12:57:12 rvb
# Some changes for gcc, and locore is a .s
# [89/03/21 rvb]
#
# Revision 2.3 89/02/25 17:39:18 gm0w
# Changes for cleanup.
#
# Revision 2.2 89/01/23 22:15:23 af
# Created.
# [89/01/16 17:11:51 af]
#
###############################################################################
#BEGIN Machine dependent Makefile fragment for the i386
###############################################################################
#tmp
SYS_RULE_2=-@
SYS_RULE_3=-@
SYS_RULE_4=-@
MD=md
#LIBS_P=-lc_p
LDOBJS_PREFIX= ${ORDERED} locore.o
LOCORE_DEPS= assym.s $(SOURCE_DIR)/machine/start.s \
$(SOURCE_DIR)/machine/locore.s $(SOURCE_DIR)/machine/cswitch.s
LOCORE_HEADS=
locore.s: ${LOCORE_DEPS}
cat ${LOCORE_DEPS} >locore.tmp
mv locore.tmp locore.s
@echo The hack below should get fixed sometime.
cp /dev/null ioconf.c
locore.o: assym.s locore.s ${LOCORE_HEADS}
${S_RULE_1A} -DLOCORE -I../machine ${S_RULE_1B}; \
${S_RULE_2}; \
${S_RULE_3}
###############################################################################
#END Machine dependent Makefile fragment for the i386
###############################################################################
.
# [90/02/14 dbg]
#
# Revision 2.6.1.5 90/02/01 13:33:48 rvb
# Don't play with SYS_RULE_1. And stub out SYS_RULE{2,3,4}
# to @ to not to have (null command) complaint.
# And, the .s's files should be in $(SOURCE_DIR) not ..
# [90/01/23 rvb]
#
# Revision 2.6.1.4 90/01/02 ./kernel/conf/files.i386 444 146 0 11741 4754020367 10170 #
# Mach Operating System
# Copyright (c) 1991,1990 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
# 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 [email protected]
# 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.
#
#
# HISTORY
# $Log: files.i386,v $
# Revision 2.12 91/02/05 17:05:14 mrt
# Changed to new copyright
# [91/01/28 14:47:43 mrt]
#
# Revision 2.11 91/01/08 17:31:50 rpd
# Switch wd8003 -> ns8390
# [91/01/04 12:14:06 rvb]
#
# Revision 2.10 90/12/14 10:59:25 jsb
# ipsc/dev_forward_table.c -> ipsc/dev_forward_name.c
# [90/12/14 09:01:30 jsb]
#
# Added ipsc/dev_forward_table.c (for cross-node device support).
# [90/12/14 08:26:54 jsb]
#
# Revision 2.9 90/12/04 14:45:48 jsb
# Replaced ipsc2 with ipsc386. Replaced i386ipsc2/ with i386ipsc/.
# Moved rtc.c and usm.c to ipsc/, and pmap.c to intel/.
# Added ipsc/node.c
# [90/12/04 11:40:54 jsb]
#
# Revision 2.8 90/11/26 14:48:31 rvb
# Merge in I386q devices for autoconf.c
# [90/11/26 11:12:12 rvb]
#
# Revision 2.7 90/11/24 15:14:40 jsb
# Added support for i386ipsc2 cnp ethernet driver.
# [90/11/24 12:02:37 jsb]
#
# Revision 2.6 90/10/01 14:22:42 jeffreyh
# added wd8003 ethernet driver
# [90/09/27 18:25:22 jeffreyh]
#
# Revision 2.5 90/09/23 17:45:08 jsb
# Fixed screwed up history messages.
# [90/09/21 16:35:15 jsb]
#
# Added files for ipsc2. Changed some other files from standard to at386.
# [90/09/21 16:31:24 jsb]
#
# Revision 2.4 90/08/27 21:47:26 dbg
# Use idt.s instead of idt.c
# [90/07/26 dbg]
#
# Switch to new kernel debugger.
# [90/07/20 dbg]
#
# Revision 2.3 90/05/21 13:26:16 dbg
# Add keyboard event driver, mouse, iopl device and io instruction
# emulation.
# [90/05/17 dbg]
#
# Revision 2.2 90/05/03 15:19:01 dbg
# Created.
#
intel/pmap.c standard
i386/bcopy.s standard
i386/bzero.s standard
i386/exec.c standard
i386/fpu.c standard
i386/gcc.s standard
i386/gdt.c standard
i386/hardclock.c standard
i386/i386_init.c standard
i386/idt.s standard
i386/init.c standard
i386/interrupt.s standard
i386/io_emulate.c standard
i386/io_map.c standard
i386/db_disasm.c optional mach_kdb
i386/db_interface.c optional mach_kdb
i386/db_trace.c optional mach_kdb
i386/ktss.c standard
i386/ldt.c standard
i386/loose_ends.c standard
i386/ntoh.s standard
i386/pic.c standard
i386/pit.c standard
i386/pcb.c standard
i386/phys.c standard
i386/read_fault.c standard
i386/setroot.c standard
i386/spl.s standard
i386/trap.c standard
i386/_setjmp.s standard
i386at/autoconf.c optional at386
i386at/blit.c optional blit device-driver |${FORCE_VOLATILE}
i386at/c765.c optional fd device-driver
i386at/com.c optional com device-driver
i386at/conf.c optional at386
i386at/hd.c optional hd
i386at/if_par.c optional par device-driver
i386at/if_3c501.c optional at3c501 device-driver
i386at/if_pc586.c optional pc586 device-driver |${VOLATILE}
i386at/if_ns8390.c optional ns8390 device-driver
i386at/iopl.c optional at386
i386at/kd.c optional at386
i386at/kdasm.s optional at386
i386at/kd_event.c optional at386
i386at/kd_mouse.c optional at386
i386at/kd_queue.c optional at386
i386at/lpr.c optional lpr device-driver
i386at/m765drv.c optional fd device-driver
i386at/m765knl.c optional fd device-driver
i386at/pic_isa.c optional at386
i386at/qd.c optional qd device-driver
i386at/rtc.c optional at386
i386at/wt.c optional wt device-driver
i386orc/ec.c optional ec device-driver
i386orc/evc1.c optional evc device-driver
i386orc/evc1font.c optional evc device-driver
i386ipsc/autoconf.c optional ipsc386
i386ipsc/conf.c optional ipsc386
i386ipsc/iopl.c optional ipsc386
i386ipsc/pic_ipsc.c optional ipsc386
i386ipsc/led.c optional ipsc386 device-driver |${FORCE_VOLATILE}
i386ipsc/sd.c optional sd device-driver |${FORCE_VOLATILE}
i386ipsc/sdintr.c optional sd device-driver |${FORCE_VOLATILE}
i386ipsc/dcm.c optional dcm device-driver |${FORCE_VOLATILE}
i386ipsc/dcm_route.s optional dcm device-driver
i386ipsc/if_cnp.c optional cnp device-driver
ipsc/rtc.c optional ipsc386
ipsc/node.c optional ipsc386
ipsc/dev_forward_name.c optional ipsc386
ipsc/usm.c optional usm device-driver |${FORCE_VOLATILE}
#
# Dummy devices for now
OPTIONS/ln optional ln
OPTIONS/ec optional ec
TIONS/mach_clport optional mac./kernel/conf/MASTER.mips 444 146 0 11610 4754020341 10323 #
# Mach Operating System
# Copyright (c) 1991,1990,1989,1988 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
# 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 [email protected]
# 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.
#
# HISTORY
# $Log: MASTER.mips,v $
# Revision 2.10 91/02/05 17:02:23 mrt
# Changed to new copyright
# [91/01/28 14:46:07 mrt]
#
# Revision 2.9 91/01/08 15:08:48 rpd
# Disabled ref_bits. Again.
# [91/01/04 rpd]
#
# Revision 2.8 90/12/05 23:27:20 af
# Merge problems.
#
# Revision 2.7 90/12/05 20:42:04 af
# Split and documented the various screen drivers tags.
#
# Earthquake for new, copyright free PMAX device drivers.
# I tried to make things a little bit flexible and
# 'standard looking': there is now here a pseudo-device
# declaration for each major piece of PMAX hardware
# rather than just the switches in the STD.. configs.
# Note that the "gx" driver is a collective name for
# the fancy 2d/3d graphics options on 3maxen.
#
# Added
# files that are not needed elsewhere [not that you can really
# cut them all out yet].
#
# Enabled ref_bits.
# Added R3000 and fixed old R2000 defs for supported cpus.
#
# Configure two ethernet boards by default to accomodate
# 3maxen where the thick ether is a separate option board.
# [90/12/03 22:52:29 af]
#
# Revision 2.6 90/10/12 18:07:17 rpd
# Removed ref_bits from STD. The new software reference bit
# code works better.
# [90/10/09 rpd]
#
# Revision 2.5 90/09/28 16:35:59 jsb
# Made reference bits standard.
# [90/09/21 rpd]
#
# Revision 2.4 90/06/02 14:45:57 rpd
# Added TRAP_HISTORY (tag "thist").
# [90/05/12 rpd]
# Compile with -g3 to get symbol table info.
# [90/04/23 rpd]
# Cleaned up.
# [90/03/26 21:34:18 rpd]
#
# Revision 2.3 90/01/22 23:04:21 af
# I finally understood (I think) how this magic config process
# works, so I cleaned up a little this file. Three types of
# basic configurations are defined now: a stable one (ANY & friends),
# a more experimental one (TEST & friends), and one that really
# does not work yet (NOTYET) because it contains being-developped
# code.
# [89/12/14 af]
#
# Revision 2.2 89/11/29 14:08:01 af
# Long overdue fix: pm ->pmdev not to conflict with pagemap option.
# [89/10/29 14:25:43 af]
#
# Fixed for pure kernel, removed MSERIES support and related
# copyright restrictions.
# [89/10/28 af]
#
# Revision 2.4.2.1 89/09/25 11:28:53 af
# Made assembly silent.
#
# Revision 2.5 89/09/25 22:20:20 mja
# Add standard ANY, WS and MF macros (same as PMAX for now).
# [89/09/22 18:00:07 mja]
#
# Revision 2.4 89/05/30 17:04:56 rvb
# Add PMAX.
# STD = [ mips_code ]
#
# ANY = [ pmax kmax kmin ]
# WS = [ pmax kmax kmin ]
# MF = [ pmax kmax kmin ]
#
machine mips
cpu "R2000" #
cpu "R3000" #
config mach_kernel swap generic #
options PMAX #
options REF_BITS #
options MIPS_CODE #
options COMPACTED #
options COUNTERS #
options TRAP_HISTORY #
makeoptions ENDIAN="-EL" #
makeoptions GPSIZE=32 #
makeoptions CC="cc"
makeoptions LD="ld"
makeoptions SIZE="size"
makeoptions CCOPTS="-O2 -g3"
makeoptions ASOPTS="-w"
#
# PMAX DEVICES
#
pseudo-device pmax #
# MC146818 clock chip
pseudo-device mc 1 #
# DC7085 serial line controller (console)
pseudo-device dz 1 #
# LK201 keyboard driver
pseudo-device lk 1 #
# Bitmapped screen(s):
# bm is the generic bitmapped screen layer
# fb is the pmax monochrome/color framebuffer
# cfb is the 3max simple color framebuffer (needs fb)
# gx is the driver for the 2d/3d graphic engines
pseudo-device bm #
pseudo-device fb #
pseudo-device cfb #
pseudo-device gx #
# AMD7990 ethernet controller
pseudo-device se 2 #
# SCSI driver
pseudo-device scsi #
# DC7061 SCSI HBA
pseudo-device sii 1 #
# NCR 53C94 SCSI HBA
pseudo-device asc 1 #
ts or extensions that they make and grant Carnegie the
# rights to redistribute these changes.
#
# HISTORY
# $Log: MAS./kernel/conf/MASTER.mips.local 444 146 0 2601 4754020342 11375 #
# Mach Operating System
# Copyright (c) 1991,1990,1989 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
# 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 [email protected]
# 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.
#
#
# HISTORY
# $Log: MASTER.mips.local,v $
# Revision 2.4 91/02/05 17:02:27 mrt
# Changed to new copyright
# [91/01/28 14:46:12 mrt]
#
# Revision 2.3 90/06/02 14:46:02 rpd
# Added AF, for Sandro's experimental features.
# [90/03/26 21:35:11 rpd]
#
# Revision 2.2 89/11/29 14:08:04 af
# Adapted (still empty) for pure kernel.
# [89/10/28 13:13:06 af]
#
# AF = [ ref_bits measure mod_bits ]
t yet].
#
# Enabled ref_bits.
# Added R3000 and fixed old R2000 defs for supported cpus.
#
# Configure two ethernet boards./kernel/conf/Makefile.mips 444 146 0 6352 4754020354 11040 #
# Mach Operating System
# Copyright (c) 1991,1990,1989 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
# 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 [email protected]
# 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.
#
# HISTORY
# $Log: Makefile.mips,v $
# Revision 2.6 91/02/05 17:02:59 mrt
# Changed to new copyright
# [91/01/28 14:47:01 mrt]
#
# Revision 2.5 90/06/19 22:56:59 rpd
# Added CDEBUGFLAGS, CMACHFLAGS definitions.
# [90/06/03 rpd]
#
# Revision 2.4 90/06/02 14:46:26 rpd
# Added dependencies on mig-generated files.
# [90/03/26 21:37:52 rpd]
#
# Revision 2.3 90/01/22 23:04:26 af
# Added nullification of VOLATILE macro.
# [89/12/10 af]
#
# Revision 2.2 89/11/29 14:08:06 af
# Adapted for pure kernel, droppped nonsensical MIPS Copyright
# (why was it included to begin with ?)
# [89/10/28 af]
#
# Revision 2.4 89/05/30 17:06:21 rvb
# Nothing Noteworthy.
#
#
######################################################################
#BEGIN Machine dependent Makefile fragment for the MIPS
######################################################################
#
RM= rm -f
TEXTBASE= 80030000
#
# COPTS is recognized by config and massaged for profiling kernels
#
#
# cc options for most kernel sources
# CCNFLAGS - normal files
# CCDFLAGS - device drivers
# CCSFLAGS - swap*.c files
# CCASFLAGS - *.s files
# CCPFLAGS - profiling *.c files
# CCPASFLAGS - profiling *.s files
#
# CCOPTS may be set from the config file
# ASOPTS may be set from the config file
# ENDIAN may be set from the config file
#
CDEBUGFLAGS = $(CCOPTS)
CMACHFLAGS = $(ENDIAN) -G ${GPSIZE}
CCNFLAGS= -c $(CDEBUGFLAGS) $(CMACHFLAGS) ${COPTS}
CCDFLAGS= -c $(CDEBUGFLAGS) $(CMACHFLAGS) ${COPTS}
CCSFLAGS= -c $(CDEBUGFLAGS) $(CMACHFLAGS) ${COPTS}
CCASFLAGS= -c $(CMACHFLAGS) ${ASOPTS} ${COPTS} -DASSEMBLER
CCPFLAGS= -c $(CDEBUGFLAGS) $(CMACHFLAGS) ${PCOPTS}
CCPASFLAGS= -c $(CMACHFLAGS) ${ASOPTS} ${PCOPTS} -DASSEMBLER
#
LDOBJS_PREFIX=start.o
LDFLAGS= $(CMACHFLAGS) -N -T ${TEXTBASE} -e start ${LDOPTS}
${SOBJS}: assym.s
VOLATILE=
# Explicit dependencies on generated files,
# to ensure that Mig has been run by the time
# these files are compiled.
exec.o : mach/mach_interface.h mach/mach_user_internal.h \
mach/mach_port_internal.h
pm_tty.o : mach/mach_interface.h
######################################################################
#END Machine dependent Makefile fragment for the MIPS
######################################################################
is file. Three types of
# basic configurations are defined now: a stable one (ANY & friends),
# a more experimental one (TEST & friends), and one that really
# does not work yet (NOTYET) because it contains being-developped
# code.
# [89/12/14 af]
#
# Revision./kernel/conf/buildconf.mips 444 146 0 2307 4754020362 11263 # Copyright (c) 1991 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 [email protected]
# 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.
#
#
# HISTORY
# $Log: buildconf.mips,v $
# Revision 2.3 91/02/05 17:03:27 mrt
# Changed to new copyright
# [91/01/28 14:47:22 mrt]
#
# Revision 2.2 89/11/29 14:08:09 af
# Created.
# [ V5.1(XF25) ]
#
#
STD+S+WS = STD+L+MF+EXTRA = STD+M+ANY+EXTRA
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 ./kernel/conf/files.mips 444 146 0 14201 4754020372 10435 # Copyright (c) 1991 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 [email protected]
# 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.
#
#
# HISTORY
# $Log: files.mips,v $
# Revision 2.10 91/02/05 17:05:26 mrt
# Changed to new copyright
# [91/01/28 14:47:51 mrt]
#
# Revision 2.9 90/12/05 23:27:32 af
#
#
# Revision 2.8 90/12/05 20:42:06 af
# Made cfb driver optional.
# New, copyright free PMAX device drivers.
# Added mapped scsi driver.
# Added mapped ether files.
# [90/12/03 22:54:01 af]
#
# Revision 2.7 90/09/09 23:19:48 rpd
# Added mapped ether driver.
# [90/08/30 17:42:07 af]
#
# Revision 2.6 90/08/27 21:47:36 dbg
# Made new debugger official.
# New, copyright-free clock driver.
# [90/08/18 00:08:05 af]
#
# Added new dbg's debugger files.
# [90/08/14 af]
#
# Revision 2.5 90/08/07 22:22:49 rpd
# Added 3max support files and new autoconf code.
# [90/08/07 15:56:50 af]
#
# Revision 2.3.3.1 90/06/11 11:01:35 af
# Added 3max support and new autoconf procedures.
#
# Revision 2.4 90/06/02 14:46:53 rpd
# Added trap_history.
# [90/05/12 rpd]
#
# Revision 2.3 90/01/22 23:04:31 af
# Merged with mainline KDB, added experimental options.
# [90/01/20 13:15:23 af]
#
# Revision 2.2 89/11/29 14:08:14 af
# Changes for pure kernel.
# [89/10/04 af]
#
# Revision 2.7 89/09/22 13:53:58 af
# Added kdb files.
# [89/08/28 af]
#
# Revision 2.6 89/05/31 15:12:04 rvb
# mips/MIPS => mips/MSERIES
# [89/05/31 rvb]
#
# Revision 2.5 89/05/31 12:46:32 rvb
# Move r2350mem.[ch] to MIPS.
#
#
# Revision 2.4 89/05/30 13:09:58 rvb
# Put MIPS specific and PMAX specific drivers in subdirectories.
#
# 28-Feb-89 Alessandro Forin (af) at Carnegie-Mellon University
# Added Pmax devices.
# ??-???-?? Robert V. Baron (rvb) at Carnegie-Mellon University
# Created.
#
#
OPTIONS/ref_bits optional ref_bits
OPTIONS/mips_code optional mips_code
OPTIONS/compacted optional compacted
OPTIONS/counters optional counters
OPTIONS/trap_history optional trap_history
mips/start.s standard ordered
mips/autoconf.c standard
mips/busses.c standard
mips/conf.c standard
mips/context.s standard
mips/db_disasm.c optional mach_kdb
mips/db_interface.c optional mach_kdb
mips/db_mips_sym.c optional mach_kdb
mips/db_trace.c optional mach_kdb
mips/exec.c standard
mips/locore.s standard
mips/mips_cache.s standard
mips/mips_copyin.s standard
mips/mips_cpu.s standard
mips/mips_init.c standard
mips/mips_instruction.c standard
mips/mips_mem_ops.c standard
mips/mips_misc.c standard
mips/mips_startup.c standard
mips/parse_args.c standard
mips/pcb.c standard
mips/pmap.c standard
mips/prom_interface.s standard
mips/softfp.s optional mips_code
mips/tlb.s standard
mips/trap.c standard
# Mips M-Series device drivers
mips/MSERIES/cp.c optional cp device-driver
mips/MSERIES/dkip.c optional dkip device-driver
mips/MSERIES/i8254clock.c optional i8254clock device-driver
mips/MSERIES/if_enp.c optional enp device-driver
mips/MSERIES/r2350mem.c optional mseries device-driver
mips/MSERIES/rd.c optional rd device-driver
mips/MSERIES/s2681cons.c optional s2681cons device-driver
mips/MSERIES/sd.c optional sd device-driver
mips/MSERIES/ts.c optional ts device-driver
mips/MSERIES/tth.c optional tthu device-driver
mips/MSERIES/vme.c optional vme device-driver
# PMAX devices drivers
mips/PMAX/if_se.c optional se device-driver
mips/PMAX/if_se_mapped.c optional se device-driver
mips/PMAX/kernel_font.c optional bm device-driver
mips/PMAX/kn01.c optional pmax
mips/PMAX/kn02.c optional pmax
mips/PMAX/mapped_scsi.c optional scsi device-driver
mips/PMAX/mc_clock.c optional mc device-driver
mips/PMAX/mips_box.c optional pmax
mips/PMAX/model_dep.c optional pmax
mips/PMAX/tc.c optional pmax
mips/PMAX/bt459.c optional bm device-driver
mips/PMAX/bt478.c optional bm device-driver
mips/PMAX/cfb_hdw.c optional cfb device-driver
mips/PMAX/cfb_misc.c optional cfb device-driver
mips/PMAX/dc503.c optional bm device-driver
mips/PMAX/dz_hdw.c optional dz device-driver
mips/PMAX/dz_tty.c optional dz device-driver
mips/PMAX/ga_hdw.c optional gx device-driver
mips/PMAX/gq_hdw.c optional gx device-driver
mips/PMAX/gx_misc.c optional gx device-driver
mips/PMAX/lk201.c optional lk device-driver
mips/PMAX/mouse.c optional bm device-driver
mips/PMAX/pm_hdw.c optional fb device-driver
mips/PMAX/pm_misc.c optional fb device-driver
mips/PMAX/rz.c optional scsi device-driver
mips/PMAX/rz_disk.c optional scsi device-driver
mips/PMAX/rz_tape.c optional scsi device-driver
mips/PMAX/screen.c optional bm device-driver
mips/PMAX/screen_switch.c optional bm device-driver
mips/PMAX/scsi.c optional scsi device-driver
mips/PMAX/scsi_53C94_hdw.c optional asc device-driver
mips/PMAX/scsi_7061_hdw.c optional sii device-driver
mips/PMAX/scsi_alldevs.c optional scsi device-driver
mips/PMAX/scsi_comm.c optional scsi device-driver
mips/PMAX/scsi_cpu.c optional scsi device-driver
mips/PMAX/scsi_disk.c optional scsi device-driver
mips/PMAX/scsi_jukebox.c optional scsi device-driver
mips/PMAX/scsi_optical.c optional scsi device-driver
mips/PMAX/scsi_printer.c optional scsi device-driver
mips/PMAX/scsi_rom.c optional scsi device-driver
mips/PMAX/scsi_scanner.c optional scsi device-driver
mips/PMAX/scsi_tape.c optional scsi device-driver
mips/PMAX/scsi_worm.c optional scsi device-driver
#
cpu "R3000" #
config mach_kernel swap generic #
options PMAX #
options REF_BITS #
options MIPS_CODE #
options COMPACTED #
options COUNTERS #
options TRAP_HISTORY #
makeoptions ENDIAN="-EL" #
makeoptions GPSIZE=32 #
makeoptions CC="./kernel/ddb/ 755 146 0 0 4756607452 6160 ./kernel/ddb/db_input.c 444 146 0 12052 4756607452 10233 /*
* Mach Operating System
* Copyright (c) 1991,1990 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: db_input.c,v $
* Revision 2.4 91/02/14 14:41:53 mrt
* Add input line editing.
* [90/11/11 dbg]
*
* Revision 2.3 91/02/05 17:06:32 mrt
* Changed to new Mach copyright
* [91/01/31 16:18:13 mrt]
*
* Revision 2.2 90/08/27 21:51:03 dbg
* Reduce lint.
* [90/08/07 dbg]
* Created.
* [90/07/25 dbg]
*
*/
/*
* Author: David B. Golub, Carnegie Mellon University
* Date: 7/90
*/
#include
#include
/*
* Character input and editing.
*/
/*
* We don't track output position while editing input,
* since input always ends with a new-line. We just
* reset the line position at the end.
*/
char * db_lbuf_start; /* start of input line buffer */
char * db_lbuf_end; /* end of input line buffer */
char * db_lc; /* current character */
char * db_le; /* one past last character */
#define CTRL(c) ((c) & 0x1f)
#define isspace(c) ((c) == ' ' || (c) == '\t')
#define BLANK ' '
#define BACKUP '\b'
void
db_putstring(s, count)
char *s;
int count;
{
while (--count >= 0)
cnputc(*s++);
}
void
db_putnchars(c, count)
int c;
int count;
{
while (--count >= 0)
cnputc(c);
}
/*
* Delete N characters, forward or backward
*/
#define DEL_FWD 0
#define DEL_BWD 1
void
db_delete(n, bwd)
int n;
int bwd;
{
register char *p;
if (bwd) {
db_lc -= n;
db_putnchars(BACKUP, n);
}
for (p = db_lc; p < db_le-n; p++) {
*p = *(p+n);
cnputc(*p);
}
db_putnchars(BLANK, n);
db_putnchars(BACKUP, db_le - db_lc);
db_le -= n;
}
/* returns TRUE at end-of-line */
boolean_t
db_inputchar(c)
int c;
{
switch (c) {
case CTRL('b'):
/* back up one character */
if (db_lc > db_lbuf_start) {
cnputc(BACKUP);
db_lc--;
}
break;
case CTRL('f'):
/* forward one character */
if (db_lc < db_le) {
cnputc(*db_lc);
db_lc++;
}
break;
case CTRL('a'):
/* beginning of line */
while (db_lc > db_lbuf_start) {
cnputc(BACKUP);
db_lc--;
}
break;
case CTRL('e'):
/* end of line */
while (db_lc < db_le) {
cnputc(*db_lc);
db_lc++;
}
break;
case CTRL('h'):
case 0177:
/* erase previous character */
if (db_lc > db_lbuf_start)
db_delete(1, DEL_BWD);
break;
case CTRL('d'):
/* erase next character */
if (db_lc < db_le)
db_delete(1, DEL_FWD);
break;
case CTRL('k'):
/* delete to end of line */
if (db_lc < db_le)
db_delete(db_le - db_lc, DEL_FWD);
break;
case CTRL('t'):
/* twiddle last 2 characters */
if (db_lc >= db_lbuf_start + 2) {
c = db_lc[-2];
db_lc[-2] = db_lc[-1];
db_lc[-1] = c;
cnputc(BACKUP);
cnputc(BACKUP);
cnputc(db_lc[-2]);
cnputc(db_lc[-1]);
}
break;
case CTRL('r'):
db_putstring("^R\n", 3);
if (db_le > db_lbuf_start) {
db_putstring(db_lbuf_start, db_le - db_lbuf_start);
db_putnchars(BACKUP, db_le - db_lc);
}
break;
case '\n':
case '\r':
*db_le++ = c;
return (TRUE);
default:
if (db_le == db_lbuf_end) {
cnputc('\007');
}
else if (c >= ' ' && c <= '~') {
register char *p;
for (p = db_le; p > db_lc; p--)
*p = *(p-1);
*db_lc++ = c;
db_le++;
cnputc(c);
db_putstring(db_lc, db_le - db_lc);
db_putnchars(BACKUP, db_le - db_lc);
}
break;
}
return (FALSE);
}
int
db_readline(lstart, lsize)
char * lstart;
int lsize;
{
db_force_whitespace(); /* synch output position */
db_lbuf_start = lstart;
db_lbuf_end = lstart + lsize;
db_lc = lstart;
db_le = lstart;
while (!db_inputchar(cngetc()))
continue;
db_putchar('\n'); /* synch output position */
*db_le = 0;
return (db_le - db_lbuf_start);
}
void
db_check_interrupt()
{
register int c;
c = cnmaygetc();
switch (c) {
case -1: /* no character */
return;
case CTRL('c'):
db_error((char *)0);
/*NOTREACHED*/
case CTRL('s'):
do {
c = cnmaygetc();
if (c == CTRL('c'))
db_error((char *)0);
} while (c != CTRL('q'));
break;
default:
/* drop on floor */
break;
}
}
* We don't track output position while editing input,
* since input always ends with a new-line. We just
* reset the line position at the end.
*/
char * db_lbuf_start; /* start of input line buffer */
char * db_lbuf_end; /* end of input line buffer */
char * db_lc; /* current character */
char * db_le; /* one past last character */
#define CTRL(c) ((c) & 0x1f)
#define isspace(c) ((c) == ' ' || (c) == '\t')
#define BLANK ' '
#define BACKUP '\b'
void
db_p./kernel/ddb/db_access.c 444 146 0 5106 4754020402 10275 /*
* Mach Operating System
* Copyright (c) 1991,1990 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
* 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 [email protected]
* 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.
*/
/*
* HISTORY
* $Log: db_access.c,v $
* Revision 2.3 91/02/05 17:05:44 mrt
* Changed to new Mach copyright
* [91/01/31 16:16:22 mrt]
*
* Revision 2.2 90/08/27 21:48:20 dbg
* Fix type declarations.
* [90/08/07 dbg]
* Created.
* [90/07/25 dbg]
*
*/
/*
* Author: David B. Golub, Carnegie Mellon University
* Date: 7/90
*/
#include
#include
#include
/*
* Access unaligned data items on aligned (longword)
* boundaries.
*/
extern void db_read_bytes(); /* machine-dependent */
extern void db_write_bytes(); /* machine-dependent */
int db_extend[] = { /* table for sign-extending */
0,
0xFFFFFF80,
0xFFFF8000,
0xFF800000
};
db_expr_t
db_get_value(addr, size, is_signed)
db_addr_t addr;
register int size;
boolean_t is_signed;
{
char data[sizeof(int)];
register db_expr_t value;
register int i;
db_read_bytes(addr, size, data);
value = 0;
#if BYTE_MSF
for (i = 0; i < size; i++)
#else /* BYTE_LSF */
for (i = size - 1; i >= 0; i--)
#endif
{
value = (value << 8) + (data[i] & 0xFF);
}
if (size < 4) {
if (is_signed && (value & db_extend[size]) != 0)
value |= db_extend[size];
}
return (value);
}
void
db_put_value(addr, size, value)
db_addr_t addr;
register int size;
register db_expr_t value;
{
char data[sizeof(int)];
register int i;
#if BYTE_MSF
for (i = size - 1; i >= 0; i--)
#else /* BYTE_LSF */
for (i = 0; i < size; i++)
#endif
{
data[i] = value & 0xFF;
value >>= 8;
}
db_write_bytes(addr, size, data);
}
mrt
* Changed to new Mach copyright
* [91/01/31 16:16:22 mrt]
*
* Revision 2.2 90/08/27 21:48:20 dbg
* Fix type declarations.
* [90/08/07 dbg]
* Created.
* [90/07/25 dbg]
*
*/
/*
* Author: David B. Golub, Carnegie Mellon University
* Date: 7/90
*/
#include