initial commit
This commit is contained in:
commit
8654300ef4
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
kern/compile/
|
||||||
|
build/
|
72
Makefile
Normal file
72
Makefile
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#
|
||||||
|
# Toplevel makefile for OS/161.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Main rules:
|
||||||
|
# all (default): depend and compile system; install into staging area
|
||||||
|
# rebuild: likewise, but start with a clean slate.
|
||||||
|
# fullrebuild: likewise, but start with a very clean slate.
|
||||||
|
#
|
||||||
|
# What all does, in order:
|
||||||
|
# tools: depend and compile the tools used in build.
|
||||||
|
# includes: install header files.
|
||||||
|
# build: depend and compile the system.
|
||||||
|
#
|
||||||
|
# Other targets:
|
||||||
|
# depend: just update make dependency information.
|
||||||
|
# tags: generate/regenerate "tags" files.
|
||||||
|
# install: install into $(OSTREE).
|
||||||
|
# clean: remove generated files.
|
||||||
|
# distclean: remove all generated files.
|
||||||
|
#
|
||||||
|
|
||||||
|
TOP=.
|
||||||
|
.include "$(TOP)/mk/os161.config.mk"
|
||||||
|
|
||||||
|
all:; # make this first
|
||||||
|
|
||||||
|
MKDIRS=$(OSTREE)
|
||||||
|
|
||||||
|
.include "$(TOP)/mk/os161.mkdirs.mk"
|
||||||
|
|
||||||
|
all: tools .WAIT includes .WAIT build
|
||||||
|
|
||||||
|
rebuild:
|
||||||
|
$(MAKE) clean
|
||||||
|
$(MAKE) all
|
||||||
|
|
||||||
|
fullrebuild:
|
||||||
|
$(MAKE) distclean
|
||||||
|
$(MAKE) all
|
||||||
|
|
||||||
|
# currently no tools required, hence no tools/ dir or work to do
|
||||||
|
tools:
|
||||||
|
@true
|
||||||
|
|
||||||
|
build:
|
||||||
|
(cd userland && $(MAKE) build)
|
||||||
|
(cd man && $(MAKE) install-staging)
|
||||||
|
(cd testscripts && $(MAKE) build)
|
||||||
|
|
||||||
|
includes tags depend:
|
||||||
|
(cd kern && $(MAKE) $@)
|
||||||
|
(cd userland && $(MAKE) $@)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
(cd kern && $(MAKE) $@)
|
||||||
|
(cd userland && $(MAKE) $@)
|
||||||
|
rm -rf $(INSTALLTOP)
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
rm -rf $(WORKDIR)
|
||||||
|
|
||||||
|
install: $(OSTREE)
|
||||||
|
(cd $(INSTALLTOP) && tar -cf - .) | (cd $(OSTREE) && tar -xvf -)
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: all rebuild fullrebuild tools build includes tags depend
|
||||||
|
.PHONY: clean distclean
|
||||||
|
|
||||||
|
# old BSD name, same as distclean
|
||||||
|
cleandir: distclean
|
||||||
|
.PHONY: cleandir
|
7
common/gcc-millicode/README
Normal file
7
common/gcc-millicode/README
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
These are support functions needed by gcc to perform operations on
|
||||||
|
64-bit integer types on 32-bit machines. The names are meaningful to
|
||||||
|
the gcc back end. The term "millicode" is sometimes used to describe
|
||||||
|
such compiler support code.
|
||||||
|
|
||||||
|
This code was taken from NetBSD's src/common/lib/libc/quad, and
|
||||||
|
polished some for OS/161.
|
56
common/gcc-millicode/adddi3.c
Normal file
56
common/gcc-millicode/adddi3.c
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software was developed by the Computer Systems Engineering group
|
||||||
|
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||||
|
* contributed to Berkeley.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* From:
|
||||||
|
* @(#)adddi3.c 8.1 (Berkeley) 6/4/93
|
||||||
|
* NetBSD: adddi3.c,v 1.1 2005/12/20 19:28:51 christos Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "longlong.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add two long longs. This is trivial since a one-bit carry from a
|
||||||
|
* single unsigned int addition x+y occurs if and only if the sum x+y
|
||||||
|
* is less than either x or y (the choice to compare with x or y is
|
||||||
|
* arbitrary).
|
||||||
|
*/
|
||||||
|
long long
|
||||||
|
__adddi3(long long a, long long b)
|
||||||
|
{
|
||||||
|
union uu aa, bb, sum;
|
||||||
|
|
||||||
|
aa.ll = a;
|
||||||
|
bb.ll = b;
|
||||||
|
sum.ui[L] = aa.ui[L] + bb.ui[L];
|
||||||
|
sum.ui[H] = aa.ui[H] + bb.ui[H] + (sum.ui[L] < bb.ui[L]);
|
||||||
|
return (sum.ll);
|
||||||
|
}
|
53
common/gcc-millicode/anddi3.c
Normal file
53
common/gcc-millicode/anddi3.c
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software was developed by the Computer Systems Engineering group
|
||||||
|
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||||
|
* contributed to Berkeley.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* From:
|
||||||
|
* @(#)anddi3.c 8.1 (Berkeley) 6/4/93
|
||||||
|
* NetBSD: anddi3.c,v 1.1 2005/12/20 19:28:51 christos Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "longlong.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return a & b, in long long.
|
||||||
|
*/
|
||||||
|
long long
|
||||||
|
__anddi3(long long a, long long b)
|
||||||
|
{
|
||||||
|
union uu aa, bb;
|
||||||
|
|
||||||
|
aa.ll = a;
|
||||||
|
bb.ll = b;
|
||||||
|
aa.ui[0] &= bb.ui[0];
|
||||||
|
aa.ui[1] &= bb.ui[1];
|
||||||
|
return (aa.ll);
|
||||||
|
}
|
61
common/gcc-millicode/ashldi3.c
Normal file
61
common/gcc-millicode/ashldi3.c
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software was developed by the Computer Systems Engineering group
|
||||||
|
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||||
|
* contributed to Berkeley.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* From:
|
||||||
|
* @(#)ashldi3.c 8.1 (Berkeley) 6/4/93
|
||||||
|
* NetBSD: ashldi3.c,v 1.1 2005/12/20 19:28:51 christos Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "longlong.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shift a (signed) long long value left (arithmetic shift left).
|
||||||
|
* This is the same as logical shift left!
|
||||||
|
*/
|
||||||
|
long long
|
||||||
|
__ashldi3(long long a, unsigned int shift)
|
||||||
|
{
|
||||||
|
union uu aa;
|
||||||
|
|
||||||
|
if (shift == 0)
|
||||||
|
return(a);
|
||||||
|
aa.ll = a;
|
||||||
|
if (shift >= INT_BITS) {
|
||||||
|
aa.ui[H] = aa.ui[L] << (shift - INT_BITS);
|
||||||
|
aa.ui[L] = 0;
|
||||||
|
} else {
|
||||||
|
aa.ui[H] = (aa.ui[H] << shift) |
|
||||||
|
(aa.ui[L] >> (INT_BITS - shift));
|
||||||
|
aa.ui[L] <<= shift;
|
||||||
|
}
|
||||||
|
return (aa.ll);
|
||||||
|
}
|
73
common/gcc-millicode/ashrdi3.c
Normal file
73
common/gcc-millicode/ashrdi3.c
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software was developed by the Computer Systems Engineering group
|
||||||
|
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||||
|
* contributed to Berkeley.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* From:
|
||||||
|
* @(#)ashrdi3.c 8.1 (Berkeley) 6/4/93
|
||||||
|
* NetBSD: ashrdi3.c,v 1.1 2005/12/20 19:28:51 christos Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "longlong.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shift a (signed) long long value right (arithmetic shift right).
|
||||||
|
*/
|
||||||
|
long long
|
||||||
|
__ashrdi3(long long a, unsigned int shift)
|
||||||
|
{
|
||||||
|
union uu aa;
|
||||||
|
|
||||||
|
if (shift == 0)
|
||||||
|
return(a);
|
||||||
|
aa.ll = a;
|
||||||
|
if (shift >= INT_BITS) {
|
||||||
|
int s;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Smear bits rightward using the machine's right-shift
|
||||||
|
* method, whether that is sign extension or zero fill,
|
||||||
|
* to get the `sign word' s. Note that shifting by
|
||||||
|
* INT_BITS is undefined, so we shift (INT_BITS-1),
|
||||||
|
* then 1 more, to get our answer.
|
||||||
|
*/
|
||||||
|
/* LINTED inherits machine dependency */
|
||||||
|
s = (aa.si[H] >> (INT_BITS - 1)) >> 1;
|
||||||
|
/* LINTED inherits machine dependency*/
|
||||||
|
aa.ui[L] = aa.si[H] >> (shift - INT_BITS);
|
||||||
|
aa.ui[H] = s;
|
||||||
|
} else {
|
||||||
|
aa.ui[L] = (aa.ui[L] >> shift) |
|
||||||
|
(aa.ui[H] << (INT_BITS - shift));
|
||||||
|
/* LINTED inherits machine dependency */
|
||||||
|
aa.si[H] >>= shift;
|
||||||
|
}
|
||||||
|
return (aa.ll);
|
||||||
|
}
|
54
common/gcc-millicode/cmpdi2.c
Normal file
54
common/gcc-millicode/cmpdi2.c
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software was developed by the Computer Systems Engineering group
|
||||||
|
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||||
|
* contributed to Berkeley.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* From:
|
||||||
|
* @(#)cmpdi2.c 8.1 (Berkeley) 6/4/93
|
||||||
|
* NetBSD: cmpdi2.c,v 1.1 2005/12/20 19:28:51 christos Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "longlong.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return 0, 1, or 2 as a <, =, > b respectively.
|
||||||
|
* Both a and b are considered signed---which means only the high word is
|
||||||
|
* signed.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
__cmpdi2(long long a, long long b)
|
||||||
|
{
|
||||||
|
union uu aa, bb;
|
||||||
|
|
||||||
|
aa.ll = a;
|
||||||
|
bb.ll = b;
|
||||||
|
return (aa.si[H] < bb.si[H] ? 0 : aa.si[H] > bb.si[H] ? 2 :
|
||||||
|
aa.ui[L] < bb.ui[L] ? 0 : aa.ui[L] > bb.ui[L] ? 2 : 1);
|
||||||
|
}
|
62
common/gcc-millicode/divdi3.c
Normal file
62
common/gcc-millicode/divdi3.c
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software was developed by the Computer Systems Engineering group
|
||||||
|
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||||
|
* contributed to Berkeley.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* From:
|
||||||
|
* @(#)divdi3.c 8.1 (Berkeley) 6/4/93
|
||||||
|
* NetBSD: divdi3.c,v 1.1 2005/12/20 19:28:51 christos Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "longlong.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Divide two signed long longs.
|
||||||
|
* ??? if -1/2 should produce -1 on this machine, this code is wrong
|
||||||
|
*/
|
||||||
|
long long
|
||||||
|
__divdi3(long long a, long long b)
|
||||||
|
{
|
||||||
|
unsigned long long ua, ub, uq;
|
||||||
|
int neg = 0;
|
||||||
|
|
||||||
|
ua = a;
|
||||||
|
ub = b;
|
||||||
|
|
||||||
|
if (a < 0)
|
||||||
|
ua = -ua, neg ^= 1;
|
||||||
|
if (b < 0)
|
||||||
|
ub = -ub, neg ^= 1;
|
||||||
|
|
||||||
|
uq = __qdivrem(ua, ub, NULL);
|
||||||
|
if (neg)
|
||||||
|
uq = - uq;
|
||||||
|
return uq;
|
||||||
|
}
|
53
common/gcc-millicode/iordi3.c
Normal file
53
common/gcc-millicode/iordi3.c
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software was developed by the Computer Systems Engineering group
|
||||||
|
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||||
|
* contributed to Berkeley.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* From:
|
||||||
|
* @(#)iordi3.c 8.1 (Berkeley) 6/4/93
|
||||||
|
* NetBSD: iordi3.c,v 1.1 2005/12/20 19:28:51 christos Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "longlong.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return a | b, in long long.
|
||||||
|
*/
|
||||||
|
long long
|
||||||
|
__iordi3(long long a, long long b)
|
||||||
|
{
|
||||||
|
union uu aa, bb;
|
||||||
|
|
||||||
|
aa.ll = a;
|
||||||
|
bb.ll = b;
|
||||||
|
aa.ui[0] |= bb.ui[0];
|
||||||
|
aa.ui[1] |= bb.ui[1];
|
||||||
|
return (aa.ll);
|
||||||
|
}
|
144
common/gcc-millicode/longlong.h
Normal file
144
common/gcc-millicode/longlong.h
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software was developed by the Computer Systems Engineering group
|
||||||
|
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||||
|
* contributed to Berkeley.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* From:
|
||||||
|
* @(#)quad.h 8.1 (Berkeley) 6/4/93
|
||||||
|
* NetBSD: quad.h,v 1.1 2005/12/20 20:29:40 christos Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Long long arithmetic.
|
||||||
|
*
|
||||||
|
* This library makes the following assumptions:
|
||||||
|
*
|
||||||
|
* - The type long long exists.
|
||||||
|
*
|
||||||
|
* - A long long variable is exactly twice as long as `int'.
|
||||||
|
*
|
||||||
|
* - The machine's arithmetic is two's complement.
|
||||||
|
*
|
||||||
|
* This library can provide 128-bit arithmetic on a machine with
|
||||||
|
* 128-bit long longs and 64-bit ints, for instance, or 96-bit
|
||||||
|
* arithmetic on machines with 48-bit ints.
|
||||||
|
*
|
||||||
|
* The names are built into gcc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(_KERNEL)
|
||||||
|
#include <types.h>
|
||||||
|
#include <endian.h>
|
||||||
|
#else
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/endian.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Depending on the desired operation, we view a `long long' in
|
||||||
|
* one or more of the following formats.
|
||||||
|
*/
|
||||||
|
union uu {
|
||||||
|
long long ll; /* as a (signed) long long */
|
||||||
|
unsigned long long ull; /* as an unsigned long long */
|
||||||
|
int si[2]; /* as two (signed) ints */
|
||||||
|
unsigned int ui[2]; /* as two unsigned ints */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define high and low parts of a long long.
|
||||||
|
*/
|
||||||
|
#if _BYTE_ORDER == _LITTLE_ENDIAN
|
||||||
|
#define H 1
|
||||||
|
#define L 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _BYTE_ORDER == _BIG_ENDIAN
|
||||||
|
#define H 0
|
||||||
|
#define L 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Total number of bits in a long long and in the pieces that make it up.
|
||||||
|
* These are used for shifting, and also below for halfword extraction
|
||||||
|
* and assembly.
|
||||||
|
*/
|
||||||
|
#define LONGLONG_BITS (sizeof(long long) * CHAR_BIT)
|
||||||
|
#define INT_BITS (sizeof(int) * CHAR_BIT)
|
||||||
|
#define HALF_BITS (sizeof(int) * CHAR_BIT / 2)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extract high and low shortwords from longword, and move low shortword of
|
||||||
|
* longword to upper half of long, i.e., produce the upper longword of
|
||||||
|
* ((long long)(x) << (number_of_bits_in_int/2)).
|
||||||
|
* [`x' must actually be unsigned int.]
|
||||||
|
*
|
||||||
|
* These are used in the multiply code, to split a longword into upper
|
||||||
|
* and lower halves, and to reassemble a product as a long long, shifted
|
||||||
|
* left (sizeof(int)*CHAR_BIT/2).
|
||||||
|
*/
|
||||||
|
#define HHALF(x) ((unsigned int)(x) >> HALF_BITS)
|
||||||
|
#define LHALF(x) ((unsigned int)(x) & (((int)1 << HALF_BITS) - 1))
|
||||||
|
#define LHUP(x) ((unsigned int)(x) << HALF_BITS)
|
||||||
|
|
||||||
|
long long __adddi3 ( long long, long long);
|
||||||
|
long long __anddi3 ( long long, long long);
|
||||||
|
long long __ashldi3 ( long long, unsigned int);
|
||||||
|
long long __ashrdi3 ( long long, unsigned int);
|
||||||
|
int __cmpdi2 ( long long, long long);
|
||||||
|
long long __divdi3 ( long long, long long);
|
||||||
|
long long __iordi3 ( long long, long long);
|
||||||
|
long long __lshldi3 ( long long, unsigned int);
|
||||||
|
long long __lshrdi3 ( long long, unsigned int);
|
||||||
|
long long __moddi3 ( long long, long long);
|
||||||
|
long long __muldi3 ( long long, long long);
|
||||||
|
long long __negdi2 ( long long);
|
||||||
|
long long __one_cmpldi2 ( long long);
|
||||||
|
long long __subdi3 ( long long, long long);
|
||||||
|
int __ucmpdi2 (unsigned long long, unsigned long long);
|
||||||
|
unsigned long long __udivdi3 (unsigned long long, unsigned long long);
|
||||||
|
unsigned long long __umoddi3 (unsigned long long, unsigned long long);
|
||||||
|
long long __xordi3 ( long long, long long);
|
||||||
|
|
||||||
|
#ifndef _KERNEL
|
||||||
|
long long __fixdfdi (double);
|
||||||
|
long long __fixsfdi (float);
|
||||||
|
unsigned long long __fixunsdfdi (double);
|
||||||
|
unsigned long long __fixunssfdi (float);
|
||||||
|
double __floatdidf (long long);
|
||||||
|
float __floatdisf (long long);
|
||||||
|
double __floatunsdidf(unsigned long long);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unsigned long long __qdivrem (unsigned long long, unsigned long long,
|
||||||
|
unsigned long long *);
|
61
common/gcc-millicode/lshldi3.c
Normal file
61
common/gcc-millicode/lshldi3.c
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software was developed by the Computer Systems Engineering group
|
||||||
|
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||||
|
* contributed to Berkeley.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* From:
|
||||||
|
* @(#)lshldi3.c 8.1 (Berkeley) 6/4/93
|
||||||
|
* NetBSD: lshldi3.c,v 1.1 2005/12/20 19:28:51 christos Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "longlong.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shift an (unsigned) long long value left (logical shift left).
|
||||||
|
* This is the same as arithmetic shift left!
|
||||||
|
*/
|
||||||
|
long long
|
||||||
|
__lshldi3(long long a, unsigned int shift)
|
||||||
|
{
|
||||||
|
union uu aa;
|
||||||
|
|
||||||
|
if (shift == 0)
|
||||||
|
return(a);
|
||||||
|
aa.ll = a;
|
||||||
|
if (shift >= INT_BITS) {
|
||||||
|
aa.ui[H] = aa.ui[L] << (shift - INT_BITS);
|
||||||
|
aa.ui[L] = 0;
|
||||||
|
} else {
|
||||||
|
aa.ui[H] = (aa.ui[H] << shift) |
|
||||||
|
(aa.ui[L] >> (INT_BITS - shift));
|
||||||
|
aa.ui[L] <<= shift;
|
||||||
|
}
|
||||||
|
return (aa.ll);
|
||||||
|
}
|
60
common/gcc-millicode/lshrdi3.c
Normal file
60
common/gcc-millicode/lshrdi3.c
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software was developed by the Computer Systems Engineering group
|
||||||
|
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||||
|
* contributed to Berkeley.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* From:
|
||||||
|
* @(#)lshrdi3.c 8.1 (Berkeley) 6/4/93
|
||||||
|
* $NetBSD: lshrdi3.c,v 1.1 2005/12/20 19:28:51 christos Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "longlong.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shift an (unsigned) long long value right (logical shift right).
|
||||||
|
*/
|
||||||
|
long long
|
||||||
|
__lshrdi3(long long a, unsigned int shift)
|
||||||
|
{
|
||||||
|
union uu aa;
|
||||||
|
|
||||||
|
if (shift == 0)
|
||||||
|
return(a);
|
||||||
|
aa.ll = a;
|
||||||
|
if (shift >= INT_BITS) {
|
||||||
|
aa.ui[L] = aa.ui[H] >> (shift - INT_BITS);
|
||||||
|
aa.ui[H] = 0;
|
||||||
|
} else {
|
||||||
|
aa.ui[L] = (aa.ui[L] >> shift) |
|
||||||
|
(aa.ui[H] << (INT_BITS - shift));
|
||||||
|
aa.ui[H] >>= shift;
|
||||||
|
}
|
||||||
|
return (aa.ll);
|
||||||
|
}
|
62
common/gcc-millicode/moddi3.c
Normal file
62
common/gcc-millicode/moddi3.c
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software was developed by the Computer Systems Engineering group
|
||||||
|
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||||
|
* contributed to Berkeley.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* From:
|
||||||
|
* @(#)moddi3.c 8.1 (Berkeley) 6/4/93
|
||||||
|
* NetBSD: moddi3.c,v 1.1 2005/12/20 19:28:51 christos Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "longlong.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return remainder after dividing two signed long longs.
|
||||||
|
*
|
||||||
|
* XXX we assume a % b < 0 iff a < 0, but this is actually machine-dependent.
|
||||||
|
*/
|
||||||
|
long long
|
||||||
|
__moddi3(long long a, long long b)
|
||||||
|
{
|
||||||
|
unsigned long long ua, ub, ur;
|
||||||
|
int neg = 0;
|
||||||
|
|
||||||
|
ua = a;
|
||||||
|
ub = b;
|
||||||
|
|
||||||
|
if (a < 0)
|
||||||
|
ua = -ua, neg ^= 1;
|
||||||
|
if (b < 0)
|
||||||
|
ub = -ub;
|
||||||
|
(void)__qdivrem(ua, ub, &ur);
|
||||||
|
if (neg)
|
||||||
|
ur = -ur;
|
||||||
|
return (ur);
|
||||||
|
}
|
241
common/gcc-millicode/muldi3.c
Normal file
241
common/gcc-millicode/muldi3.c
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software was developed by the Computer Systems Engineering group
|
||||||
|
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||||
|
* contributed to Berkeley.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* From:
|
||||||
|
* @(#)muldi3.c 8.1 (Berkeley) 6/4/93
|
||||||
|
* NetBSD: muldi3.c,v 1.1 2005/12/20 19:28:51 christos Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "longlong.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Multiply two long longs.
|
||||||
|
*
|
||||||
|
* Our algorithm is based on the following. Split incoming long long
|
||||||
|
* values u and v (where u,v >= 0) into
|
||||||
|
*
|
||||||
|
* u = 2^n u1 * u0 (n = number of bits in `unsigned int', usu. 32)
|
||||||
|
*
|
||||||
|
* and
|
||||||
|
*
|
||||||
|
* v = 2^n v1 * v0
|
||||||
|
*
|
||||||
|
* Then
|
||||||
|
*
|
||||||
|
* uv = 2^2n u1 v1 + 2^n u1 v0 + 2^n v1 u0 + u0 v0
|
||||||
|
* = 2^2n u1 v1 + 2^n (u1 v0 + v1 u0) + u0 v0
|
||||||
|
*
|
||||||
|
* Now add 2^n u1 v1 to the first term and subtract it from the middle,
|
||||||
|
* and add 2^n u0 v0 to the last term and subtract it from the middle.
|
||||||
|
* This gives:
|
||||||
|
*
|
||||||
|
* uv = (2^2n + 2^n) (u1 v1) +
|
||||||
|
* (2^n) (u1 v0 - u1 v1 + u0 v1 - u0 v0) +
|
||||||
|
* (2^n + 1) (u0 v0)
|
||||||
|
*
|
||||||
|
* Factoring the middle a bit gives us:
|
||||||
|
*
|
||||||
|
* uv = (2^2n + 2^n) (u1 v1) + [u1v1 = high]
|
||||||
|
* (2^n) (u1 - u0) (v0 - v1) + [(u1-u0)... = mid]
|
||||||
|
* (2^n + 1) (u0 v0) [u0v0 = low]
|
||||||
|
*
|
||||||
|
* The terms (u1 v1), (u1 - u0) (v0 - v1), and (u0 v0) can all be done
|
||||||
|
* in just half the precision of the original. (Note that either or both
|
||||||
|
* of (u1 - u0) or (v0 - v1) may be negative.)
|
||||||
|
*
|
||||||
|
* This algorithm is from Knuth vol. 2 (2nd ed), section 4.3.3, p. 278.
|
||||||
|
*
|
||||||
|
* Since C does not give us a `int * int = long long' operator, we split
|
||||||
|
* our input long longs into two ints, then split the two ints into two
|
||||||
|
* shorts. We can then calculate `short * short = int' in native
|
||||||
|
* arithmetic.
|
||||||
|
*
|
||||||
|
* Our product should, strictly speaking, be a `long long long', with
|
||||||
|
* 128 bits, but we are going to discard the upper 64. In other words,
|
||||||
|
* we are not interested in uv, but rather in (uv mod 2^2n). This
|
||||||
|
* makes some of the terms above vanish, and we get:
|
||||||
|
*
|
||||||
|
* (2^n)(high) + (2^n)(mid) + (2^n + 1)(low)
|
||||||
|
*
|
||||||
|
* or
|
||||||
|
*
|
||||||
|
* (2^n)(high + mid + low) + low
|
||||||
|
*
|
||||||
|
* Furthermore, `high' and `mid' can be computed mod 2^n, as any factor
|
||||||
|
* of 2^n in either one will also vanish. Only `low' need be computed
|
||||||
|
* mod 2^2n, and only because of the final term above.
|
||||||
|
*/
|
||||||
|
static long long __lmulq(unsigned int, unsigned int);
|
||||||
|
|
||||||
|
long long
|
||||||
|
__muldi3(long long a, long long b)
|
||||||
|
{
|
||||||
|
union uu u, v, low, prod;
|
||||||
|
unsigned int high, mid, udiff, vdiff;
|
||||||
|
int negall, negmid;
|
||||||
|
#define u1 u.ui[H]
|
||||||
|
#define u0 u.ui[L]
|
||||||
|
#define v1 v.ui[H]
|
||||||
|
#define v0 v.ui[L]
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get u and v such that u, v >= 0. When this is finished,
|
||||||
|
* u1, u0, v1, and v0 will be directly accessible through the
|
||||||
|
* int fields.
|
||||||
|
*/
|
||||||
|
if (a >= 0)
|
||||||
|
u.ll = a, negall = 0;
|
||||||
|
else
|
||||||
|
u.ll = -a, negall = 1;
|
||||||
|
if (b >= 0)
|
||||||
|
v.ll = b;
|
||||||
|
else
|
||||||
|
v.ll = -b, negall ^= 1;
|
||||||
|
|
||||||
|
if (u1 == 0 && v1 == 0) {
|
||||||
|
/*
|
||||||
|
* An (I hope) important optimization occurs when u1 and v1
|
||||||
|
* are both 0. This should be common since most numbers
|
||||||
|
* are small. Here the product is just u0*v0.
|
||||||
|
*/
|
||||||
|
prod.ll = __lmulq(u0, v0);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Compute the three intermediate products, remembering
|
||||||
|
* whether the middle term is negative. We can discard
|
||||||
|
* any upper bits in high and mid, so we can use native
|
||||||
|
* unsigned int * unsigned int => unsigned int arithmetic.
|
||||||
|
*/
|
||||||
|
low.ll = __lmulq(u0, v0);
|
||||||
|
|
||||||
|
if (u1 >= u0)
|
||||||
|
negmid = 0, udiff = u1 - u0;
|
||||||
|
else
|
||||||
|
negmid = 1, udiff = u0 - u1;
|
||||||
|
if (v0 >= v1)
|
||||||
|
vdiff = v0 - v1;
|
||||||
|
else
|
||||||
|
vdiff = v1 - v0, negmid ^= 1;
|
||||||
|
mid = udiff * vdiff;
|
||||||
|
|
||||||
|
high = u1 * v1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assemble the final product.
|
||||||
|
*/
|
||||||
|
prod.ui[H] = high + (negmid ? -mid : mid) + low.ui[L] +
|
||||||
|
low.ui[H];
|
||||||
|
prod.ui[L] = low.ui[L];
|
||||||
|
}
|
||||||
|
return (negall ? -prod.ll : prod.ll);
|
||||||
|
#undef u1
|
||||||
|
#undef u0
|
||||||
|
#undef v1
|
||||||
|
#undef v0
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Multiply two 2N-bit ints to produce a 4N-bit long long, where N is
|
||||||
|
* half the number of bits in an int (whatever that is---the code
|
||||||
|
* below does not care as long as the header file does its part of the
|
||||||
|
* bargain---but typically N==16).
|
||||||
|
*
|
||||||
|
* We use the same algorithm from Knuth, but this time the modulo refinement
|
||||||
|
* does not apply. On the other hand, since N is half the size of an int,
|
||||||
|
* we can get away with native multiplication---none of our input terms
|
||||||
|
* exceeds (UINT_MAX >> 1).
|
||||||
|
*
|
||||||
|
* Note that, for unsigned int l, the quad-precision (long long) result
|
||||||
|
*
|
||||||
|
* l << N
|
||||||
|
*
|
||||||
|
* splits into high and low ints as HHALF(l) and LHUP(l) respectively.
|
||||||
|
*/
|
||||||
|
static long long
|
||||||
|
__lmulq(unsigned int u, unsigned int v)
|
||||||
|
{
|
||||||
|
unsigned int u1, u0, v1, v0, udiff, vdiff, high, mid, low;
|
||||||
|
unsigned int prodh, prodl, was;
|
||||||
|
union uu prod;
|
||||||
|
int neg;
|
||||||
|
|
||||||
|
u1 = HHALF(u);
|
||||||
|
u0 = LHALF(u);
|
||||||
|
v1 = HHALF(v);
|
||||||
|
v0 = LHALF(v);
|
||||||
|
|
||||||
|
low = u0 * v0;
|
||||||
|
|
||||||
|
/* This is the same small-number optimization as before. */
|
||||||
|
if (u1 == 0 && v1 == 0)
|
||||||
|
return (low);
|
||||||
|
|
||||||
|
if (u1 >= u0)
|
||||||
|
udiff = u1 - u0, neg = 0;
|
||||||
|
else
|
||||||
|
udiff = u0 - u1, neg = 1;
|
||||||
|
if (v0 >= v1)
|
||||||
|
vdiff = v0 - v1;
|
||||||
|
else
|
||||||
|
vdiff = v1 - v0, neg ^= 1;
|
||||||
|
mid = udiff * vdiff;
|
||||||
|
|
||||||
|
high = u1 * v1;
|
||||||
|
|
||||||
|
/* prod = (high << 2N) + (high << N); */
|
||||||
|
prodh = high + HHALF(high);
|
||||||
|
prodl = LHUP(high);
|
||||||
|
|
||||||
|
/* if (neg) prod -= mid << N; else prod += mid << N; */
|
||||||
|
if (neg) {
|
||||||
|
was = prodl;
|
||||||
|
prodl -= LHUP(mid);
|
||||||
|
prodh -= HHALF(mid) + (prodl > was);
|
||||||
|
} else {
|
||||||
|
was = prodl;
|
||||||
|
prodl += LHUP(mid);
|
||||||
|
prodh += HHALF(mid) + (prodl < was);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* prod += low << N */
|
||||||
|
was = prodl;
|
||||||
|
prodl += LHUP(low);
|
||||||
|
prodh += HHALF(low) + (prodl < was);
|
||||||
|
/* ... + low; */
|
||||||
|
if ((prodl += low) < low)
|
||||||
|
prodh++;
|
||||||
|
|
||||||
|
/* return 4N-bit product */
|
||||||
|
prod.ui[H] = prodh;
|
||||||
|
prod.ui[L] = prodl;
|
||||||
|
return (prod.ll);
|
||||||
|
}
|
52
common/gcc-millicode/negdi2.c
Normal file
52
common/gcc-millicode/negdi2.c
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software was developed by the Computer Systems Engineering group
|
||||||
|
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||||
|
* contributed to Berkeley.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* From:
|
||||||
|
* @(#)negdi2.c 8.1 (Berkeley) 6/4/93
|
||||||
|
* NetBSD: negdi2.c,v 1.1 2005/12/20 19:28:51 christos Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "longlong.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return -a (or, equivalently, 0 - a), in long long. See subdi3.c.
|
||||||
|
*/
|
||||||
|
long long
|
||||||
|
__negdi2(long long a)
|
||||||
|
{
|
||||||
|
union uu aa, res;
|
||||||
|
|
||||||
|
aa.ll = a;
|
||||||
|
res.ui[L] = -aa.ui[L];
|
||||||
|
res.ui[H] = -aa.ui[H] - (res.ui[L] > 0);
|
||||||
|
return (res.ll);
|
||||||
|
}
|
53
common/gcc-millicode/notdi2.c
Normal file
53
common/gcc-millicode/notdi2.c
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software was developed by the Computer Systems Engineering group
|
||||||
|
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||||
|
* contributed to Berkeley.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* From:
|
||||||
|
* @(#)notdi2.c 8.1 (Berkeley) 6/4/93
|
||||||
|
* NetBSD: notdi2.c,v 1.1 2005/12/20 19:28:51 christos Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "longlong.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return ~a. For some reason gcc calls this `one's complement' rather
|
||||||
|
* than `not'.
|
||||||
|
*/
|
||||||
|
long long
|
||||||
|
__one_cmpldi2(long long a)
|
||||||
|
{
|
||||||
|
union uu aa;
|
||||||
|
|
||||||
|
aa.ll = a;
|
||||||
|
aa.ui[0] = ~aa.ui[0];
|
||||||
|
aa.ui[1] = ~aa.ui[1];
|
||||||
|
return (aa.ll);
|
||||||
|
}
|
279
common/gcc-millicode/qdivrem.c
Normal file
279
common/gcc-millicode/qdivrem.c
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software was developed by the Computer Systems Engineering group
|
||||||
|
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||||
|
* contributed to Berkeley.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* From:
|
||||||
|
* @(#)qdivrem.c 8.1 (Berkeley) 6/4/93
|
||||||
|
* NetBSD: qdivrem.c,v 1.1 2005/12/20 19:28:51 christos Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Multiprecision divide. This algorithm is from Knuth vol. 2 (2nd ed),
|
||||||
|
* section 4.3.1, pp. 257--259.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "longlong.h"
|
||||||
|
|
||||||
|
#define B ((int)1 << HALF_BITS) /* digit base */
|
||||||
|
|
||||||
|
/* Combine two `digits' to make a single two-digit number. */
|
||||||
|
#define COMBINE(a, b) (((unsigned int)(a) << HALF_BITS) | (b))
|
||||||
|
|
||||||
|
/* select a type for digits in base B: use unsigned short if they fit */
|
||||||
|
#if UINT_MAX == 0xffffffffU && USHRT_MAX >= 0xffff
|
||||||
|
typedef unsigned short digit;
|
||||||
|
#else
|
||||||
|
typedef unsigned int digit;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void shl(digit *p, int len, int sh);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* __qdivrem(u, v, rem) returns u/v and, optionally, sets *rem to u%v.
|
||||||
|
*
|
||||||
|
* We do this in base 2-sup-HALF_BITS, so that all intermediate
|
||||||
|
* products fit within unsigned int. As a consequence, the maximum
|
||||||
|
* length dividend and divisor are 4 `digits' in this base (they are
|
||||||
|
* shorter if they have leading zeros).
|
||||||
|
*/
|
||||||
|
unsigned long long
|
||||||
|
__qdivrem(unsigned long long ull, unsigned long long vll,
|
||||||
|
unsigned long long *arq)
|
||||||
|
{
|
||||||
|
union uu tmp;
|
||||||
|
digit *u, *v, *q;
|
||||||
|
digit v1, v2;
|
||||||
|
unsigned int qhat, rhat, t;
|
||||||
|
int m, n, d, j, i;
|
||||||
|
digit uspace[5], vspace[5], qspace[5];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Take care of special cases: divide by zero, and u < v.
|
||||||
|
*/
|
||||||
|
if (vll == 0) {
|
||||||
|
/* divide by zero. */
|
||||||
|
static volatile const unsigned int zero = 0;
|
||||||
|
|
||||||
|
tmp.ui[H] = tmp.ui[L] = 1 / zero;
|
||||||
|
if (arq)
|
||||||
|
*arq = ull;
|
||||||
|
return (tmp.ll);
|
||||||
|
}
|
||||||
|
if (ull < vll) {
|
||||||
|
if (arq)
|
||||||
|
*arq = ull;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
u = &uspace[0];
|
||||||
|
v = &vspace[0];
|
||||||
|
q = &qspace[0];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Break dividend and divisor into digits in base B, then
|
||||||
|
* count leading zeros to determine m and n. When done, we
|
||||||
|
* will have:
|
||||||
|
* u = (u[1]u[2]...u[m+n]) sub B
|
||||||
|
* v = (v[1]v[2]...v[n]) sub B
|
||||||
|
* v[1] != 0
|
||||||
|
* 1 < n <= 4 (if n = 1, we use a different division algorithm)
|
||||||
|
* m >= 0 (otherwise u < v, which we already checked)
|
||||||
|
* m + n = 4
|
||||||
|
* and thus
|
||||||
|
* m = 4 - n <= 2
|
||||||
|
*/
|
||||||
|
tmp.ull = ull;
|
||||||
|
u[0] = 0;
|
||||||
|
u[1] = (digit)HHALF(tmp.ui[H]);
|
||||||
|
u[2] = (digit)LHALF(tmp.ui[H]);
|
||||||
|
u[3] = (digit)HHALF(tmp.ui[L]);
|
||||||
|
u[4] = (digit)LHALF(tmp.ui[L]);
|
||||||
|
tmp.ull = vll;
|
||||||
|
v[1] = (digit)HHALF(tmp.ui[H]);
|
||||||
|
v[2] = (digit)LHALF(tmp.ui[H]);
|
||||||
|
v[3] = (digit)HHALF(tmp.ui[L]);
|
||||||
|
v[4] = (digit)LHALF(tmp.ui[L]);
|
||||||
|
for (n = 4; v[1] == 0; v++) {
|
||||||
|
if (--n == 1) {
|
||||||
|
unsigned int rbj; /* r*B+u[j] (not root boy jim) */
|
||||||
|
digit q1, q2, q3, q4;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Change of plan, per exercise 16.
|
||||||
|
* r = 0;
|
||||||
|
* for j = 1..4:
|
||||||
|
* q[j] = floor((r*B + u[j]) / v),
|
||||||
|
* r = (r*B + u[j]) % v;
|
||||||
|
* We unroll this completely here.
|
||||||
|
*/
|
||||||
|
t = v[2]; /* nonzero, by definition */
|
||||||
|
q1 = (digit)(u[1] / t);
|
||||||
|
rbj = COMBINE(u[1] % t, u[2]);
|
||||||
|
q2 = (digit)(rbj / t);
|
||||||
|
rbj = COMBINE(rbj % t, u[3]);
|
||||||
|
q3 = (digit)(rbj / t);
|
||||||
|
rbj = COMBINE(rbj % t, u[4]);
|
||||||
|
q4 = (digit)(rbj / t);
|
||||||
|
if (arq)
|
||||||
|
*arq = rbj % t;
|
||||||
|
tmp.ui[H] = COMBINE(q1, q2);
|
||||||
|
tmp.ui[L] = COMBINE(q3, q4);
|
||||||
|
return (tmp.ll);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* By adjusting q once we determine m, we can guarantee that
|
||||||
|
* there is a complete four-digit quotient at &qspace[1] when
|
||||||
|
* we finally stop.
|
||||||
|
*/
|
||||||
|
for (m = 4 - n; u[1] == 0; u++)
|
||||||
|
m--;
|
||||||
|
for (i = 4 - m; --i >= 0;)
|
||||||
|
q[i] = 0;
|
||||||
|
q += 4 - m;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Here we run Program D, translated from MIX to C and acquiring
|
||||||
|
* a few minor changes.
|
||||||
|
*
|
||||||
|
* D1: choose multiplier 1 << d to ensure v[1] >= B/2.
|
||||||
|
*/
|
||||||
|
d = 0;
|
||||||
|
for (t = v[1]; t < B / 2; t <<= 1)
|
||||||
|
d++;
|
||||||
|
if (d > 0) {
|
||||||
|
shl(&u[0], m + n, d); /* u <<= d */
|
||||||
|
shl(&v[1], n - 1, d); /* v <<= d */
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* D2: j = 0.
|
||||||
|
*/
|
||||||
|
j = 0;
|
||||||
|
v1 = v[1]; /* for D3 -- note that v[1..n] are constant */
|
||||||
|
v2 = v[2]; /* for D3 */
|
||||||
|
do {
|
||||||
|
digit uj0, uj1, uj2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* D3: Calculate qhat (\^q, in TeX notation).
|
||||||
|
* Let qhat = min((u[j]*B + u[j+1])/v[1], B-1), and
|
||||||
|
* let rhat = (u[j]*B + u[j+1]) mod v[1].
|
||||||
|
* While rhat < B and v[2]*qhat > rhat*B+u[j+2],
|
||||||
|
* decrement qhat and increase rhat correspondingly.
|
||||||
|
* Note that if rhat >= B, v[2]*qhat < rhat*B.
|
||||||
|
*/
|
||||||
|
uj0 = u[j + 0]; /* for D3 only -- note that u[j+...] change */
|
||||||
|
uj1 = u[j + 1]; /* for D3 only */
|
||||||
|
uj2 = u[j + 2]; /* for D3 only */
|
||||||
|
if (uj0 == v1) {
|
||||||
|
qhat = B;
|
||||||
|
rhat = uj1;
|
||||||
|
goto qhat_too_big;
|
||||||
|
} else {
|
||||||
|
unsigned int nn = COMBINE(uj0, uj1);
|
||||||
|
qhat = nn / v1;
|
||||||
|
rhat = nn % v1;
|
||||||
|
}
|
||||||
|
while (v2 * qhat > COMBINE(rhat, uj2)) {
|
||||||
|
qhat_too_big:
|
||||||
|
qhat--;
|
||||||
|
if ((rhat += v1) >= B)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* D4: Multiply and subtract.
|
||||||
|
* The variable `t' holds any borrows across the loop.
|
||||||
|
* We split this up so that we do not require v[0] = 0,
|
||||||
|
* and to eliminate a final special case.
|
||||||
|
*/
|
||||||
|
for (t = 0, i = n; i > 0; i--) {
|
||||||
|
t = u[i + j] - v[i] * qhat - t;
|
||||||
|
u[i + j] = (digit)LHALF(t);
|
||||||
|
t = (B - HHALF(t)) & (B - 1);
|
||||||
|
}
|
||||||
|
t = u[j] - t;
|
||||||
|
u[j] = (digit)LHALF(t);
|
||||||
|
/*
|
||||||
|
* D5: test remainder.
|
||||||
|
* There is a borrow if and only if HHALF(t) is nonzero;
|
||||||
|
* in that (rare) case, qhat was too large (by exactly 1).
|
||||||
|
* Fix it by adding v[1..n] to u[j..j+n].
|
||||||
|
*/
|
||||||
|
if (HHALF(t)) {
|
||||||
|
qhat--;
|
||||||
|
for (t = 0, i = n; i > 0; i--) { /* D6: add back. */
|
||||||
|
t += u[i + j] + v[i];
|
||||||
|
u[i + j] = (digit)LHALF(t);
|
||||||
|
t = HHALF(t);
|
||||||
|
}
|
||||||
|
u[j] = (digit)LHALF(u[j] + t);
|
||||||
|
}
|
||||||
|
q[j] = (digit)qhat;
|
||||||
|
} while (++j <= m); /* D7: loop on j. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If caller wants the remainder, we have to calculate it as
|
||||||
|
* u[m..m+n] >> d (this is at most n digits and thus fits in
|
||||||
|
* u[m+1..m+n], but we may need more source digits).
|
||||||
|
*/
|
||||||
|
if (arq) {
|
||||||
|
if (d) {
|
||||||
|
for (i = m + n; i > m; --i)
|
||||||
|
u[i] = (digit)(((unsigned int)u[i] >> d) |
|
||||||
|
LHALF((unsigned int)u[i - 1] <<
|
||||||
|
(HALF_BITS - d)));
|
||||||
|
u[i] = 0;
|
||||||
|
}
|
||||||
|
tmp.ui[H] = COMBINE(uspace[1], uspace[2]);
|
||||||
|
tmp.ui[L] = COMBINE(uspace[3], uspace[4]);
|
||||||
|
*arq = tmp.ll;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp.ui[H] = COMBINE(qspace[1], qspace[2]);
|
||||||
|
tmp.ui[L] = COMBINE(qspace[3], qspace[4]);
|
||||||
|
return (tmp.ll);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shift p[0]..p[len] left `sh' bits, ignoring any bits that
|
||||||
|
* `fall out' the left (there never will be any such anyway).
|
||||||
|
* We may assume len >= 0. NOTE THAT THIS WRITES len+1 DIGITS.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
shl(digit *p, int len, int sh)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
p[i] = (digit)(LHALF((unsigned int)p[i] << sh) |
|
||||||
|
((unsigned int)p[i + 1] >> (HALF_BITS - sh)));
|
||||||
|
p[i] = (digit)(LHALF((unsigned int)p[i] << sh));
|
||||||
|
}
|
55
common/gcc-millicode/subdi3.c
Normal file
55
common/gcc-millicode/subdi3.c
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software was developed by the Computer Systems Engineering group
|
||||||
|
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||||
|
* contributed to Berkeley.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* From:
|
||||||
|
* @(#)subdi3.c 8.1 (Berkeley) 6/4/93
|
||||||
|
* NetBSD: subdi3.c,v 1.1 2005/12/20 19:28:51 christos Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "longlong.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Subtract two long long values. This is trivial since a one-bit
|
||||||
|
* carry from a single unsigned int difference x-y occurs if and only
|
||||||
|
* if (x-y) > x.
|
||||||
|
*/
|
||||||
|
long long
|
||||||
|
__subdi3(long long a, long long b)
|
||||||
|
{
|
||||||
|
union uu aa, bb, diff;
|
||||||
|
|
||||||
|
aa.ll = a;
|
||||||
|
bb.ll = b;
|
||||||
|
diff.ui[L] = aa.ui[L] - bb.ui[L];
|
||||||
|
diff.ui[H] = aa.ui[H] - bb.ui[H] - (diff.ui[L] > aa.ui[L]);
|
||||||
|
return (diff.ll);
|
||||||
|
}
|
53
common/gcc-millicode/ucmpdi2.c
Normal file
53
common/gcc-millicode/ucmpdi2.c
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software was developed by the Computer Systems Engineering group
|
||||||
|
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||||
|
* contributed to Berkeley.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* From:
|
||||||
|
* @(#)ucmpdi2.c 8.1 (Berkeley) 6/4/93
|
||||||
|
* NetBSD: ucmpdi2.c,v 1.1 2005/12/20 19:28:51 christos Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "longlong.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return 0, 1, or 2 as a <, =, > b respectively.
|
||||||
|
* Neither a nor b are considered signed.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
__ucmpdi2(unsigned long long a, unsigned long long b)
|
||||||
|
{
|
||||||
|
union uu aa, bb;
|
||||||
|
|
||||||
|
aa.ull = a;
|
||||||
|
bb.ull = b;
|
||||||
|
return (aa.ui[H] < bb.ui[H] ? 0 : aa.ui[H] > bb.ui[H] ? 2 :
|
||||||
|
aa.ui[L] < bb.ui[L] ? 0 : aa.ui[L] > bb.ui[L] ? 2 : 1);
|
||||||
|
}
|
48
common/gcc-millicode/udivdi3.c
Normal file
48
common/gcc-millicode/udivdi3.c
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software was developed by the Computer Systems Engineering group
|
||||||
|
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||||
|
* contributed to Berkeley.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* From:
|
||||||
|
* @(#)udivdi3.c 8.1 (Berkeley) 6/4/93
|
||||||
|
* NetBSD: udivdi3.c,v 1.1 2005/12/20 19:28:51 christos Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "longlong.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Divide two unsigned long longs.
|
||||||
|
*/
|
||||||
|
unsigned long long
|
||||||
|
__udivdi3(unsigned long long a, unsigned long long b)
|
||||||
|
{
|
||||||
|
|
||||||
|
return __qdivrem(a, b, NULL);
|
||||||
|
}
|
50
common/gcc-millicode/umoddi3.c
Normal file
50
common/gcc-millicode/umoddi3.c
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software was developed by the Computer Systems Engineering group
|
||||||
|
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||||
|
* contributed to Berkeley.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* From:
|
||||||
|
* @(#)umoddi3.c 8.1 (Berkeley) 6/4/93
|
||||||
|
* NetBSD: umoddi3.c,v 1.1 2005/12/20 19:28:51 christos Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "longlong.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return remainder after dividing two unsigned long longs.
|
||||||
|
*/
|
||||||
|
unsigned long long
|
||||||
|
__umoddi3(unsigned long long a, unsigned long long b)
|
||||||
|
{
|
||||||
|
unsigned long long r;
|
||||||
|
|
||||||
|
(void)__qdivrem(a, b, &r);
|
||||||
|
return (r);
|
||||||
|
}
|
53
common/gcc-millicode/xordi3.c
Normal file
53
common/gcc-millicode/xordi3.c
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software was developed by the Computer Systems Engineering group
|
||||||
|
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||||
|
* contributed to Berkeley.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* From:
|
||||||
|
* @(#)xordi3.c 8.1 (Berkeley) 6/4/93
|
||||||
|
* NetBSD: xordi3.c,v 1.1 2005/12/20 19:28:51 christos Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "longlong.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return a ^ b, in long long.
|
||||||
|
*/
|
||||||
|
long long
|
||||||
|
__xordi3(long long a, long long b)
|
||||||
|
{
|
||||||
|
union uu aa, bb;
|
||||||
|
|
||||||
|
aa.ll = a;
|
||||||
|
bb.ll = b;
|
||||||
|
aa.ui[0] ^= bb.ui[0];
|
||||||
|
aa.ui[1] ^= bb.ui[1];
|
||||||
|
return (aa.ll);
|
||||||
|
}
|
104
common/libc/arch/mips/setjmp.S
Normal file
104
common/libc/arch/mips/setjmp.S
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* setjmp and longjmp for MIPS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kern/mips/regdefs.h>
|
||||||
|
|
||||||
|
.text
|
||||||
|
.set noreorder
|
||||||
|
|
||||||
|
/*
|
||||||
|
* int setjmp(jmp_buf jb);
|
||||||
|
*
|
||||||
|
* Save the current state so we can return again from the call later
|
||||||
|
* if/when longjmp is called. (If the function that called setjmp
|
||||||
|
* returns before longjmp is called, the results are undefined. We
|
||||||
|
* only need to save registers, not the whole contents of the stack.)
|
||||||
|
*/
|
||||||
|
|
||||||
|
.globl setjmp
|
||||||
|
.type setjmp,@function
|
||||||
|
.ent setjmp
|
||||||
|
setjmp:
|
||||||
|
/*
|
||||||
|
* jmp_buf is in a0. We need to save s0-s8, sp, and ra in it.
|
||||||
|
* Don't store more registers without adjusting machine/setjmp.h.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sw sp, 0(a0) /* save registers */
|
||||||
|
sw ra, 4(a0)
|
||||||
|
sw s0, 8(a0)
|
||||||
|
sw s1, 12(a0)
|
||||||
|
sw s2, 16(a0)
|
||||||
|
sw s3, 20(a0)
|
||||||
|
sw s4, 24(a0)
|
||||||
|
sw s5, 28(a0)
|
||||||
|
sw s6, 32(a0)
|
||||||
|
sw s7, 36(a0)
|
||||||
|
sw s8, 40(a0)
|
||||||
|
|
||||||
|
j ra /* done */
|
||||||
|
li v0, 0 /* return 0 (in delay slot) */
|
||||||
|
.end setjmp
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* void longjmp(jmp_buf jb, int code);
|
||||||
|
*/
|
||||||
|
.globl longjmp
|
||||||
|
.type longjmp,@function
|
||||||
|
.ent longjmp
|
||||||
|
longjmp:
|
||||||
|
/*
|
||||||
|
* jmp_buf is in a0. Return code is in a1.
|
||||||
|
* We need to restore s0-s8, sp, and ra from the jmp_buf.
|
||||||
|
* The return code is forced to 1 if 0 is passed in.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sltiu t0, a1, 1 /* set t0 to 1 if return code is 0... otherwise 0 */
|
||||||
|
addu a1, a1, t0 /* update the return code */
|
||||||
|
|
||||||
|
lw sp, 0(a0) /* restore registers */
|
||||||
|
lw ra, 4(a0)
|
||||||
|
lw s0, 8(a0)
|
||||||
|
lw s1, 12(a0)
|
||||||
|
lw s2, 16(a0)
|
||||||
|
lw s3, 20(a0)
|
||||||
|
lw s4, 24(a0)
|
||||||
|
lw s5, 28(a0)
|
||||||
|
lw s6, 32(a0)
|
||||||
|
lw s7, 36(a0)
|
||||||
|
lw s8, 40(a0)
|
||||||
|
|
||||||
|
j ra /* return, to where setjmp was called from */
|
||||||
|
move v0, a1 /* set return value */
|
||||||
|
.end longjmp
|
592
common/libc/printf/__printf.c
Normal file
592
common/libc/printf/__printf.c
Normal file
@ -0,0 +1,592 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Guts of printf.
|
||||||
|
*
|
||||||
|
* This file is used in both libc and the kernel and needs to work in both
|
||||||
|
* contexts. This makes a few things a bit awkward.
|
||||||
|
*
|
||||||
|
* This is a slightly simplified version of the real-life printf
|
||||||
|
* originally used in the VINO kernel.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _KERNEL
|
||||||
|
#include <types.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#define assert KASSERT
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do we want to support "long long" types with %lld?
|
||||||
|
*
|
||||||
|
* Using 64-bit types with gcc causes gcc to emit calls to functions
|
||||||
|
* like __moddi3 and __divdi3. These need to be provided at link time,
|
||||||
|
* which can be a hassle; this switch is provided to help avoid
|
||||||
|
* needing them.
|
||||||
|
*/
|
||||||
|
#define USE_LONGLONG
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define a type that holds the longest signed integer we intend to support.
|
||||||
|
*/
|
||||||
|
#ifdef USE_LONGLONG
|
||||||
|
#define INTTYPE long long
|
||||||
|
#else
|
||||||
|
#define INTTYPE long
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Space for a long long in base 8, plus a NUL, plus one
|
||||||
|
* character extra for slop.
|
||||||
|
*
|
||||||
|
* CHAR_BIT is the number of bits in a char; thus sizeof(long long)*CHAR_BIT
|
||||||
|
* is the number of bits in a long long. Each octal digit prints 3 bits.
|
||||||
|
* Values printed in larger bases will be shorter strings.
|
||||||
|
*/
|
||||||
|
#define NUMBER_BUF_SIZE ((sizeof(INTTYPE) * CHAR_BIT) / 3 + 2)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure holding the state for printf.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/* Callback for sending printed string data */
|
||||||
|
void (*sendfunc)(void *clientdata, const char *str, size_t len);
|
||||||
|
void *clientdata;
|
||||||
|
|
||||||
|
/* The varargs argument pointer */
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
/* Total count of characters printed */
|
||||||
|
int charcount;
|
||||||
|
|
||||||
|
/* Flag that's true if we are currently looking in a %-format */
|
||||||
|
int in_pct;
|
||||||
|
|
||||||
|
/* Size of the integer argument to retrieve */
|
||||||
|
enum {
|
||||||
|
INTSZ,
|
||||||
|
LONGSZ,
|
||||||
|
#ifdef USE_LONGLONG
|
||||||
|
LLONGSZ,
|
||||||
|
#endif
|
||||||
|
SIZETSZ,
|
||||||
|
} size;
|
||||||
|
|
||||||
|
/* The value of the integer argument retrieved */
|
||||||
|
unsigned INTTYPE num;
|
||||||
|
|
||||||
|
/* Sign of the integer argument (0 = positive; -1 = negative) */
|
||||||
|
int sign;
|
||||||
|
|
||||||
|
/* Field width (number of spaces) */
|
||||||
|
int spacing;
|
||||||
|
|
||||||
|
/* Flag: align to left in field instead of right */
|
||||||
|
int rightspc;
|
||||||
|
|
||||||
|
/* Character to pad to field size with (space or 0) */
|
||||||
|
int fillchar;
|
||||||
|
|
||||||
|
/* Number base to print the integer argument in (8, 10, 16) */
|
||||||
|
int base;
|
||||||
|
|
||||||
|
/* Flag: if set, print 0x before hex and 0 before octal numbers */
|
||||||
|
int baseprefix;
|
||||||
|
|
||||||
|
/* Flag: alternative output format selected with %#... */
|
||||||
|
int altformat;
|
||||||
|
} PF;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send some text onward to the output.
|
||||||
|
*
|
||||||
|
* We count the total length we send out so we can return it from __vprintf,
|
||||||
|
* since that's what most printf-like functions want to return.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
void
|
||||||
|
__pf_print(PF *pf, const char *txt, size_t len)
|
||||||
|
{
|
||||||
|
pf->sendfunc(pf->clientdata, txt, len);
|
||||||
|
pf->charcount += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reset the state for the next %-field.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
void
|
||||||
|
__pf_endfield(PF *pf)
|
||||||
|
{
|
||||||
|
pf->in_pct = 0;
|
||||||
|
pf->size = INTSZ;
|
||||||
|
pf->num = 0;
|
||||||
|
pf->sign = 0;
|
||||||
|
pf->spacing = 0;
|
||||||
|
pf->rightspc = 0;
|
||||||
|
pf->fillchar = ' ';
|
||||||
|
pf->base = 0;
|
||||||
|
pf->baseprefix = 0;
|
||||||
|
pf->altformat = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process modifier chars (between the % and the type specifier)
|
||||||
|
* # use "alternate display format"
|
||||||
|
* - left align in field instead of right align
|
||||||
|
* l value is long (ll = long long)
|
||||||
|
* z value is size_t
|
||||||
|
* 0-9 field width
|
||||||
|
* leading 0 pad with zeros instead of spaces
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
void
|
||||||
|
__pf_modifier(PF *pf, int ch)
|
||||||
|
{
|
||||||
|
switch (ch) {
|
||||||
|
case '#':
|
||||||
|
pf->altformat = 1;
|
||||||
|
break;
|
||||||
|
case '-':
|
||||||
|
pf->rightspc = 1;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
if (pf->size==LONGSZ) {
|
||||||
|
#ifdef USE_LONGLONG
|
||||||
|
pf->size = LLONGSZ;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pf->size = LONGSZ;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'z':
|
||||||
|
pf->size = SIZETSZ;
|
||||||
|
break;
|
||||||
|
case '0':
|
||||||
|
if (pf->spacing>0) {
|
||||||
|
/*
|
||||||
|
* Already seen some digits; this is part of the
|
||||||
|
* field size.
|
||||||
|
*/
|
||||||
|
pf->spacing = pf->spacing*10;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*
|
||||||
|
* Leading zero; set the padding character to 0.
|
||||||
|
*/
|
||||||
|
pf->fillchar = '0';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
* Invalid characters should be filtered out by a
|
||||||
|
* higher-level function, so if this assert goes off
|
||||||
|
* it's our fault.
|
||||||
|
*/
|
||||||
|
assert(ch>'0' && ch<='9');
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Got a digit; accumulate the field size.
|
||||||
|
*/
|
||||||
|
pf->spacing = pf->spacing*10 + (ch-'0');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Retrieve a numeric argument from the argument list and store it
|
||||||
|
* in pf->num, according to the size recorded in pf->size and using
|
||||||
|
* the numeric type specified by ch.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
void
|
||||||
|
__pf_getnum(PF *pf, int ch)
|
||||||
|
{
|
||||||
|
if (ch=='p') {
|
||||||
|
/*
|
||||||
|
* Pointer.
|
||||||
|
*
|
||||||
|
* uintptr_t is a C99 standard type that's an unsigned
|
||||||
|
* integer the same size as a pointer.
|
||||||
|
*/
|
||||||
|
pf->num = (uintptr_t) va_arg(pf->ap, void *);
|
||||||
|
}
|
||||||
|
else if (ch=='d') {
|
||||||
|
/* signed integer */
|
||||||
|
INTTYPE signednum=0;
|
||||||
|
switch (pf->size) {
|
||||||
|
case INTSZ:
|
||||||
|
/* %d */
|
||||||
|
signednum = va_arg(pf->ap, int);
|
||||||
|
break;
|
||||||
|
case LONGSZ:
|
||||||
|
/* %ld */
|
||||||
|
signednum = va_arg(pf->ap, long);
|
||||||
|
break;
|
||||||
|
#ifdef USE_LONGLONG
|
||||||
|
case LLONGSZ:
|
||||||
|
/* %lld */
|
||||||
|
signednum = va_arg(pf->ap, long long);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case SIZETSZ:
|
||||||
|
/* %zd */
|
||||||
|
signednum = va_arg(pf->ap, ssize_t);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for negative numbers.
|
||||||
|
*/
|
||||||
|
if (signednum < 0) {
|
||||||
|
pf->sign = -1;
|
||||||
|
pf->num = -signednum;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pf->num = signednum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* unsigned integer */
|
||||||
|
switch (pf->size) {
|
||||||
|
case INTSZ:
|
||||||
|
/* %u (or %o, %x) */
|
||||||
|
pf->num = va_arg(pf->ap, unsigned int);
|
||||||
|
break;
|
||||||
|
case LONGSZ:
|
||||||
|
/* %lu (or %lo, %lx) */
|
||||||
|
pf->num = va_arg(pf->ap, unsigned long);
|
||||||
|
break;
|
||||||
|
#ifdef USE_LONGLONG
|
||||||
|
case LLONGSZ:
|
||||||
|
/* %llu, %llo, %llx */
|
||||||
|
pf->num = va_arg(pf->ap, unsigned long long);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case SIZETSZ:
|
||||||
|
/* %zu, %zo, %zx */
|
||||||
|
pf->num = va_arg(pf->ap, size_t);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the printing base based on the numeric type specified in ch.
|
||||||
|
* %o octal
|
||||||
|
* %d,%u decimal
|
||||||
|
* %x hex
|
||||||
|
* %p pointer (print as hex)
|
||||||
|
*
|
||||||
|
* If the "alternate format" was requested, or always for pointers,
|
||||||
|
* note to print the C prefix for the type.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
void
|
||||||
|
__pf_setbase(PF *pf, int ch)
|
||||||
|
{
|
||||||
|
switch (ch) {
|
||||||
|
case 'd':
|
||||||
|
case 'u':
|
||||||
|
pf->base = 10;
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
case 'p':
|
||||||
|
pf->base = 16;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
pf->base = 8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (pf->altformat || ch=='p') {
|
||||||
|
pf->baseprefix = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function to print "spc" instances of the fill character.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
void
|
||||||
|
__pf_fill(PF *pf, int spc)
|
||||||
|
{
|
||||||
|
char f = pf->fillchar;
|
||||||
|
int i;
|
||||||
|
for (i=0; i<spc; i++) {
|
||||||
|
__pf_print(pf, &f, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* General printing function. Prints the string "stuff".
|
||||||
|
* The two prefixes (in practice one is a type prefix, such as "0x",
|
||||||
|
* and the other is the sign) get printed *after* space padding but
|
||||||
|
* *before* zero padding, if padding is on the left.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
void
|
||||||
|
__pf_printstuff(PF *pf,
|
||||||
|
const char *prefix, const char *prefix2,
|
||||||
|
const char *stuff)
|
||||||
|
{
|
||||||
|
/* Total length to print. */
|
||||||
|
int len = strlen(prefix)+strlen(prefix2)+strlen(stuff);
|
||||||
|
|
||||||
|
/* Get field width and compute amount of padding in "spc". */
|
||||||
|
int spc = pf->spacing;
|
||||||
|
if (spc > len) {
|
||||||
|
spc -= len;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
spc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If padding on left and the fill char is not 0, pad first. */
|
||||||
|
if (spc > 0 && pf->rightspc==0 && pf->fillchar!='0') {
|
||||||
|
__pf_fill(pf, spc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print the prefixes. */
|
||||||
|
__pf_print(pf, prefix, strlen(prefix));
|
||||||
|
__pf_print(pf, prefix2, strlen(prefix2));
|
||||||
|
|
||||||
|
/* If padding on left and the fill char *is* 0, pad here. */
|
||||||
|
if (spc > 0 && pf->rightspc==0 && pf->fillchar=='0') {
|
||||||
|
__pf_fill(pf, spc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print the actual string. */
|
||||||
|
__pf_print(pf, stuff, strlen(stuff));
|
||||||
|
|
||||||
|
/* If padding on the right, pad afterwards. */
|
||||||
|
if (spc > 0 && pf->rightspc!=0) {
|
||||||
|
__pf_fill(pf, spc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function to convert a number to ascii and then print it.
|
||||||
|
*
|
||||||
|
* Works from right to left in a buffer of NUMBER_BUF_SIZE bytes.
|
||||||
|
* NUMBER_BUF_SIZE is set so that the longest number string we can
|
||||||
|
* generate (a long long printed in octal) will fit. See above.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
void
|
||||||
|
__pf_printnum(PF *pf)
|
||||||
|
{
|
||||||
|
/* Digits to print with. */
|
||||||
|
const char *const digits = "0123456789abcdef";
|
||||||
|
|
||||||
|
char buf[NUMBER_BUF_SIZE]; /* Accumulation buffer for string. */
|
||||||
|
char *x; /* Current pointer into buf. */
|
||||||
|
unsigned INTTYPE xnum; /* Current value to print. */
|
||||||
|
const char *bprefix; /* Base prefix (0, 0x, or nothing) */
|
||||||
|
const char *sprefix; /* Sign prefix (- or nothing) */
|
||||||
|
|
||||||
|
/* Start in the last slot of the buffer. */
|
||||||
|
x = buf+sizeof(buf)-1;
|
||||||
|
|
||||||
|
/* Insert null terminator. */
|
||||||
|
*x-- = 0;
|
||||||
|
|
||||||
|
/* Initialize value. */
|
||||||
|
xnum = pf->num;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert a single digit.
|
||||||
|
* Do this loop at least once - that way 0 prints as 0 and not "".
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
/*
|
||||||
|
* Get the digit character for the least significant
|
||||||
|
* part of xnum.
|
||||||
|
*/
|
||||||
|
*x = digits[xnum % pf->base];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Back up the pointer to point to the next space to the left.
|
||||||
|
*/
|
||||||
|
x--;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Drop the value of the digit we just printed from xnum.
|
||||||
|
*/
|
||||||
|
xnum = xnum / pf->base;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If xnum hits 0 there's no more number left.
|
||||||
|
*/
|
||||||
|
} while (xnum > 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* x points to the *next* slot in the buffer to use.
|
||||||
|
* However, we're done printing the number. So it's pointing
|
||||||
|
* one slot *before* the start of the actual number text.
|
||||||
|
* So advance it by one so it actually points at the number.
|
||||||
|
*/
|
||||||
|
x++;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a base prefix was requested, select it.
|
||||||
|
*/
|
||||||
|
if (pf->baseprefix && pf->base==16) {
|
||||||
|
bprefix = "0x";
|
||||||
|
}
|
||||||
|
else if (pf->baseprefix && pf->base==8) {
|
||||||
|
bprefix = "0";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bprefix = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Choose the sign prefix.
|
||||||
|
*/
|
||||||
|
sprefix = pf->sign ? "-" : "";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now actually print the string we just generated.
|
||||||
|
*/
|
||||||
|
__pf_printstuff(pf, sprefix, bprefix, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process a single character out of the format string.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
void
|
||||||
|
__pf_send(PF *pf, int ch)
|
||||||
|
{
|
||||||
|
/* Cannot get NULs here. */
|
||||||
|
assert(ch!=0);
|
||||||
|
|
||||||
|
if (pf->in_pct==0 && ch!='%') {
|
||||||
|
/*
|
||||||
|
* Not currently in a format, and not a %. Just send
|
||||||
|
* the character on through.
|
||||||
|
*/
|
||||||
|
char c = ch;
|
||||||
|
__pf_print(pf, &c, 1);
|
||||||
|
}
|
||||||
|
else if (pf->in_pct==0) {
|
||||||
|
/*
|
||||||
|
* Not in a format, but got a %. Start a format.
|
||||||
|
*/
|
||||||
|
pf->in_pct = 1;
|
||||||
|
}
|
||||||
|
else if (strchr("#-lz0123456789", ch)) {
|
||||||
|
/*
|
||||||
|
* These are the modifier characters we recognize.
|
||||||
|
* (These are the characters between the % and the type.)
|
||||||
|
*/
|
||||||
|
__pf_modifier(pf, ch);
|
||||||
|
}
|
||||||
|
else if (strchr("doupx", ch)) {
|
||||||
|
/*
|
||||||
|
* Integer types.
|
||||||
|
* Fetch the number, set the base, print it, then
|
||||||
|
* reset for the next format.
|
||||||
|
*/
|
||||||
|
__pf_getnum(pf, ch);
|
||||||
|
__pf_setbase(pf, ch);
|
||||||
|
__pf_printnum(pf);
|
||||||
|
__pf_endfield(pf);
|
||||||
|
}
|
||||||
|
else if (ch=='s') {
|
||||||
|
/*
|
||||||
|
* Print a string.
|
||||||
|
*/
|
||||||
|
const char *str = va_arg(pf->ap, const char *);
|
||||||
|
if (str==NULL) {
|
||||||
|
str = "(null)";
|
||||||
|
}
|
||||||
|
__pf_printstuff(pf, "", "", str);
|
||||||
|
__pf_endfield(pf);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*
|
||||||
|
* %%, %c, or illegal character.
|
||||||
|
* Illegal characters are printed like %%.
|
||||||
|
* for example, %5k prints " k".
|
||||||
|
*/
|
||||||
|
char x[2];
|
||||||
|
if (ch=='c') {
|
||||||
|
x[0] = va_arg(pf->ap, int);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x[0] = ch;
|
||||||
|
}
|
||||||
|
x[1] = 0;
|
||||||
|
__pf_printstuff(pf, "", "", x);
|
||||||
|
__pf_endfield(pf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do a whole printf session.
|
||||||
|
* Create and initialize a printf state object,
|
||||||
|
* then send it each character from the format string.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
__vprintf(void (*func)(void *clientdata, const char *str, size_t len),
|
||||||
|
void *clientdata, const char *format, va_list ap)
|
||||||
|
{
|
||||||
|
PF pf;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
pf.sendfunc = func;
|
||||||
|
pf.clientdata = clientdata;
|
||||||
|
#ifdef va_copy
|
||||||
|
va_copy(pf.ap, ap);
|
||||||
|
#else
|
||||||
|
pf.ap = ap;
|
||||||
|
#endif
|
||||||
|
pf.charcount = 0;
|
||||||
|
__pf_endfield(&pf);
|
||||||
|
|
||||||
|
for (i=0; format[i]; i++) {
|
||||||
|
__pf_send(&pf, format[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pf.charcount;
|
||||||
|
}
|
157
common/libc/printf/snprintf.c
Normal file
157
common/libc/printf/snprintf.c
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is shared between libc and the kernel, so don't put anything
|
||||||
|
* in here that won't work in both contexts.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _KERNEL
|
||||||
|
#include <types.h>
|
||||||
|
#include <lib.h>
|
||||||
|
|
||||||
|
#else
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#endif /* _KERNEL */
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Standard C string/IO function: printf into a character buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Context structure for snprintf: buffer to print into, maximum
|
||||||
|
* length, and index of the next character to write.
|
||||||
|
*
|
||||||
|
* Note that while the length argument to snprintf includes space for
|
||||||
|
* a null terminator, SNP.buflen does not. This is to make something
|
||||||
|
* vaguely reasonable happen if a length of 0 is passed to snprintf.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *buf;
|
||||||
|
size_t buflen;
|
||||||
|
size_t bufpos;
|
||||||
|
} SNP;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send function for snprintf. This is the function handed to the
|
||||||
|
* printf guts. It gets called with mydata pointing to the context,
|
||||||
|
* and some string data of length LEN in DATA. DATA is not necessarily
|
||||||
|
* null-terminated.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
__snprintf_send(void *mydata, const char *data, size_t len)
|
||||||
|
{
|
||||||
|
SNP *snp = mydata;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
/* For each character we're sent... */
|
||||||
|
for (i=0; i<len; i++) {
|
||||||
|
|
||||||
|
/* If we aren't past the length, */
|
||||||
|
if (snp->bufpos < snp->buflen) {
|
||||||
|
|
||||||
|
/* store the character */
|
||||||
|
snp->buf[snp->bufpos] = data[i];
|
||||||
|
|
||||||
|
/* and increment the position. */
|
||||||
|
snp->bufpos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The va_list version of snprintf.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
vsnprintf(char *buf, size_t len, const char *fmt, va_list ap)
|
||||||
|
{
|
||||||
|
int chars;
|
||||||
|
SNP snp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fill in the context structure.
|
||||||
|
* We set snp.buflen to the number of characters that can be
|
||||||
|
* written (excluding the null terminator) so as not to have
|
||||||
|
* to special-case the possibility that we got passed a length
|
||||||
|
* of zero elsewhere.
|
||||||
|
*/
|
||||||
|
snp.buf = buf;
|
||||||
|
if (len==0) {
|
||||||
|
snp.buflen = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
snp.buflen = len-1;
|
||||||
|
}
|
||||||
|
snp.bufpos = 0;
|
||||||
|
|
||||||
|
/* Call __vprintf to do the actual work. */
|
||||||
|
chars = __vprintf(__snprintf_send, &snp, fmt, ap);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a null terminator. If the length *we were passed* is greater
|
||||||
|
* than zero, we reserved a space in the buffer for the terminator,
|
||||||
|
* so this won't overflow. If the length we were passed is zero,
|
||||||
|
* nothing will have been or should be written anyway, and buf
|
||||||
|
* might even be NULL. (C99 explicitly endorses this possibility.)
|
||||||
|
*/
|
||||||
|
if (len > 0) {
|
||||||
|
buf[snp.bufpos] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the number of characters __vprintf processed.
|
||||||
|
* According to C99, snprintf should return this number, not
|
||||||
|
* the number of characters actually stored, and should not
|
||||||
|
* return -1 on overflow but only on other errors. (All none
|
||||||
|
* of them since we don't do multibyte characters...)
|
||||||
|
*/
|
||||||
|
return chars;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* snprintf - hand off to vsnprintf.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
snprintf(char *buf, size_t len, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
int chars;
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
chars = vsnprintf(buf, len, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
return chars;
|
||||||
|
}
|
||||||
|
|
101
common/libc/stdlib/atoi.c
Normal file
101
common/libc/stdlib/atoi.c
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is shared between libc and the kernel, so don't put anything
|
||||||
|
* in here that won't work in both contexts.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _KERNEL
|
||||||
|
#include <types.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#else
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Standard C function: parse a string that represents a decimal integer.
|
||||||
|
* Leading whitespace is allowed. Trailing gunk is allowed too. Doesn't
|
||||||
|
* really report syntax errors or overflow in any useful way.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
atoi(const char *s)
|
||||||
|
{
|
||||||
|
static const char digits[] = "0123456789"; /* legal digits in order */
|
||||||
|
unsigned val=0; /* value we're accumulating */
|
||||||
|
int neg=0; /* set to true if we see a minus sign */
|
||||||
|
|
||||||
|
/* skip whitespace */
|
||||||
|
while (*s==' ' || *s=='\t') {
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for sign */
|
||||||
|
if (*s=='-') {
|
||||||
|
neg=1;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
else if (*s=='+') {
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* process each digit */
|
||||||
|
while (*s) {
|
||||||
|
const char *where;
|
||||||
|
unsigned digit;
|
||||||
|
|
||||||
|
/* look for the digit in the list of digits */
|
||||||
|
where = strchr(digits, *s);
|
||||||
|
if (where==NULL) {
|
||||||
|
/* not found; not a digit, so stop */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the index into the digit list, which is the value */
|
||||||
|
digit = (where - digits);
|
||||||
|
|
||||||
|
/* could (should?) check for overflow here */
|
||||||
|
|
||||||
|
/* shift the number over and add in the new digit */
|
||||||
|
val = val*10 + digit;
|
||||||
|
|
||||||
|
/* look at the next character */
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* handle negative numbers */
|
||||||
|
if (neg) {
|
||||||
|
return -val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* done */
|
||||||
|
return val;
|
||||||
|
}
|
76
common/libc/string/bzero.c
Normal file
76
common/libc/string/bzero.c
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is shared between libc and the kernel, so don't put anything
|
||||||
|
* in here that won't work in both contexts.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _KERNEL
|
||||||
|
#include <types.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#else
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Standard (well, semi-standard) C string function - zero a block of
|
||||||
|
* memory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
bzero(void *vblock, size_t len)
|
||||||
|
{
|
||||||
|
char *block = vblock;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For performance, optimize the common case where the pointer
|
||||||
|
* and the length are word-aligned, and write word-at-a-time
|
||||||
|
* instead of byte-at-a-time. Otherwise, write bytes.
|
||||||
|
*
|
||||||
|
* The alignment logic here should be portable. We rely on the
|
||||||
|
* compiler to be reasonably intelligent about optimizing the
|
||||||
|
* divides and moduli out. Fortunately, it is.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((uintptr_t)block % sizeof(long) == 0 &&
|
||||||
|
len % sizeof(long) == 0) {
|
||||||
|
long *lb = (long *)block;
|
||||||
|
for (i=0; i<len/sizeof(long); i++) {
|
||||||
|
lb[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (i=0; i<len; i++) {
|
||||||
|
block[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
86
common/libc/string/memcpy.c
Normal file
86
common/libc/string/memcpy.c
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is shared between libc and the kernel, so don't put anything
|
||||||
|
* in here that won't work in both contexts.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _KERNEL
|
||||||
|
#include <types.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#else
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* C standard function - copy a block of memory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void *
|
||||||
|
memcpy(void *dst, const void *src, size_t len)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* memcpy does not support overlapping buffers, so always do it
|
||||||
|
* forwards. (Don't change this without adjusting memmove.)
|
||||||
|
*
|
||||||
|
* For speedy copying, optimize the common case where both pointers
|
||||||
|
* and the length are word-aligned, and copy word-at-a-time instead
|
||||||
|
* of byte-at-a-time. Otherwise, copy by bytes.
|
||||||
|
*
|
||||||
|
* The alignment logic below should be portable. We rely on
|
||||||
|
* the compiler to be reasonably intelligent about optimizing
|
||||||
|
* the divides and modulos out. Fortunately, it is.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((uintptr_t)dst % sizeof(long) == 0 &&
|
||||||
|
(uintptr_t)src % sizeof(long) == 0 &&
|
||||||
|
len % sizeof(long) == 0) {
|
||||||
|
|
||||||
|
long *d = dst;
|
||||||
|
const long *s = src;
|
||||||
|
|
||||||
|
for (i=0; i<len/sizeof(long); i++) {
|
||||||
|
d[i] = s[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
char *d = dst;
|
||||||
|
const char *s = src;
|
||||||
|
|
||||||
|
for (i=0; i<len; i++) {
|
||||||
|
d[i] = s[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
117
common/libc/string/memmove.c
Normal file
117
common/libc/string/memmove.c
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is shared between libc and the kernel, so don't put anything
|
||||||
|
* in here that won't work in both contexts.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _KERNEL
|
||||||
|
#include <types.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#else
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* C standard function - copy a block of memory, handling overlapping
|
||||||
|
* regions correctly.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void *
|
||||||
|
memmove(void *dst, const void *src, size_t len)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the buffers don't overlap, it doesn't matter what direction
|
||||||
|
* we copy in. If they do, it does, so just assume they always do.
|
||||||
|
* We don't concern ourselves with the possibility that the region
|
||||||
|
* to copy might roll over across the top of memory, because it's
|
||||||
|
* not going to happen.
|
||||||
|
*
|
||||||
|
* If the destination is above the source, we have to copy
|
||||||
|
* back to front to avoid overwriting the data we want to
|
||||||
|
* copy.
|
||||||
|
*
|
||||||
|
* dest: dddddddd
|
||||||
|
* src: ssssssss ^
|
||||||
|
* | ^ |___|
|
||||||
|
* |___|
|
||||||
|
*
|
||||||
|
* If the destination is below the source, we have to copy
|
||||||
|
* front to back.
|
||||||
|
*
|
||||||
|
* dest: dddddddd
|
||||||
|
* src: ^ ssssssss
|
||||||
|
* |___| ^ |
|
||||||
|
* |___|
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((uintptr_t)dst < (uintptr_t)src) {
|
||||||
|
/*
|
||||||
|
* As author/maintainer of libc, take advantage of the
|
||||||
|
* fact that we know memcpy copies forwards.
|
||||||
|
*/
|
||||||
|
return memcpy(dst, src, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy by words in the common case. Look in memcpy.c for more
|
||||||
|
* information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((uintptr_t)dst % sizeof(long) == 0 &&
|
||||||
|
(uintptr_t)src % sizeof(long) == 0 &&
|
||||||
|
len % sizeof(long) == 0) {
|
||||||
|
|
||||||
|
long *d = dst;
|
||||||
|
const long *s = src;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The reason we copy index i-1 and test i>0 is that
|
||||||
|
* i is unsigned -- so testing i>=0 doesn't work.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (i=len/sizeof(long); i>0; i--) {
|
||||||
|
d[i-1] = s[i-1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
char *d = dst;
|
||||||
|
const char *s = src;
|
||||||
|
|
||||||
|
for (i=len; i>0; i--) {
|
||||||
|
d[i-1] = s[i-1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
52
common/libc/string/memset.c
Normal file
52
common/libc/string/memset.c
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _KERNEL
|
||||||
|
#include <types.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#else
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* C standard function - initialize a block of memory
|
||||||
|
*/
|
||||||
|
|
||||||
|
void *
|
||||||
|
memset(void *ptr, int ch, size_t len)
|
||||||
|
{
|
||||||
|
char *p = ptr;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i=0; i<len; i++) {
|
||||||
|
p[i] = ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
54
common/libc/string/strcat.c
Normal file
54
common/libc/string/strcat.c
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is shared between libc and the kernel, so don't put anything
|
||||||
|
* in here that won't work in both contexts.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _KERNEL
|
||||||
|
#include <types.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#else
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Standard C string function: append one string to another.
|
||||||
|
*/
|
||||||
|
|
||||||
|
char *
|
||||||
|
strcat(char *dest, const char *src)
|
||||||
|
{
|
||||||
|
size_t offset;
|
||||||
|
|
||||||
|
offset = strlen(dest);
|
||||||
|
strcpy(dest+offset, src);
|
||||||
|
return dest;
|
||||||
|
}
|
68
common/libc/string/strchr.c
Normal file
68
common/libc/string/strchr.c
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is shared between libc and the kernel, so don't put anything
|
||||||
|
* in here that won't work in both contexts.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _KERNEL
|
||||||
|
#include <types.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#else
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* C standard string function: find leftmost instance of a character
|
||||||
|
* in a string.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
strchr(const char *s, int ch_arg)
|
||||||
|
{
|
||||||
|
/* avoid sign-extension problems */
|
||||||
|
const char ch = ch_arg;
|
||||||
|
|
||||||
|
/* scan from left to right */
|
||||||
|
while (*s) {
|
||||||
|
/* if we hit it, return it */
|
||||||
|
if (*s == ch) {
|
||||||
|
return (char *)s;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we were looking for the 0, return that */
|
||||||
|
if (*s == ch) {
|
||||||
|
return (char *)s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* didn't find it */
|
||||||
|
return NULL;
|
||||||
|
}
|
90
common/libc/string/strcmp.c
Normal file
90
common/libc/string/strcmp.c
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is shared between libc and the kernel, so don't put anything
|
||||||
|
* in here that won't work in both contexts.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _KERNEL
|
||||||
|
#include <types.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#else
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Standard C string function: compare two strings and return their
|
||||||
|
* sort order.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
strcmp(const char *a, const char *b)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Walk down both strings until either they're different
|
||||||
|
* or we hit the end of A.
|
||||||
|
*
|
||||||
|
* If A and B strings are not the same length, when the
|
||||||
|
* shorter one ends, the two will be different, and we'll
|
||||||
|
* stop before running off the end of either.
|
||||||
|
*
|
||||||
|
* If they *are* the same length, it's sufficient to check
|
||||||
|
* that we haven't run off the end of A, because that's the
|
||||||
|
* same as checking to make sure we haven't run off the end of
|
||||||
|
* B.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (i=0; a[i]!=0 && a[i]==b[i]; i++) {
|
||||||
|
/* nothing */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If A is greater than B, return 1. If A is less than B,
|
||||||
|
* return -1. If they're the same, return 0. Since we have
|
||||||
|
* stopped at the first character of difference (or the end of
|
||||||
|
* both strings) checking the character under I accomplishes
|
||||||
|
* this.
|
||||||
|
*
|
||||||
|
* Note that strcmp does not handle accented characters,
|
||||||
|
* internationalization, or locale sort order; strcoll() does
|
||||||
|
* that.
|
||||||
|
*
|
||||||
|
* The rules say we compare order in terms of *unsigned* char.
|
||||||
|
*/
|
||||||
|
if ((unsigned char)a[i] > (unsigned char)b[i]) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (a[i] == b[i]) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
63
common/libc/string/strcpy.c
Normal file
63
common/libc/string/strcpy.c
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is shared between libc and the kernel, so don't put anything
|
||||||
|
* in here that won't work in both contexts.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _KERNEL
|
||||||
|
#include <types.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#else
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Standard C string function: copy one string to another.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
strcpy(char *dest, const char *src)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy characters until we hit the null terminator.
|
||||||
|
*/
|
||||||
|
for (i=0; src[i]; i++) {
|
||||||
|
dest[i] = src[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add null terminator to result.
|
||||||
|
*/
|
||||||
|
dest[i] = 0;
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
55
common/libc/string/strlen.c
Normal file
55
common/libc/string/strlen.c
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is shared between libc and the kernel, so don't put anything
|
||||||
|
* in here that won't work in both contexts.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _KERNEL
|
||||||
|
#include <types.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#else
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* C standard string function: get length of a string
|
||||||
|
*/
|
||||||
|
|
||||||
|
size_t
|
||||||
|
strlen(const char *str)
|
||||||
|
{
|
||||||
|
size_t ret = 0;
|
||||||
|
|
||||||
|
while (str[ret]) {
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
69
common/libc/string/strrchr.c
Normal file
69
common/libc/string/strrchr.c
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is shared between libc and the kernel, so don't put anything
|
||||||
|
* in here that won't work in both contexts.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _KERNEL
|
||||||
|
#include <types.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#else
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* C standard string function: find rightmost instance of a character
|
||||||
|
* in a string.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
strrchr(const char *s, int ch_arg)
|
||||||
|
{
|
||||||
|
/* avoid sign-extension problems */
|
||||||
|
const char ch = ch_arg;
|
||||||
|
|
||||||
|
/* start one past the last character INCLUDING NULL TERMINATOR */
|
||||||
|
size_t i = strlen(s)+1;
|
||||||
|
|
||||||
|
/* go from right to left; stop at 0 */
|
||||||
|
while (i > 0) {
|
||||||
|
|
||||||
|
/* decrement first */
|
||||||
|
i--;
|
||||||
|
|
||||||
|
/* now check the character we're over */
|
||||||
|
if (s[i] == ch) {
|
||||||
|
return (char *)(s+i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* didn't find it */
|
||||||
|
return NULL;
|
||||||
|
}
|
96
common/libc/string/strtok_r.c
Normal file
96
common/libc/string/strtok_r.c
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is shared between libc and the kernel, so don't put anything
|
||||||
|
* in here that won't work in both contexts.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _KERNEL
|
||||||
|
#include <types.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#else
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Standard C string function: tokenize a string splitting based on a
|
||||||
|
* list of separator characters. Reentrant version.
|
||||||
|
*
|
||||||
|
* The "context" argument should point to a "char *" that is preserved
|
||||||
|
* between calls to strtok_r that wish to operate on same string.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
strtok_r(char *string, const char *seps, char **context)
|
||||||
|
{
|
||||||
|
char *head; /* start of word */
|
||||||
|
char *tail; /* end of word */
|
||||||
|
|
||||||
|
/* If we're starting up, initialize context */
|
||||||
|
if (string) {
|
||||||
|
*context = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get potential start of this next word */
|
||||||
|
head = *context;
|
||||||
|
if (head == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip any leading separators */
|
||||||
|
while (*head && strchr(seps, *head)) {
|
||||||
|
head++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Did we hit the end? */
|
||||||
|
if (*head == 0) {
|
||||||
|
/* Nothing left */
|
||||||
|
*context = NULL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* skip over word */
|
||||||
|
tail = head;
|
||||||
|
while (*tail && !strchr(seps, *tail)) {
|
||||||
|
tail++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save head for next time in context */
|
||||||
|
if (*tail == 0) {
|
||||||
|
*context = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*tail = 0;
|
||||||
|
tail++;
|
||||||
|
*context = tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return current word */
|
||||||
|
return head;
|
||||||
|
}
|
199
configure
vendored
Executable file
199
configure
vendored
Executable file
@ -0,0 +1,199 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Configure script for OS/161 tree.
|
||||||
|
# This generates the file "defs.mk" at the top level of the tree.
|
||||||
|
#
|
||||||
|
# Usage: ./configure [options]
|
||||||
|
# where you can get a list of the options by doing ./configure --help.
|
||||||
|
#
|
||||||
|
# Must be run with the top of the OS/161 tree as its current directory.
|
||||||
|
#
|
||||||
|
# Note: while this superficially acts like a GNU Autoconf configure
|
||||||
|
# script, it was not generated by autoconf. Scripts generated by
|
||||||
|
# autoconf are much harder to read. :-)
|
||||||
|
#
|
||||||
|
# If this script bombs out, you can create defs.mk by hand based on
|
||||||
|
# the comments in mk/os161.config.mk.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Target hardware platform and machine type.
|
||||||
|
PLATFORM='sys161'
|
||||||
|
MACHINE='mips'
|
||||||
|
|
||||||
|
# Default optimize/debug flag: optimize.
|
||||||
|
DEBUG='-O2'
|
||||||
|
|
||||||
|
# Default location of the root of the installed system.
|
||||||
|
# Note that we quote it such that the reference to the home directory
|
||||||
|
# is a make variable, not a shell variable. This means it gets expanded
|
||||||
|
# when make runs rather than when this script runs.
|
||||||
|
OSTREE='$(HOME)/os161/root'
|
||||||
|
|
||||||
|
# By default don't explicitly configure a Python interpreter.
|
||||||
|
PYTHON_INTERPRETER=
|
||||||
|
|
||||||
|
# Assume this
|
||||||
|
HOST_CC=gcc
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
|
||||||
|
#
|
||||||
|
# Check to make sure we're in the right place.
|
||||||
|
|
||||||
|
if [ ! -d kern/main ]; then
|
||||||
|
echo 'Please run configure from the top of the OS/161 tree.'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# Process the command-line options.
|
||||||
|
|
||||||
|
while [ "x$1" != x ]; do
|
||||||
|
case "$1" in
|
||||||
|
--debug) DEBUG='-g';;
|
||||||
|
--ostree=*) OSTREE=`echo $1 | sed 's,^[^=]*=,,'`;;
|
||||||
|
--help|*)
|
||||||
|
more <<EOF
|
||||||
|
Usage: ./configure [options]
|
||||||
|
where the options are:
|
||||||
|
--help Print this message.
|
||||||
|
|
||||||
|
--debug Compile the user-level programs with debug info.
|
||||||
|
This is disabled by default because there's no
|
||||||
|
support for userlevel source debugging in OS/161.
|
||||||
|
(Note: debug info in the kernel is controlled by
|
||||||
|
the kernel config file.)
|
||||||
|
|
||||||
|
--ostree=PATH Install the compiled system in a directory tree
|
||||||
|
rooted at PATH. Default is \$HOME/os161/root.
|
||||||
|
EOF
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
# Check if the host system supports 4.4BSD <err.h>.
|
||||||
|
|
||||||
|
printf "Checking for <err.h>... "
|
||||||
|
|
||||||
|
cat > __conftest.c <<EOF
|
||||||
|
#include <err.h>
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
err(0, "works");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
OK=0
|
||||||
|
if $HOST_CC __conftest.c -o __conftest >/dev/null 2>&1; then
|
||||||
|
if ./__conftest >/dev/null 2>&1; then
|
||||||
|
OK=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f __conf*
|
||||||
|
|
||||||
|
if [ $OK = 1 ]; then
|
||||||
|
echo 'yes'
|
||||||
|
else
|
||||||
|
echo 'no'
|
||||||
|
COMPAT_CFLAGS="${COMPATCFLAGS} -DNEED_ERR"
|
||||||
|
COMPAT_TARGETS="${HOSTTARGETS} install-errh"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Check if the host system has ntohll() and htonll().
|
||||||
|
|
||||||
|
printf "Checking for ntohll()..."
|
||||||
|
|
||||||
|
cat > __conftest.c <<EOF
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
int ok = ntohll(0xbeefbeefbeefbeefULL) != 0;
|
||||||
|
return !ok; /* exit(0) for success */
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
OK=0
|
||||||
|
if $HOST_CC __conftest.c -o __conftest >/dev/null 2>&1; then
|
||||||
|
if ./__conftest >/dev/null 2>&1; then
|
||||||
|
OK=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f __conf*
|
||||||
|
|
||||||
|
if [ $OK = 1 ]; then
|
||||||
|
echo 'yes'
|
||||||
|
else
|
||||||
|
echo 'no'
|
||||||
|
COMPAT_CFLAGS="${COMPATCFLAGS} -DNEED_NTOHLL"
|
||||||
|
HOST_CFLAGS="${HOST_CFLAGS} -DDECLARE_NTOHLL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Look for a Python interpreter.
|
||||||
|
PYTHON=
|
||||||
|
for PYNAME in \
|
||||||
|
python python2.7 \
|
||||||
|
/usr/local/bin/python /usr/local/bin/python2.7 \
|
||||||
|
/usr/pkg/bin/python /usr/pkg/bin/python2.7 \
|
||||||
|
/opt/bin/python /opt/bin/python2.7 \
|
||||||
|
; do
|
||||||
|
PYVERSION=`($PYNAME -V) 2>&1 || echo none`
|
||||||
|
case "$PYVERSION" in
|
||||||
|
Python\ 2.*|Python\ 3.*) PYTHON=$PYNAME;;
|
||||||
|
none) ;;
|
||||||
|
*) ;; # ?
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
case "$PYTHON" in
|
||||||
|
python) ;;
|
||||||
|
/*) PYTHON_INTERPRETER="$PYTHON";;
|
||||||
|
*) PYTHON_INTERPRETER="/usr/bin/env $PYTHON";;
|
||||||
|
esac
|
||||||
|
|
||||||
|
####################
|
||||||
|
|
||||||
|
# Now generate defs.mk.
|
||||||
|
|
||||||
|
echo 'Generating defs.mk.'
|
||||||
|
|
||||||
|
(
|
||||||
|
# First, put an explanatory comment at the top.
|
||||||
|
cat <<EOF
|
||||||
|
# This file was generated by configure. Edits will disappear if you rerun
|
||||||
|
# configure. If you find that you need to edit this file to make things
|
||||||
|
# work, let the course staff know and we'll try to fix the configure script.
|
||||||
|
#
|
||||||
|
# The purpose of this file is to hold all the makefile definitions
|
||||||
|
# needed to adjust the OS/161 build process to any particular
|
||||||
|
# environment. If I've done it right, all you need to do is rerun the
|
||||||
|
# configure script and make clean if you start working on a different
|
||||||
|
# host OS. If I've done it mostly right, you may need to edit this
|
||||||
|
# file but you still hopefully won't need to edit any of the
|
||||||
|
# makefiles.
|
||||||
|
#
|
||||||
|
# The things that can be set here are documented in mk/os161.config.mk.
|
||||||
|
#
|
||||||
|
|
||||||
|
EOF
|
||||||
|
echo "OSTREE=${OSTREE}"
|
||||||
|
echo "PLATFORM=${PLATFORM}"
|
||||||
|
echo "MACHINE=${MACHINE}"
|
||||||
|
echo "COMPAT_CFLAGS=${COMPAT_CFLAGS}"
|
||||||
|
echo "COMPAT_TARGETS=${COMPAT_TARGETS}"
|
||||||
|
if [ "x$HOST_CFLAGS" != x ]; then
|
||||||
|
echo "HOST_CFLAGS+=$HOST_CFLAGS"
|
||||||
|
fi
|
||||||
|
if [ "x$PYTHON_INTERPRETER" != x ]; then
|
||||||
|
echo "PYTHON_INTERPRETER=$PYTHON_INTERPRETER"
|
||||||
|
fi
|
||||||
|
|
||||||
|
) > defs.mk
|
22
defs.mk
Normal file
22
defs.mk
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# This file was generated by configure. Edits will disappear if you rerun
|
||||||
|
# configure. If you find that you need to edit this file to make things
|
||||||
|
# work, let the course staff know and we'll try to fix the configure script.
|
||||||
|
#
|
||||||
|
# The purpose of this file is to hold all the makefile definitions
|
||||||
|
# needed to adjust the OS/161 build process to any particular
|
||||||
|
# environment. If I've done it right, all you need to do is rerun the
|
||||||
|
# configure script and make clean if you start working on a different
|
||||||
|
# host OS. If I've done it mostly right, you may need to edit this
|
||||||
|
# file but you still hopefully won't need to edit any of the
|
||||||
|
# makefiles.
|
||||||
|
#
|
||||||
|
# The things that can be set here are documented in mk/os161.config.mk.
|
||||||
|
#
|
||||||
|
|
||||||
|
OSTREE=/root/os161/root
|
||||||
|
PLATFORM=sys161
|
||||||
|
MACHINE=mips
|
||||||
|
COMPAT_CFLAGS= -DNEED_NTOHLL
|
||||||
|
COMPAT_TARGETS=
|
||||||
|
HOST_CFLAGS+= -DDECLARE_NTOHLL
|
||||||
|
PYTHON_INTERPRETER=/usr/bin/env
|
120
design/assignments.txt
Normal file
120
design/assignments.txt
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
The (potential) OS/161 assignments
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
OS/161 is used by a wide variety of courses at a wide variety of
|
||||||
|
schools, no two of which have the exact same set of assignments and
|
||||||
|
assignment requirements. The code base has been (to the extent
|
||||||
|
reasonably possible) structured to allow this and not assume any
|
||||||
|
particular structure or (particularly) numbering of assignments.
|
||||||
|
|
||||||
|
That said, in various places comments and documentation must (to be
|
||||||
|
helpful, at least) refer to particular assignments and things that are
|
||||||
|
(typically) done in particular assignments. These are written in
|
||||||
|
fairly general terms. This file is provided as an index for those
|
||||||
|
terms.
|
||||||
|
|
||||||
|
*** Always refer to the course materials provided by your ***
|
||||||
|
*** instructors when trying to figure out what functionality ***
|
||||||
|
*** you are and are not required to implement. ***
|
||||||
|
|
||||||
|
Note that the OS/161 code base you are given may include solutions for
|
||||||
|
some parts of the assignments described below, or even some whole
|
||||||
|
assignments.
|
||||||
|
|
||||||
|
Also note that the text below refers to assorted technical terms and
|
||||||
|
OS concepts without much or any explanation; you may not be familiar
|
||||||
|
with most of them at first and that's perfectly ok.
|
||||||
|
|
||||||
|
|
||||||
|
OS/161 is intended to support six basic assignments, most of which can
|
||||||
|
be divided into smaller pieces. These six assignments are:
|
||||||
|
|
||||||
|
- synchronization;
|
||||||
|
- basic system calls;
|
||||||
|
- virtual memory;
|
||||||
|
- basic file system functionality;
|
||||||
|
- file system recovery via journaling;
|
||||||
|
- some additional piece of OS functionality.
|
||||||
|
|
||||||
|
|
||||||
|
Synchronization.
|
||||||
|
|
||||||
|
This assignment has (potentially) three parts:
|
||||||
|
- Implement (sleep) locks and condition variables.
|
||||||
|
- Implement reader-writer locks.
|
||||||
|
- Solve some synchronization problems of the dining-philosophers
|
||||||
|
variety.
|
||||||
|
|
||||||
|
|
||||||
|
Basic system calls. (And processes.)
|
||||||
|
|
||||||
|
This assignment has (potentially) up to six parts:
|
||||||
|
- Implement file tables and open-file objects.
|
||||||
|
- Implement the basic system calls for files, normally:
|
||||||
|
- open()
|
||||||
|
- dup2()
|
||||||
|
- read()
|
||||||
|
- write()
|
||||||
|
- lseek()
|
||||||
|
- close()
|
||||||
|
- chdir()
|
||||||
|
- __getcwd()
|
||||||
|
- Implement processes, process IDs, and the basic process system
|
||||||
|
calls, normally:
|
||||||
|
- getpid()
|
||||||
|
- fork()
|
||||||
|
- _exit()
|
||||||
|
- waitpid()
|
||||||
|
- Implement the execv() system call.
|
||||||
|
- Implement a scheduler.
|
||||||
|
|
||||||
|
|
||||||
|
Virtual memory.
|
||||||
|
|
||||||
|
This assignment entails replacing a provided very simple virtual
|
||||||
|
memory system with a real one. This possibly includes providing the
|
||||||
|
sbrk() system call. It does not split into parts readily.
|
||||||
|
|
||||||
|
|
||||||
|
Basic file system functionality.
|
||||||
|
|
||||||
|
This assignment has (potentially) up to five parts:
|
||||||
|
- Add more system calls for file system operations, typically taken
|
||||||
|
from these:
|
||||||
|
- sync()
|
||||||
|
- mkdir()
|
||||||
|
- rmdir()
|
||||||
|
- remove()
|
||||||
|
- link()
|
||||||
|
- rename()
|
||||||
|
- getdirentry()
|
||||||
|
- fstat()
|
||||||
|
- fsync()
|
||||||
|
- ftruncate()
|
||||||
|
- flock()
|
||||||
|
although others may be chosen.
|
||||||
|
- Implement a buffer cache.
|
||||||
|
- Replace a biglock with fine-grained locking in the VFS layer
|
||||||
|
and/or the SFS file system.
|
||||||
|
- Add support for subdirectories to SFS.
|
||||||
|
- Implement cross-directory rename in SFS.
|
||||||
|
- Implement larger files in SFS.
|
||||||
|
|
||||||
|
|
||||||
|
File system recovery via journaling.
|
||||||
|
|
||||||
|
This assignment has (potentially) five parts:
|
||||||
|
- Implement an on-disk container for a file system journal.
|
||||||
|
- Instrument the buffer cache to support write-ahead journaling.
|
||||||
|
- Design a system of journal records suitable for recovering the
|
||||||
|
file system after a crash.
|
||||||
|
- Add code to SFS to issue these journal records.
|
||||||
|
- Implement code to read the on-disk journal and recover from a
|
||||||
|
crash.
|
||||||
|
|
||||||
|
|
||||||
|
Additional projects.
|
||||||
|
|
||||||
|
There is a wide variety of things that can be done to build on the
|
||||||
|
above assignments. None are listed here, because this file is not
|
||||||
|
the place for it.
|
55
design/shell.txt
Normal file
55
design/shell.txt
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
SHELL DESIGN NOTES
|
||||||
|
------------------
|
||||||
|
|
||||||
|
The shell has few bells and whistles. It allows up to 128
|
||||||
|
backgrounded jobs (after this point you have to wait for some to exit,
|
||||||
|
because the table it uses to track these cannot be resized.)
|
||||||
|
|
||||||
|
The background jobs are tracked in an array of MAXBG pid_t's. If an
|
||||||
|
open slot is found, a background job's pid can be stashed there.
|
||||||
|
Background jobs can be collected using the "wait" built-in command,
|
||||||
|
which removes any pids whose exit status it collects from the
|
||||||
|
background jobs table.
|
||||||
|
|
||||||
|
The wait built-in command takes an optional argument, the process
|
||||||
|
id to wait for. The shell will attempt to wait for any process, not
|
||||||
|
just the ones it actually started as its own background jobs. However,
|
||||||
|
since no facility exists for looking up the pids of running processes,
|
||||||
|
this ability is not necessarily useful. If no argument is provided,
|
||||||
|
wait waits for all outstanding background jobs.
|
||||||
|
|
||||||
|
The shell uses WNOHANG if WNOHANG is defined, in which case
|
||||||
|
background jobs are polled after every command, like in Unix shells.
|
||||||
|
If WNOHANG is not defined, background jobs are polled only by user
|
||||||
|
request. In OS/161 2.0, WNOHANG is always defined in the kernel header
|
||||||
|
files, but the implementation is only suggested, not required. To make
|
||||||
|
the shell stop trying to use WNOHANG, patch it, or remove WNOHANG from
|
||||||
|
kern/wait.h.
|
||||||
|
|
||||||
|
There are two other built-in commands: chdir, which uses the chdir
|
||||||
|
system call to change directory, and can also be accessed as just cd,
|
||||||
|
and exit, which causes the shell to exit with a specified exit status
|
||||||
|
(0 if not supplied).
|
||||||
|
|
||||||
|
Note that all these built-in commands must be built into the shell
|
||||||
|
in order to work usefully.
|
||||||
|
|
||||||
|
The shell processes commands by reading lines and then splitting
|
||||||
|
them up into words using whitespace characters (space, tab, carriage
|
||||||
|
return, and newline) as separators. No punctuation characters are
|
||||||
|
interpreted, except for `&'. No variable substitution or argument
|
||||||
|
wildcard expansion ("globbing") is performed.
|
||||||
|
|
||||||
|
The `&' character, if present as the last word on a command line,
|
||||||
|
is treated as the "background" operator: the command is run as a
|
||||||
|
background job, that is, after starting it the shell immediately
|
||||||
|
prints another prompt and accepts more commands. Note that the `&'
|
||||||
|
must be preceded by whitespace to be recognized. The process id of the
|
||||||
|
background job is printed as it starts. Note that shell builtins
|
||||||
|
cannot be backgrounded; furthermore, because the OS/161 console does
|
||||||
|
not support job control, starting background jobs that perform
|
||||||
|
terminal input (or, to a lesser extent, terminal output) may produce
|
||||||
|
confusing and/or unwanted results.
|
||||||
|
|
||||||
|
The shell also supports the "sh -c COMMAND" syntax in the hopes
|
||||||
|
that it will be useful.
|
24
design/usermalloc.txt
Normal file
24
design/usermalloc.txt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
User-level malloc
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
The user-level malloc implementation is defined to be simple, not
|
||||||
|
fast or efficient. It uses a very basic first-fit block algorithm.
|
||||||
|
|
||||||
|
There's an 8-byte header which holds the offsets to the previous
|
||||||
|
and next blocks, a used/free bit, and some magic numbers (for
|
||||||
|
consistency checking) in the remaining available header bits. It also
|
||||||
|
allocates in units of 8 bytes to guarantee proper alignment of
|
||||||
|
doubles. (It also assumes its own headers are aligned on 8-byte
|
||||||
|
boundaries.)
|
||||||
|
|
||||||
|
On malloc(), it searches the entire heap starting at the beginning
|
||||||
|
for the first block big enough to hold the allocation. If it doesn't
|
||||||
|
find one, it calls sbrk() to get more memory. If it does find one, it
|
||||||
|
marks the block in use. It splits the remaining portion of the block
|
||||||
|
off as a new free block only if said portion is large enough to hold
|
||||||
|
both a header and some data.
|
||||||
|
|
||||||
|
On free(), it marks the block free and then tries to merge it with
|
||||||
|
the adjacent blocks (both above and below) if they're free.
|
||||||
|
|
||||||
|
That's about all there is to it.
|
17
kern/Makefile
Normal file
17
kern/Makefile
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#
|
||||||
|
# Toplevel makefile for the OS/161 kernel tree.
|
||||||
|
#
|
||||||
|
# Note: actual kernels are not compiled here; they are compiled in
|
||||||
|
# compile/FOO where FOO is a kernel configuration name.
|
||||||
|
#
|
||||||
|
# We don't actually do anything from here except install includes.
|
||||||
|
#
|
||||||
|
|
||||||
|
TOP=..
|
||||||
|
.include "$(TOP)/mk/os161.config.mk"
|
||||||
|
|
||||||
|
INCLUDES=\
|
||||||
|
include/kern include/kern \
|
||||||
|
arch/$(MACHINE)/include/kern include/kern/$(MACHINE)
|
||||||
|
|
||||||
|
.include "$(TOP)/mk/os161.includes.mk"
|
79
kern/arch/mips/conf/conf.arch
Normal file
79
kern/arch/mips/conf/conf.arch
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
|
||||||
|
#
|
||||||
|
# The machine dependent sources for MIPS.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Standard C functions
|
||||||
|
machine mips file ../common/libc/arch/mips/setjmp.S
|
||||||
|
|
||||||
|
# 64-bit integer ops support for gcc
|
||||||
|
machine mips file ../common/gcc-millicode/adddi3.c
|
||||||
|
machine mips file ../common/gcc-millicode/anddi3.c
|
||||||
|
machine mips file ../common/gcc-millicode/ashldi3.c
|
||||||
|
machine mips file ../common/gcc-millicode/ashrdi3.c
|
||||||
|
machine mips file ../common/gcc-millicode/cmpdi2.c
|
||||||
|
machine mips file ../common/gcc-millicode/divdi3.c
|
||||||
|
machine mips file ../common/gcc-millicode/iordi3.c
|
||||||
|
machine mips file ../common/gcc-millicode/lshldi3.c
|
||||||
|
machine mips file ../common/gcc-millicode/lshrdi3.c
|
||||||
|
machine mips file ../common/gcc-millicode/moddi3.c
|
||||||
|
machine mips file ../common/gcc-millicode/muldi3.c
|
||||||
|
machine mips file ../common/gcc-millicode/negdi2.c
|
||||||
|
machine mips file ../common/gcc-millicode/notdi2.c
|
||||||
|
machine mips file ../common/gcc-millicode/qdivrem.c
|
||||||
|
machine mips file ../common/gcc-millicode/subdi3.c
|
||||||
|
machine mips file ../common/gcc-millicode/ucmpdi2.c
|
||||||
|
machine mips file ../common/gcc-millicode/udivdi3.c
|
||||||
|
machine mips file ../common/gcc-millicode/umoddi3.c
|
||||||
|
machine mips file ../common/gcc-millicode/xordi3.c
|
||||||
|
|
||||||
|
#
|
||||||
|
# Low-level stuff ("locore")
|
||||||
|
# The platform should select cache handling and exception handling from
|
||||||
|
# among these:
|
||||||
|
#
|
||||||
|
# cache-mips1.S
|
||||||
|
# cache-mips161.S
|
||||||
|
# cache-mips32.S
|
||||||
|
#
|
||||||
|
# exception-mips1.S
|
||||||
|
# exception-mips32.S
|
||||||
|
#
|
||||||
|
|
||||||
|
machine mips file arch/mips/locore/trap.c # Common trap handler.
|
||||||
|
|
||||||
|
#
|
||||||
|
# Thread subsystem
|
||||||
|
#
|
||||||
|
|
||||||
|
machine mips file arch/mips/thread/cpu.c # CPU control.
|
||||||
|
machine mips file arch/mips/thread/switch.S # Thread context switch
|
||||||
|
machine mips file arch/mips/thread/switchframe.c # New thread prep
|
||||||
|
machine mips file arch/mips/thread/thread_machdep.c # MD thread code
|
||||||
|
machine mips file arch/mips/thread/threadstart.S # New thread startup
|
||||||
|
|
||||||
|
#
|
||||||
|
# VM system
|
||||||
|
# The platform should select TLB handling from among these:
|
||||||
|
#
|
||||||
|
# tlb-mips1.S
|
||||||
|
# tlb-mips161.S
|
||||||
|
# tlb-mips32.S
|
||||||
|
#
|
||||||
|
|
||||||
|
machine mips file arch/mips/vm/ram.c # Physical memory accounting
|
||||||
|
|
||||||
|
# This is included here rather than in conf.kern because
|
||||||
|
# it may not be suitable for all architectures.
|
||||||
|
machine mips file vm/copyinout.c # copyin/out et al.
|
||||||
|
|
||||||
|
# For the early assignments, we supply a very stupid MIPS-only skeleton
|
||||||
|
# of a VM system. It is just barely capable of running a single userlevel
|
||||||
|
# program as long as that program's not very large.
|
||||||
|
defoption dumbvm
|
||||||
|
machine mips optfile dumbvm arch/mips/vm/dumbvm.c
|
||||||
|
|
||||||
|
#
|
||||||
|
# System call layer
|
||||||
|
#
|
||||||
|
machine mips file arch/mips/syscall/syscall.c # System call handler
|
98
kern/arch/mips/conf/ldscript
Normal file
98
kern/arch/mips/conf/ldscript
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* This is a pile of crap that tells the linker how to link the kernel,
|
||||||
|
* because it's too stupid to be able to work it out on its own.
|
||||||
|
*/
|
||||||
|
ENTRY(__start)
|
||||||
|
|
||||||
|
_DYNAMIC_LINK = 0;
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Base address for the kernel.
|
||||||
|
*/
|
||||||
|
. = 0x80000200;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read-only loaded sections.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* code */
|
||||||
|
.text : { *(.text) }
|
||||||
|
|
||||||
|
/* linker-provided symbol for end of code */
|
||||||
|
_etext = .;
|
||||||
|
|
||||||
|
/* read-only data */
|
||||||
|
.rodata : { *(.rodata) *(.rodata.*) }
|
||||||
|
|
||||||
|
/* MIPS register-usage blather */
|
||||||
|
.reginfo : { *(.reginfo) }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Move to a fresh page. This method puts read-only and
|
||||||
|
* read-write material on separate pages without having to
|
||||||
|
* waste space on page-alignment in the on-disk file; the
|
||||||
|
* on-disk page that contains both text and data is mapped
|
||||||
|
* twice.
|
||||||
|
*
|
||||||
|
* For mips kernels we can't write-protect the text anyhow so
|
||||||
|
* there's no point doing it.
|
||||||
|
*/
|
||||||
|
/* . = . + 0x1000; */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read-write loaded sections.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* initialized data */
|
||||||
|
.data : {
|
||||||
|
*(.data)
|
||||||
|
CONSTRUCTORS
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Value for GP register */
|
||||||
|
_gp = ALIGN(16) + 0x7ff0;
|
||||||
|
|
||||||
|
/* Small data accessed via GP register */
|
||||||
|
.lit8 : { *(.lit8) }
|
||||||
|
.lit4 : { *(.lit4) }
|
||||||
|
.sdata : { *(.sdata) }
|
||||||
|
|
||||||
|
/* cleared-to-zero data */
|
||||||
|
.sbss : { *(.sbss *.scommon) }
|
||||||
|
.bss : { *(.bss) *(COMMON) }
|
||||||
|
|
||||||
|
/* linker-provided symbol for end of program */
|
||||||
|
_end = .;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Debug info
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* stabs debug sections */
|
||||||
|
.stab 0: { *(.stab) }
|
||||||
|
.stabstr 0: { *(.stabstr) }
|
||||||
|
|
||||||
|
/* DWARF debug sections */
|
||||||
|
.debug 0: { *(.debug) }
|
||||||
|
.line 0: { *(.line) }
|
||||||
|
.debug_srcinfo 0: { *(.debug_srcinfo) }
|
||||||
|
.debug_sfnames 0: { *(.debug_sfnames) }
|
||||||
|
.debug_aranges 0: { *(.debug_aranges) }
|
||||||
|
.debug_pubnames 0: { *(.debug_pubnames) }
|
||||||
|
.debug_info 0: { *(.debug_info .gnu.linkonce.wi.*) }
|
||||||
|
.debug_abbrev 0: { *(.debug_abbrev) }
|
||||||
|
.debug_line 0: { *(.debug_line) }
|
||||||
|
.debug_frame 0: { *(.debug_frame) }
|
||||||
|
.debug_str 0: { *(.debug_str) }
|
||||||
|
.debug_loc 0: { *(.debug_loc) }
|
||||||
|
.debug_macinfo 0: { *(.debug_macinfo) }
|
||||||
|
.debug_weaknames 0: { *(.debug_weaknames) }
|
||||||
|
.debug_funcnames 0: { *(.debug_funcnames) }
|
||||||
|
.debug_typenames 0: { *(.debug_typenames) }
|
||||||
|
.debug_varnames 0: { *(.debug_varnames) }
|
||||||
|
|
||||||
|
/* These must appear regardless of . */
|
||||||
|
.gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
|
||||||
|
.gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
|
||||||
|
}
|
73
kern/arch/mips/include/current.h
Normal file
73
kern/arch/mips/include/current.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MIPS_CURRENT_H_
|
||||||
|
#define _MIPS_CURRENT_H_
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Macro for current thread, or current cpu.
|
||||||
|
*
|
||||||
|
* This file should only be included via <current.h> (q.v.)
|
||||||
|
*
|
||||||
|
* On mips we track the current thread. There's an architectural
|
||||||
|
* issue that informs this choice: there's no easy way to find the
|
||||||
|
* current cpu, the current thread, or even the kernel stack of the
|
||||||
|
* current thread when entering the kernel at trap time. (On most CPUs
|
||||||
|
* there's a canonical way to find at least the stack.)
|
||||||
|
*
|
||||||
|
* Therefore we do the following:
|
||||||
|
*
|
||||||
|
* - We misuse a kernel-settable field of a nonessential MMU register
|
||||||
|
* to hold the CPU number.
|
||||||
|
*
|
||||||
|
* - On trap entry we use this number to index an array that gets us
|
||||||
|
* both the kernel stack and curthread.
|
||||||
|
*
|
||||||
|
* - We tell the compiler not to use the s7 register and keep
|
||||||
|
* curthread there.
|
||||||
|
*
|
||||||
|
* Note that if you want to change this scheme to use a different
|
||||||
|
* register, or change to a different scheme, you need to touch three
|
||||||
|
* places: here, the mips-specific kernel CFLAGS in the makefiles, and
|
||||||
|
* the trap entry and return code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
register struct thread *curthread __asm("$23"); /* s7 register */
|
||||||
|
#else
|
||||||
|
#error "Don't know how to declare curthread in this compiler"
|
||||||
|
#endif
|
||||||
|
#undef __NEED_CURTHREAD
|
||||||
|
#define __NEED_CURCPU
|
||||||
|
|
||||||
|
/* For how we've defined it, curthread gets set first, then curcpu. */
|
||||||
|
#define INIT_CURCPU(cpu, thread) (curthread = (thread), curcpu = (cpu))
|
||||||
|
|
||||||
|
#endif /* _MIPS_CURRENT_H_ */
|
58
kern/arch/mips/include/elf.h
Normal file
58
kern/arch/mips/include/elf.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MIPS_ELF_H_
|
||||||
|
#define _MIPS_ELF_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MIPS machine-dependent definitions for the ELF binary format.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* The ELF executable type. */
|
||||||
|
#define EM_MACHINE EM_MIPS
|
||||||
|
|
||||||
|
/* Linker relocation codes. SIZE DESCRIPTION */
|
||||||
|
#define R_MIPS_NONE 0 /* --- nop */
|
||||||
|
#define R_MIPS_16 1 /* u16 value */
|
||||||
|
#define R_MIPS_32 2 /* u32 value */
|
||||||
|
#define R_MIPS_REL32 3 /* u32 value relative to patched address */
|
||||||
|
#define R_MIPS_26 4 /* u26 j/jal instruction address field */
|
||||||
|
#define R_MIPS_HI16 5 /* u16 %hi(sym) as below */
|
||||||
|
#define R_MIPS_LO16 6 /* s16 %lo(sym) as below */
|
||||||
|
#define R_MIPS_GPREL16 7 /* s16 offset from GP register */
|
||||||
|
#define R_MIPS_LITERAL 8 /* s16 GPREL16 for file-local symbols (?) */
|
||||||
|
#define R_MIPS_GOT16 9 /* u16 offset into global offset table */
|
||||||
|
#define R_MIPS_PC16 10 /* s16 PC-relative reference */
|
||||||
|
#define R_MIPS_CALL16 11 /* u16 call through global offset table */
|
||||||
|
#define R_MIPS_GPREL32 12 /* s32 offset from GP register */
|
||||||
|
/* %hi/%lo are defined so %hi(sym) << 16 + %lo(sym) = sym */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _MIPS_ELF_H_ */
|
44
kern/arch/mips/include/kern/endian.h
Normal file
44
kern/arch/mips/include/kern/endian.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _KERN_MIPS_ENDIAN_H_
|
||||||
|
#define _KERN_MIPS_ENDIAN_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Endianness. While the MIPS can be either big-endian (mipseb) or
|
||||||
|
* little-endian (mipsel), at least for now we only do mipseb.
|
||||||
|
*
|
||||||
|
* This file should only be included via <kern/endian.h> which in turn
|
||||||
|
* should be gotten via <endian.h> in the kernel or <arpa/inet.h> in
|
||||||
|
* userland.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _BYTE_ORDER _BIG_ENDIAN
|
||||||
|
|
||||||
|
#endif /* _KERN_MIPS_ENDIAN_H_ */
|
74
kern/arch/mips/include/kern/regdefs.h
Normal file
74
kern/arch/mips/include/kern/regdefs.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Macros for general-purpose register numbers for MIPS.
|
||||||
|
*
|
||||||
|
* Exported to userlevel because it's ~standard for that architecture.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _KERN_MIPS_REGDEFS_H_
|
||||||
|
#define _KERN_MIPS_REGDEFS_H_
|
||||||
|
|
||||||
|
|
||||||
|
#define z0 $0 /* always zero register */
|
||||||
|
#define AT $1 /* assembler temp register */
|
||||||
|
#define v0 $2 /* value 0 */
|
||||||
|
#define v1 $3 /* value 1 */
|
||||||
|
#define a0 $4 /* argument 0 */
|
||||||
|
#define a1 $5 /* argument 1 */
|
||||||
|
#define a2 $6 /* argument 2 */
|
||||||
|
#define a3 $7 /* argument 3 */
|
||||||
|
#define t0 $8 /* temporary (caller-save) 0 */
|
||||||
|
#define t1 $9 /* temporary (caller-save) 1 */
|
||||||
|
#define t2 $10 /* temporary (caller-save) 2 */
|
||||||
|
#define t3 $11 /* temporary (caller-save) 3 */
|
||||||
|
#define t4 $12 /* temporary (caller-save) 4 */
|
||||||
|
#define t5 $13 /* temporary (caller-save) 5 */
|
||||||
|
#define t6 $14 /* temporary (caller-save) 6 */
|
||||||
|
#define t7 $15 /* temporary (caller-save) 7 */
|
||||||
|
#define s0 $16 /* saved (callee-save) 0 */
|
||||||
|
#define s1 $17 /* saved (callee-save) 1 */
|
||||||
|
#define s2 $18 /* saved (callee-save) 2 */
|
||||||
|
#define s3 $19 /* saved (callee-save) 3 */
|
||||||
|
#define s4 $20 /* saved (callee-save) 4 */
|
||||||
|
#define s5 $21 /* saved (callee-save) 5 */
|
||||||
|
#define s6 $22 /* saved (callee-save) 6 */
|
||||||
|
#define s7 $23 /* saved (callee-save) 7 */
|
||||||
|
#define t8 $24 /* temporary (caller-save) 8 */
|
||||||
|
#define t9 $25 /* temporary (caller-save) 9 */
|
||||||
|
#define k0 $26 /* kernel temporary 0 */
|
||||||
|
#define k1 $27 /* kernel temporary 1 */
|
||||||
|
#define gp $28 /* global pointer */
|
||||||
|
#define sp $29 /* stack pointer */
|
||||||
|
#define s8 $30 /* saved (callee-save) 8 = frame pointer */
|
||||||
|
#define ra $31 /* return address */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _KERN_MIPS_REGDEFS_H_ */
|
47
kern/arch/mips/include/kern/setjmp.h
Normal file
47
kern/arch/mips/include/kern/setjmp.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MIPS_SETJMP_H_
|
||||||
|
#define _MIPS_SETJMP_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MIPS jmp_buf definition.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Must save: s0-s8, sp, ra (11 registers)
|
||||||
|
* Don't change __JB_REGS without adjusting mips_setjmp.S accordingly.
|
||||||
|
*/
|
||||||
|
#define __JB_REGS 11
|
||||||
|
|
||||||
|
/* A jmp_buf is an array of __JB_REGS registers */
|
||||||
|
typedef uint32_t jmp_buf[__JB_REGS];
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _MIPS_SETJMP_H_ */
|
45
kern/arch/mips/include/kern/signal.h
Normal file
45
kern/arch/mips/include/kern/signal.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _KERN_MIPS_SIGNAL_H_
|
||||||
|
#define _KERN_MIPS_SIGNAL_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure used to hold the register values for returning from a
|
||||||
|
* userland signal handler - basically the saved register values from
|
||||||
|
* whatever userlevel execution context the signal interrupted. Fill
|
||||||
|
* this in as needed, if you ever implement signal handlers. (Which you
|
||||||
|
* probably won't.)
|
||||||
|
*/
|
||||||
|
struct sigcontext {
|
||||||
|
/* Dummy. */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _KERN_MIPS_SIGNAL_H_ */
|
78
kern/arch/mips/include/kern/types.h
Normal file
78
kern/arch/mips/include/kern/types.h
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _KERN_MIPS_TYPES_H_
|
||||||
|
#define _KERN_MIPS_TYPES_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Machine-dependent types visible to userland.
|
||||||
|
* (Kernel-only types should go in mips/types.h.)
|
||||||
|
* 32-bit MIPS version.
|
||||||
|
*
|
||||||
|
* See kern/types.h for an explanation of the underscores.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Sized integer types, with convenient short names */
|
||||||
|
typedef char __i8; /* 8-bit signed integer */
|
||||||
|
typedef short __i16; /* 16-bit signed integer */
|
||||||
|
typedef int __i32; /* 32-bit signed integer */
|
||||||
|
typedef long long __i64; /* 64-bit signed integer */
|
||||||
|
|
||||||
|
typedef unsigned char __u8; /* 8-bit unsigned integer */
|
||||||
|
typedef unsigned short __u16; /* 16-bit unsigned integer */
|
||||||
|
typedef unsigned int __u32; /* 32-bit unsigned integer */
|
||||||
|
typedef unsigned long long __u64; /* 64-bit unsigned integer */
|
||||||
|
|
||||||
|
/* Further standard C types */
|
||||||
|
typedef long __intptr_t; /* Signed pointer-sized integer */
|
||||||
|
typedef unsigned long __uintptr_t; /* Unsigned pointer-sized integer */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since we're a 32-bit platform, size_t, ssize_t, and ptrdiff_t can
|
||||||
|
* correctly be either (unsigned) int or (unsigned) long. However, if we
|
||||||
|
* don't define it to the same one gcc is using, gcc will get
|
||||||
|
* upset. If you switch compilers and see otherwise unexplicable type
|
||||||
|
* errors involving size_t, try changing this.
|
||||||
|
*/
|
||||||
|
#if 1
|
||||||
|
typedef unsigned __size_t; /* Size of a memory region */
|
||||||
|
typedef int __ssize_t; /* Signed type of same size */
|
||||||
|
typedef int __ptrdiff_t; /* Difference of two pointers */
|
||||||
|
#else
|
||||||
|
typedef unsigned long __size_t; /* Size of a memory region */
|
||||||
|
typedef long __ssize_t; /* Signed type of same size */
|
||||||
|
typedef long __ptrdiff_t; /* Difference of two pointers */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Number of bits per byte. */
|
||||||
|
#define __CHAR_BIT 8
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _KERN_MIPS_TYPES_H_ */
|
63
kern/arch/mips/include/membar.h
Normal file
63
kern/arch/mips/include/membar.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MIPS_MEMBAR_H_
|
||||||
|
#define _MIPS_MEMBAR_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On the mips there's only one memory barrier instruction, so these
|
||||||
|
* are all the same. This is not true on many other CPUs (x86, arm,
|
||||||
|
* sparc, powerpc, etc.) We also mark the instruction as a compiler-
|
||||||
|
* level barrier by telling gcc that it destroys memory; this prevents
|
||||||
|
* gcc from reordering loads and stores around it.
|
||||||
|
*
|
||||||
|
* See include/membar.h for further information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MEMBAR_INLINE
|
||||||
|
void
|
||||||
|
membar_any_any(void)
|
||||||
|
{
|
||||||
|
__asm volatile(
|
||||||
|
".set push;" /* save assembler mode */
|
||||||
|
".set mips32;" /* allow MIPS32 instructions */
|
||||||
|
"sync;" /* do it */
|
||||||
|
".set pop" /* restore assembler mode */
|
||||||
|
: /* no outputs */
|
||||||
|
: /* no inputs */
|
||||||
|
: "memory"); /* "changes" memory */
|
||||||
|
}
|
||||||
|
|
||||||
|
MEMBAR_INLINE void membar_load_load(void) { membar_any_any(); }
|
||||||
|
MEMBAR_INLINE void membar_store_store(void) { membar_any_any(); }
|
||||||
|
MEMBAR_INLINE void membar_store_any(void) { membar_any_any(); }
|
||||||
|
MEMBAR_INLINE void membar_any_store(void) { membar_any_any(); }
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _MIPS_MEMBAR_H_ */
|
117
kern/arch/mips/include/specialreg.h
Normal file
117
kern/arch/mips/include/specialreg.h
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MIPS_SPECIALREG_H_
|
||||||
|
#define _MIPS_SPECIALREG_H_
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Coprocessor 0 (system processor) register numbers
|
||||||
|
*/
|
||||||
|
#define c0_index $0 /* TLB entry index register */
|
||||||
|
#define c0_random $1 /* TLB random slot register */
|
||||||
|
#define c0_entrylo $2 /* TLB entry contents (low-order half) */
|
||||||
|
/* c0_entrylo0 $2 */ /* MIPS-II and up only */
|
||||||
|
/* c0_entrylo1 $3 */ /* MIPS-II and up only */
|
||||||
|
#define c0_context $4 /* some precomputed pagetable stuff */
|
||||||
|
/* c0_pagemask $5 */ /* MIPS-II and up only */
|
||||||
|
/* c0_wired $6 */ /* MIPS-II and up only */
|
||||||
|
#define c0_vaddr $8 /* virtual addr of failing memory access */
|
||||||
|
#define c0_count $9 /* cycle counter (MIPS-II and up) */
|
||||||
|
#define c0_entryhi $10 /* TLB entry contents (high-order half) */
|
||||||
|
#define c0_compare $11 /* on-chip timer control (MIPS-II and up) */
|
||||||
|
#define c0_status $12 /* processor status register */
|
||||||
|
#define c0_cause $13 /* exception cause register */
|
||||||
|
#define c0_epc $14 /* exception PC register */
|
||||||
|
#define c0_prid $15 /* processor ID register */
|
||||||
|
/* c0_config $16 */ /* MIPS-II and up only */
|
||||||
|
/* c0_lladdr $17 */ /* MIPS-II and up only */
|
||||||
|
/* c0_watchlo $18 */ /* MIPS-II and up only */
|
||||||
|
/* c0_watchhi $19 */ /* MIPS-II and up only */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mode bits in c0_status
|
||||||
|
*/
|
||||||
|
#define CST_IEc 0x00000001 /* current: interrupt enable */
|
||||||
|
#define CST_KUc 0x00000002 /* current: user mode */
|
||||||
|
#define CST_IEp 0x00000004 /* previous: interrupt enable */
|
||||||
|
#define CST_KUp 0x00000008 /* previous: user mode */
|
||||||
|
#define CST_IEo 0x00000010 /* old: interrupt enable */
|
||||||
|
#define CST_KUo 0x00000020 /* old: user mode */
|
||||||
|
#define CST_MODEMASK 0x0000003f /* mask for the above */
|
||||||
|
#define CST_IRQMASK 0x0000ff00 /* mask for the individual irq enable bits */
|
||||||
|
#define CST_BEV 0x00400000 /* bootstrap exception vectors flag */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fields of the c0_cause register
|
||||||
|
*/
|
||||||
|
#define CCA_UTLB 0x00000001 /* true if UTLB exception (set by our asm) */
|
||||||
|
#define CCA_CODE 0x0000003c /* EX_foo in trapframe.h */
|
||||||
|
#define CCA_IRQS 0x0000ff00 /* Currently pending interrupts */
|
||||||
|
#define CCA_COPN 0x30000000 /* Coprocessor number for EX_CPU */
|
||||||
|
#define CCA_JD 0x80000000 /* True if exception happened in jump delay */
|
||||||
|
|
||||||
|
#define CCA_CODESHIFT 2 /* shift for CCA_CODE field */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fields of the c0_index register
|
||||||
|
*/
|
||||||
|
#define CIN_P 0x80000000 /* nonzero -> TLB probe found nothing */
|
||||||
|
#define CIN_INDEX 0x00003f00 /* 6-bit index into TLB */
|
||||||
|
|
||||||
|
#define CIN_INDEXSHIFT 8 /* shift for CIN_INDEX field */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fields of the c0_context register
|
||||||
|
*
|
||||||
|
* The intent of c0_context is that you can manage virtually-mapped
|
||||||
|
* page tables in kseg2; then you load the base address of the current
|
||||||
|
* page table into c0_context. On a TLB miss the failing address is
|
||||||
|
* masked and shifted and appears in the VSHIFT field, and c0_context
|
||||||
|
* thereby contains the address of the page table entry you need to
|
||||||
|
* load into the TLB. This can be used to make TLB refill very fast.
|
||||||
|
*
|
||||||
|
* However, in OS/161 we use CTX_PTBASE to hold the current CPU
|
||||||
|
* number. This (or something like it) is fairly important to have and
|
||||||
|
* there's no other good place in the chip to put it. See discussions
|
||||||
|
* elsewhere.
|
||||||
|
*/
|
||||||
|
#define CTX_VSHIFT 0x001ffffc /* shifted/masked copy of c0_vaddr */
|
||||||
|
#define CTX_PTBASE 0xffe00000 /* page table base address */
|
||||||
|
|
||||||
|
#define CTX_PTBASESHIFT 21 /* shift for CTX_PBASE field */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hardwired exception handler addresses.
|
||||||
|
*/
|
||||||
|
#define EXADDR_UTLB 0x80000000
|
||||||
|
#define EXADDR_GENERAL 0x80000080
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _MIPS_SPECIALREG_H_ */
|
122
kern/arch/mips/include/spinlock.h
Normal file
122
kern/arch/mips/include/spinlock.h
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MIPS_SPINLOCK_H_
|
||||||
|
#define _MIPS_SPINLOCK_H_
|
||||||
|
|
||||||
|
#include <cdefs.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Type of value needed to actually spin on */
|
||||||
|
typedef unsigned spinlock_data_t;
|
||||||
|
|
||||||
|
/* Initializer for use by SPINLOCK_INITIALIZER */
|
||||||
|
#define SPINLOCK_DATA_INITIALIZER 0
|
||||||
|
|
||||||
|
/* Atomic operations on spinlock_data_t */
|
||||||
|
SPINLOCK_INLINE
|
||||||
|
void spinlock_data_set(volatile spinlock_data_t *sd, unsigned val);
|
||||||
|
SPINLOCK_INLINE
|
||||||
|
spinlock_data_t spinlock_data_get(volatile spinlock_data_t *sd);
|
||||||
|
SPINLOCK_INLINE
|
||||||
|
spinlock_data_t spinlock_data_testandset(volatile spinlock_data_t *sd);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assign a spinlock_data_t. On mips assigment of a plain 32-bit value
|
||||||
|
* is one instruction, and instructions are atomic with respect to
|
||||||
|
* memory.
|
||||||
|
*/
|
||||||
|
SPINLOCK_INLINE
|
||||||
|
void
|
||||||
|
spinlock_data_set(volatile spinlock_data_t *sd, unsigned val)
|
||||||
|
{
|
||||||
|
*sd = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read a spinlock_data_t. On mips reading a plain 32-bit value is one
|
||||||
|
* instruction, and instructions are atomic with respect to memory.
|
||||||
|
*/
|
||||||
|
SPINLOCK_INLINE
|
||||||
|
spinlock_data_t
|
||||||
|
spinlock_data_get(volatile spinlock_data_t *sd)
|
||||||
|
{
|
||||||
|
return *sd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test-and-set a spinlock_data_t. Use the LL/SC instructions to
|
||||||
|
* make it atomic.
|
||||||
|
*
|
||||||
|
* LL (load linked) loads a machine word from memory, and marks the
|
||||||
|
* address. SC (store conditional) stores a machine word to memory,
|
||||||
|
* but succeeds only if the address is marked from a previous LL on
|
||||||
|
* the same processor. Stores from other processors clear that mark,
|
||||||
|
* as do traps on the current processor. Note that there may be no
|
||||||
|
* other memory accesses (besides instruction fetches) between the LL
|
||||||
|
* and the SC or the behavior is *undefined*. You can only use LL/SC
|
||||||
|
* to atomically update one machine word.
|
||||||
|
*/
|
||||||
|
SPINLOCK_INLINE
|
||||||
|
spinlock_data_t
|
||||||
|
spinlock_data_testandset(volatile spinlock_data_t *sd)
|
||||||
|
{
|
||||||
|
spinlock_data_t x;
|
||||||
|
spinlock_data_t y;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test-and-set using LL/SC.
|
||||||
|
*
|
||||||
|
* Load the existing value into X, and use Y to store 1.
|
||||||
|
* After the SC, Y contains 1 if the store succeeded,
|
||||||
|
* 0 if it failed.
|
||||||
|
*
|
||||||
|
* On failure, return 1 to pretend that the spinlock
|
||||||
|
* was already held.
|
||||||
|
*/
|
||||||
|
|
||||||
|
y = 1;
|
||||||
|
__asm volatile(
|
||||||
|
".set push;" /* save assembler mode */
|
||||||
|
".set mips32;" /* allow MIPS32 instructions */
|
||||||
|
".set volatile;" /* avoid unwanted optimization */
|
||||||
|
"ll %0, 0(%2);" /* x = *sd */
|
||||||
|
"sc %1, 0(%2);" /* *sd = y; y = success? */
|
||||||
|
".set pop" /* restore assembler mode */
|
||||||
|
: "=&r" (x), "+r" (y) : "r" (sd));
|
||||||
|
if (y == 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _MIPS_SPINLOCK_H_ */
|
48
kern/arch/mips/include/thread.h
Normal file
48
kern/arch/mips/include/thread.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MIPS_THREAD_H_
|
||||||
|
#define _MIPS_THREAD_H_
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Machine-dependent thread bits.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <setjmp.h>
|
||||||
|
|
||||||
|
typedef void (*badfaultfunc_t)(void);
|
||||||
|
|
||||||
|
struct thread_machdep {
|
||||||
|
badfaultfunc_t tm_badfaultfunc; /* fault hook used by copyin/out */
|
||||||
|
jmp_buf tm_copyjmp; /* longjmp area used by copyin/out */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _MIPS_THREAD_H_ */
|
105
kern/arch/mips/include/tlb.h
Normal file
105
kern/arch/mips/include/tlb.h
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MIPS_TLB_H_
|
||||||
|
#define _MIPS_TLB_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MIPS-specific TLB access functions.
|
||||||
|
*
|
||||||
|
* tlb_random: write the TLB entry specified by ENTRYHI and ENTRYLO
|
||||||
|
* into a "random" TLB slot chosen by the processor.
|
||||||
|
*
|
||||||
|
* IMPORTANT NOTE: never write more than one TLB entry with the
|
||||||
|
* same virtual page field.
|
||||||
|
*
|
||||||
|
* tlb_write: same as tlb_random, but you choose the slot.
|
||||||
|
*
|
||||||
|
* tlb_read: read a TLB entry out of the TLB into ENTRYHI and ENTRYLO.
|
||||||
|
* INDEX specifies which one to get.
|
||||||
|
*
|
||||||
|
* tlb_probe: look for an entry matching the virtual page in ENTRYHI.
|
||||||
|
* Returns the index, or a negative number if no matching entry
|
||||||
|
* was found. ENTRYLO is not actually used, but must be set; 0
|
||||||
|
* should be passed.
|
||||||
|
*
|
||||||
|
* IMPORTANT NOTE: An entry may be matching even if the valid bit
|
||||||
|
* is not set. To completely invalidate the TLB, load it with
|
||||||
|
* translations for addresses in one of the unmapped address
|
||||||
|
* ranges - these will never be matched.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void tlb_random(uint32_t entryhi, uint32_t entrylo);
|
||||||
|
void tlb_write(uint32_t entryhi, uint32_t entrylo, uint32_t index);
|
||||||
|
void tlb_read(uint32_t *entryhi, uint32_t *entrylo, uint32_t index);
|
||||||
|
int tlb_probe(uint32_t entryhi, uint32_t entrylo);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TLB entry fields.
|
||||||
|
*
|
||||||
|
* Note that the MIPS has support for a 6-bit address space ID. In the
|
||||||
|
* interests of simplicity, we don't use it. The fields related to it
|
||||||
|
* (TLBLO_GLOBAL and TLBHI_PID) can be left always zero, as can the
|
||||||
|
* bits that aren't assigned a meaning.
|
||||||
|
*
|
||||||
|
* The TLBLO_DIRTY bit is actually a write privilege bit - it is not
|
||||||
|
* ever set by the processor. If you set it, writes are permitted. If
|
||||||
|
* you don't set it, you'll get a "TLB Modify" exception when a write
|
||||||
|
* is attempted.
|
||||||
|
*
|
||||||
|
* There is probably no reason in the course of CS161 to use TLBLO_NOCACHE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Fields in the high-order word */
|
||||||
|
#define TLBHI_VPAGE 0xfffff000
|
||||||
|
/* TLBHI_PID 0x00000fc0 */
|
||||||
|
|
||||||
|
/* Fields in the low-order word */
|
||||||
|
#define TLBLO_PPAGE 0xfffff000
|
||||||
|
#define TLBLO_NOCACHE 0x00000800
|
||||||
|
#define TLBLO_DIRTY 0x00000400
|
||||||
|
#define TLBLO_VALID 0x00000200
|
||||||
|
/* TLBLO_GLOBAL 0x00000100 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Values for completely invalid TLB entries. The TLB entry index should
|
||||||
|
* be passed to TLBHI_INVALID; this prevents loading the same invalid
|
||||||
|
* entry into multiple TLB slots.
|
||||||
|
*/
|
||||||
|
#define TLBHI_INVALID(entryno) ((0x80000+(entryno))<<12)
|
||||||
|
#define TLBLO_INVALID() (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Number of TLB entries in the processor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NUM_TLB 64
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _MIPS_TLB_H_ */
|
108
kern/arch/mips/include/trapframe.h
Normal file
108
kern/arch/mips/include/trapframe.h
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MIPS_TRAPFRAME_H_
|
||||||
|
#define _MIPS_TRAPFRAME_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure describing what is saved on the stack during entry to
|
||||||
|
* the exception handler.
|
||||||
|
*
|
||||||
|
* This must agree with the code in exception-*.S.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct trapframe {
|
||||||
|
uint32_t tf_vaddr; /* coprocessor 0 vaddr register */
|
||||||
|
uint32_t tf_status; /* coprocessor 0 status register */
|
||||||
|
uint32_t tf_cause; /* coprocessor 0 cause register */
|
||||||
|
uint32_t tf_lo;
|
||||||
|
uint32_t tf_hi;
|
||||||
|
uint32_t tf_ra; /* Saved register 31 */
|
||||||
|
uint32_t tf_at; /* Saved register 1 (AT) */
|
||||||
|
uint32_t tf_v0; /* Saved register 2 (v0) */
|
||||||
|
uint32_t tf_v1; /* etc. */
|
||||||
|
uint32_t tf_a0;
|
||||||
|
uint32_t tf_a1;
|
||||||
|
uint32_t tf_a2;
|
||||||
|
uint32_t tf_a3;
|
||||||
|
uint32_t tf_t0;
|
||||||
|
uint32_t tf_t1;
|
||||||
|
uint32_t tf_t2;
|
||||||
|
uint32_t tf_t3;
|
||||||
|
uint32_t tf_t4;
|
||||||
|
uint32_t tf_t5;
|
||||||
|
uint32_t tf_t6;
|
||||||
|
uint32_t tf_t7;
|
||||||
|
uint32_t tf_s0;
|
||||||
|
uint32_t tf_s1;
|
||||||
|
uint32_t tf_s2;
|
||||||
|
uint32_t tf_s3;
|
||||||
|
uint32_t tf_s4;
|
||||||
|
uint32_t tf_s5;
|
||||||
|
uint32_t tf_s6;
|
||||||
|
uint32_t tf_s7;
|
||||||
|
uint32_t tf_t8;
|
||||||
|
uint32_t tf_t9;
|
||||||
|
uint32_t tf_gp;
|
||||||
|
uint32_t tf_sp;
|
||||||
|
uint32_t tf_s8;
|
||||||
|
uint32_t tf_epc; /* coprocessor 0 epc register */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MIPS exception codes.
|
||||||
|
*/
|
||||||
|
#define EX_IRQ 0 /* Interrupt */
|
||||||
|
#define EX_MOD 1 /* TLB Modify (write to read-only page) */
|
||||||
|
#define EX_TLBL 2 /* TLB miss on load */
|
||||||
|
#define EX_TLBS 3 /* TLB miss on store */
|
||||||
|
#define EX_ADEL 4 /* Address error on load */
|
||||||
|
#define EX_ADES 5 /* Address error on store */
|
||||||
|
#define EX_IBE 6 /* Bus error on instruction fetch */
|
||||||
|
#define EX_DBE 7 /* Bus error on data load *or* store */
|
||||||
|
#define EX_SYS 8 /* Syscall */
|
||||||
|
#define EX_BP 9 /* Breakpoint */
|
||||||
|
#define EX_RI 10 /* Reserved (illegal) instruction */
|
||||||
|
#define EX_CPU 11 /* Coprocessor unusable */
|
||||||
|
#define EX_OVF 12 /* Arithmetic overflow */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function to enter user mode. Does not return. The trapframe must
|
||||||
|
* be on the thread's own stack or bad things will happen.
|
||||||
|
*/
|
||||||
|
__DEAD void mips_usermode(struct trapframe *tf);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Arrays used to load the kernel stack and curthread on trap entry.
|
||||||
|
*/
|
||||||
|
extern vaddr_t cpustacks[];
|
||||||
|
extern vaddr_t cputhreads[];
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _MIPS_TRAPFRAME_H_ */
|
46
kern/arch/mips/include/types.h
Normal file
46
kern/arch/mips/include/types.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MIPS_TYPES_H_
|
||||||
|
#define _MIPS_TYPES_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Machine-dependent types that are *not* made visible to userland.
|
||||||
|
* Those that are made visible are found in kern/machine/types.h.
|
||||||
|
* 32-bit MIPS version.
|
||||||
|
*
|
||||||
|
* (Use the underscore versions of the base type names because this
|
||||||
|
* file is included by types.h before the non-underscore versions are
|
||||||
|
* defined.)
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef __u32 paddr_t;
|
||||||
|
typedef __u32 vaddr_t;
|
||||||
|
|
||||||
|
#endif /* _MIPS_TYPES_H_ */
|
129
kern/arch/mips/include/vm.h
Normal file
129
kern/arch/mips/include/vm.h
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MIPS_VM_H_
|
||||||
|
#define _MIPS_VM_H_
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Machine-dependent VM system definitions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PAGE_SIZE 4096 /* size of VM page */
|
||||||
|
#define PAGE_FRAME 0xfffff000 /* mask for getting page number from addr */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MIPS-I hardwired memory layout:
|
||||||
|
* 0xc0000000 - 0xffffffff kseg2 (kernel, tlb-mapped)
|
||||||
|
* 0xa0000000 - 0xbfffffff kseg1 (kernel, unmapped, uncached)
|
||||||
|
* 0x80000000 - 0x9fffffff kseg0 (kernel, unmapped, cached)
|
||||||
|
* 0x00000000 - 0x7fffffff kuseg (user, tlb-mapped)
|
||||||
|
*
|
||||||
|
* (mips32 is a little different)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MIPS_KUSEG 0x00000000
|
||||||
|
#define MIPS_KSEG0 0x80000000
|
||||||
|
#define MIPS_KSEG1 0xa0000000
|
||||||
|
#define MIPS_KSEG2 0xc0000000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The first 512 megs of physical space can be addressed in both kseg0 and
|
||||||
|
* kseg1. We use kseg0 for the kernel. This macro returns the kernel virtual
|
||||||
|
* address of a given physical address within that range. (We assume we're
|
||||||
|
* not using systems with more physical space than that anyway.)
|
||||||
|
*
|
||||||
|
* N.B. If you, say, call a function that returns a paddr or 0 on error,
|
||||||
|
* check the paddr for being 0 *before* you use this macro. While paddr 0
|
||||||
|
* is not legal for memory allocation or memory management (it holds
|
||||||
|
* exception handler code) when converted to a vaddr it's *not* NULL, *is*
|
||||||
|
* a valid address, and will make a *huge* mess if you scribble on it.
|
||||||
|
*/
|
||||||
|
#define PADDR_TO_KVADDR(paddr) ((paddr)+MIPS_KSEG0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The top of user space. (Actually, the address immediately above the
|
||||||
|
* last valid user address.)
|
||||||
|
*/
|
||||||
|
#define USERSPACETOP MIPS_KSEG0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The starting value for the stack pointer at user level. Because
|
||||||
|
* the stack is subtract-then-store, this can start as the next
|
||||||
|
* address after the stack area.
|
||||||
|
*
|
||||||
|
* We put the stack at the very top of user virtual memory because it
|
||||||
|
* grows downwards.
|
||||||
|
*/
|
||||||
|
#define USERSTACK USERSPACETOP
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interface to the low-level module that looks after the amount of
|
||||||
|
* physical memory we have.
|
||||||
|
*
|
||||||
|
* ram_getsize returns one past the highest valid physical
|
||||||
|
* address. (This value is page-aligned.) The extant RAM ranges from
|
||||||
|
* physical address 0 up to but not including this address.
|
||||||
|
*
|
||||||
|
* ram_getfirstfree returns the lowest valid physical address. (It is
|
||||||
|
* also page-aligned.) Memory at this address and above is available
|
||||||
|
* for use during operation, and excludes the space the kernel is
|
||||||
|
* loaded into and memory that is grabbed in the very early stages of
|
||||||
|
* bootup. Memory below this address is already in use and should be
|
||||||
|
* reserved or otherwise not managed by the VM system. It should be
|
||||||
|
* called exactly once when the VM system initializes to take over
|
||||||
|
* management of physical memory.
|
||||||
|
*
|
||||||
|
* ram_stealmem can be used before ram_getsize is called to allocate
|
||||||
|
* memory that cannot be freed later. This is intended for use early
|
||||||
|
* in bootup before VM initialization is complete.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ram_bootstrap(void);
|
||||||
|
paddr_t ram_stealmem(unsigned long npages);
|
||||||
|
paddr_t ram_getsize(void);
|
||||||
|
paddr_t ram_getfirstfree(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TLB shootdown bits.
|
||||||
|
*
|
||||||
|
* We'll take up to 16 invalidations before just flushing the whole TLB.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct tlbshootdown {
|
||||||
|
/*
|
||||||
|
* Change this to what you need for your VM design.
|
||||||
|
*/
|
||||||
|
int ts_placeholder;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TLBSHOOTDOWN_MAX 16
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _MIPS_VM_H_ */
|
49
kern/arch/mips/locore/cache-mips161.S
Normal file
49
kern/arch/mips/locore/cache-mips161.S
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2001, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kern/mips/regdefs.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cache flushing code for the System/161 MIPS variant, which
|
||||||
|
* (for now at least) has magically coherent caches. Almost all
|
||||||
|
* real MIPS processors require explicit cache control of one
|
||||||
|
* form or another; it can be quite a nuisance. (It is particularly
|
||||||
|
* nasty on the MIPS-1, that is, r2000/r3000.)
|
||||||
|
*/
|
||||||
|
|
||||||
|
.text
|
||||||
|
.set noreorder
|
||||||
|
|
||||||
|
.globl mips_flushicache
|
||||||
|
.type mips_flushicache,@function
|
||||||
|
.ent mips_flushicache
|
||||||
|
mips_flushicache:
|
||||||
|
j ra
|
||||||
|
nop
|
||||||
|
.end mips_flushicache
|
366
kern/arch/mips/locore/exception-mips1.S
Normal file
366
kern/arch/mips/locore/exception-mips1.S
Normal file
@ -0,0 +1,366 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kern/mips/regdefs.h>
|
||||||
|
#include <mips/specialreg.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Entry points for exceptions.
|
||||||
|
*
|
||||||
|
* MIPS-1 (r2000/r3000) style exception handling, with the "rfe"
|
||||||
|
* instruction rather than "eret", and the three sets of status bits.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do not allow the assembler to use $1 (at), because we need to be
|
||||||
|
* able to save it.
|
||||||
|
*/
|
||||||
|
.set noat
|
||||||
|
.set noreorder
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UTLB exception handler.
|
||||||
|
*
|
||||||
|
* This code is copied to address 0x80000000, where the MIPS processor
|
||||||
|
* automatically invokes it.
|
||||||
|
*
|
||||||
|
* To avoid colliding with the other exception code, it must not
|
||||||
|
* exceed 128 bytes (32 instructions).
|
||||||
|
*
|
||||||
|
* This is the special entry point for the fast-path TLB refill for
|
||||||
|
* faults in the user address space. We don't implement fast-path TLB
|
||||||
|
* refill by default. Note that if you do, you either need to make
|
||||||
|
* sure the refill code doesn't fault or write extra code in
|
||||||
|
* common_exception to tidy up after such faults.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.text
|
||||||
|
.globl mips_utlb_handler
|
||||||
|
.type mips_utlb_handler,@function
|
||||||
|
.ent mips_utlb_handler
|
||||||
|
mips_utlb_handler:
|
||||||
|
j common_exception /* Don't need to do anything special */
|
||||||
|
nop /* Delay slot */
|
||||||
|
.globl mips_utlb_end
|
||||||
|
mips_utlb_end:
|
||||||
|
.end mips_utlb_handler
|
||||||
|
|
||||||
|
/*
|
||||||
|
* General exception handler.
|
||||||
|
*
|
||||||
|
* This code is copied to address 0x80000080, where
|
||||||
|
* the MIPS processor automatically invokes it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.text
|
||||||
|
.globl mips_general_handler
|
||||||
|
.type mips_general_handler,@function
|
||||||
|
.ent mips_general_handler
|
||||||
|
mips_general_handler:
|
||||||
|
j common_exception /* Don't need to do anything special */
|
||||||
|
nop /* Delay slot */
|
||||||
|
.globl mips_general_end
|
||||||
|
mips_general_end:
|
||||||
|
.end mips_general_handler
|
||||||
|
|
||||||
|
/* This keeps gdb from conflating common_exception and mips_general_end */
|
||||||
|
nop /* padding */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shared exception code for both handlers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.text
|
||||||
|
.type common_exception,@function
|
||||||
|
.ent common_exception
|
||||||
|
.cfi_startproc
|
||||||
|
.cfi_signal_frame
|
||||||
|
common_exception:
|
||||||
|
mfc0 k0, c0_status /* Get status register */
|
||||||
|
andi k0, k0, CST_KUp /* Check the we-were-in-user-mode bit */
|
||||||
|
beq k0, $0, 1f /* If clear, from kernel, already have stack */
|
||||||
|
nop /* delay slot */
|
||||||
|
|
||||||
|
/* Coming from user mode - find kernel stack */
|
||||||
|
mfc0 k1, c0_context /* we keep the CPU number here */
|
||||||
|
srl k1, k1, CTX_PTBASESHIFT /* shift it to get just the CPU number */
|
||||||
|
sll k1, k1, 2 /* shift it back to make an array index */
|
||||||
|
lui k0, %hi(cpustacks) /* get base address of cpustacks[] */
|
||||||
|
addu k0, k0, k1 /* index it */
|
||||||
|
move k1, sp /* Save previous stack pointer in k1 */
|
||||||
|
b 2f /* Skip to common code */
|
||||||
|
lw sp, %lo(cpustacks)(k0) /* Load kernel stack pointer (in delay slot) */
|
||||||
|
1:
|
||||||
|
/* Coming from kernel mode - just save previous stuff */
|
||||||
|
move k1, sp /* Save previous stack in k1 (delay slot) */
|
||||||
|
2:
|
||||||
|
/*
|
||||||
|
* At this point:
|
||||||
|
* Interrupts are off. (The processor did this for us.)
|
||||||
|
* k0 contains the value for curthread, to go into s7.
|
||||||
|
* k1 contains the old stack pointer.
|
||||||
|
* sp points into the kernel stack.
|
||||||
|
* All other registers are untouched.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate stack space for 35 words to hold the trap frame,
|
||||||
|
* plus four more words for a minimal argument block, plus
|
||||||
|
* one more for proper (64-bit) stack alignment.
|
||||||
|
*/
|
||||||
|
addi sp, sp, -160
|
||||||
|
.cfi_def_cfa sp, 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save general registers.
|
||||||
|
* We exclude k0/k1, which the kernel is free to clobber (and which
|
||||||
|
* we already have clobbered), and $0, whose value is fixed.
|
||||||
|
*
|
||||||
|
* The order here must match mips/include/trapframe.h.
|
||||||
|
*
|
||||||
|
* gdb uses the .cfi_offset assembler directives inserted below to
|
||||||
|
* to figure out where each register is stored. Since we've marked
|
||||||
|
* this function as a "signal handler" with the .cfi_signal_frame
|
||||||
|
* directive, gdb won't complain about the fact that the stack
|
||||||
|
* is noncontiguous (if we're coming from userland).
|
||||||
|
*
|
||||||
|
* We also play a trick with the return address: we mark the ra
|
||||||
|
* register as stored to the stack normally and then mark the
|
||||||
|
* return address for *this* function as being in the k1 register
|
||||||
|
* using the .cfi_return_column directive. gdb is then able to
|
||||||
|
* recognize that the ra we've stored here is the return address
|
||||||
|
* for the function that was executing when this exception was
|
||||||
|
* taken.
|
||||||
|
*
|
||||||
|
* All of the cfi (call frame information) material is compiled
|
||||||
|
* into the .eh_frame section of the compiled kernel.
|
||||||
|
*/
|
||||||
|
sw s8, 148(sp) /* save s8 */
|
||||||
|
.cfi_offset s8, 148
|
||||||
|
sw k1, 144(sp) /* real saved sp */
|
||||||
|
.cfi_offset sp, 144
|
||||||
|
sw gp, 140(sp) /* save gp */
|
||||||
|
nop /* delay slot for store */
|
||||||
|
.cfi_offset gp, 140
|
||||||
|
|
||||||
|
.cfi_return_column k1
|
||||||
|
mfc0 k1, c0_epc /* Copr.0 reg 13 == PC for exception */
|
||||||
|
sw k1, 152(sp) /* real saved PC */
|
||||||
|
.cfi_offset k1, 152
|
||||||
|
|
||||||
|
sw t9, 136(sp)
|
||||||
|
.cfi_offset t9, 136
|
||||||
|
sw t8, 132(sp)
|
||||||
|
.cfi_offset t8, 132
|
||||||
|
sw s7, 128(sp)
|
||||||
|
.cfi_offset s7, 128
|
||||||
|
sw s6, 124(sp)
|
||||||
|
.cfi_offset s6, 124
|
||||||
|
sw s5, 120(sp)
|
||||||
|
.cfi_offset s5, 120
|
||||||
|
sw s4, 116(sp)
|
||||||
|
.cfi_offset s4, 116
|
||||||
|
sw s3, 112(sp)
|
||||||
|
.cfi_offset s3, 112
|
||||||
|
sw s2, 108(sp)
|
||||||
|
.cfi_offset s2, 108
|
||||||
|
sw s1, 104(sp)
|
||||||
|
.cfi_offset s1, 104
|
||||||
|
sw s0, 100(sp)
|
||||||
|
.cfi_offset s0, 100
|
||||||
|
sw t7, 96(sp)
|
||||||
|
.cfi_offset t7, 96
|
||||||
|
sw t6, 92(sp)
|
||||||
|
.cfi_offset t6, 92
|
||||||
|
sw t5, 88(sp)
|
||||||
|
.cfi_offset t5, 88
|
||||||
|
sw t4, 84(sp)
|
||||||
|
.cfi_offset t4, 84
|
||||||
|
sw t3, 80(sp)
|
||||||
|
.cfi_offset t3, 80
|
||||||
|
sw t2, 76(sp)
|
||||||
|
.cfi_offset t2, 76
|
||||||
|
sw t1, 72(sp)
|
||||||
|
.cfi_offset t1, 72
|
||||||
|
sw t0, 68(sp)
|
||||||
|
.cfi_offset t0, 68
|
||||||
|
sw a3, 64(sp)
|
||||||
|
.cfi_offset a3, 64
|
||||||
|
sw a2, 60(sp)
|
||||||
|
.cfi_offset a2, 60
|
||||||
|
sw a1, 56(sp)
|
||||||
|
.cfi_offset a1, 56
|
||||||
|
sw a0, 52(sp)
|
||||||
|
.cfi_offset a0, 52
|
||||||
|
sw v1, 48(sp)
|
||||||
|
.cfi_offset v1, 48
|
||||||
|
sw v0, 44(sp)
|
||||||
|
.cfi_offset v0, 44
|
||||||
|
sw AT, 40(sp)
|
||||||
|
.cfi_offset AT, 40
|
||||||
|
|
||||||
|
sw ra, 36(sp)
|
||||||
|
.cfi_offset ra, 36
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save special registers.
|
||||||
|
*/
|
||||||
|
mfhi t0
|
||||||
|
mflo t1
|
||||||
|
sw t0, 32(sp)
|
||||||
|
sw t1, 28(sp)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save remaining exception context information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mfc0 t2, c0_status /* Copr.0 reg 11 == status */
|
||||||
|
sw t2, 20(sp)
|
||||||
|
mfc0 t3, c0_vaddr /* Copr.0 reg 8 == faulting vaddr */
|
||||||
|
sw t3, 16(sp)
|
||||||
|
mfc0 t4, c0_cause
|
||||||
|
sw t4, 24(sp) /* Copr.0 reg 13 == exception cause */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load the curthread register if coming from user mode.
|
||||||
|
*/
|
||||||
|
andi k0, t2, CST_KUp /* Check the we-were-in-user-mode bit */
|
||||||
|
beq k0, $0, 3f /* If clear, were in kernel, skip ahead */
|
||||||
|
nop /* delay slot */
|
||||||
|
|
||||||
|
mfc0 k1, c0_context /* we keep the CPU number here */
|
||||||
|
srl k1, k1, CTX_PTBASESHIFT /* shift it to get just the CPU number */
|
||||||
|
sll k1, k1, 2 /* shift it back to make an array index */
|
||||||
|
lui k0, %hi(cputhreads) /* get base address of cputhreads[] */
|
||||||
|
addu k0, k0, k1 /* index it */
|
||||||
|
lw s7, %lo(cputhreads)(k0) /* Load curthread value */
|
||||||
|
3:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load the kernel GP value.
|
||||||
|
*/
|
||||||
|
la gp, _gp
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prepare to call mips_trap(struct trapframe *)
|
||||||
|
*/
|
||||||
|
|
||||||
|
addiu a0, sp, 16 /* set argument - pointer to the trapframe */
|
||||||
|
jal mips_trap /* call it */
|
||||||
|
nop /* delay slot */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now restore stuff and return from the exception.
|
||||||
|
* Interrupts should be off.
|
||||||
|
*/
|
||||||
|
exception_return:
|
||||||
|
|
||||||
|
/* 16(sp) no need to restore tf_vaddr */
|
||||||
|
lw t0, 20(sp) /* load status register value into t0 */
|
||||||
|
nop /* load delay slot */
|
||||||
|
mtc0 t0, c0_status /* store it back to coprocessor 0 */
|
||||||
|
/* 24(sp) no need to restore tf_cause */
|
||||||
|
|
||||||
|
/* restore special registers */
|
||||||
|
lw t1, 28(sp)
|
||||||
|
lw t0, 32(sp)
|
||||||
|
mtlo t1
|
||||||
|
mthi t0
|
||||||
|
|
||||||
|
/* load the general registers */
|
||||||
|
lw ra, 36(sp)
|
||||||
|
|
||||||
|
lw AT, 40(sp)
|
||||||
|
lw v0, 44(sp)
|
||||||
|
lw v1, 48(sp)
|
||||||
|
lw a0, 52(sp)
|
||||||
|
lw a1, 56(sp)
|
||||||
|
lw a2, 60(sp)
|
||||||
|
lw a3, 64(sp)
|
||||||
|
lw t0, 68(sp)
|
||||||
|
lw t1, 72(sp)
|
||||||
|
lw t2, 76(sp)
|
||||||
|
lw t3, 80(sp)
|
||||||
|
lw t4, 84(sp)
|
||||||
|
lw t5, 88(sp)
|
||||||
|
lw t6, 92(sp)
|
||||||
|
lw t7, 96(sp)
|
||||||
|
lw s0, 100(sp)
|
||||||
|
lw s1, 104(sp)
|
||||||
|
lw s2, 108(sp)
|
||||||
|
lw s3, 112(sp)
|
||||||
|
lw s4, 116(sp)
|
||||||
|
lw s5, 120(sp)
|
||||||
|
lw s6, 124(sp)
|
||||||
|
lw s7, 128(sp)
|
||||||
|
lw t8, 132(sp)
|
||||||
|
lw t9, 136(sp)
|
||||||
|
lw gp, 140(sp) /* restore gp */
|
||||||
|
/* 144(sp) stack pointer - below */
|
||||||
|
lw s8, 148(sp) /* restore s8 */
|
||||||
|
lw k1, 152(sp) /* fetch exception return PC into k1 */
|
||||||
|
|
||||||
|
lw sp, 144(sp) /* fetch saved sp (must be last) */
|
||||||
|
|
||||||
|
/* done */
|
||||||
|
jr k1 /* jump back */
|
||||||
|
rfe /* in delay slot */
|
||||||
|
.cfi_endproc
|
||||||
|
.end common_exception
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Code to enter user mode for the first time.
|
||||||
|
* Does not return.
|
||||||
|
*
|
||||||
|
* This is called from mips_usermode().
|
||||||
|
* Interrupts on this processor should be off.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.text
|
||||||
|
.globl asm_usermode
|
||||||
|
.type asm_usermode,@function
|
||||||
|
.ent asm_usermode
|
||||||
|
asm_usermode:
|
||||||
|
/*
|
||||||
|
* a0 is the address of a trapframe to use for exception "return".
|
||||||
|
* It's allocated on our stack.
|
||||||
|
*
|
||||||
|
* Move it to the stack pointer - we don't need the actual stack
|
||||||
|
* position any more. (When we come back from usermode, cpustacks[]
|
||||||
|
* will be used to reinitialize our stack pointer, and that was
|
||||||
|
* set by mips_usermode.)
|
||||||
|
*
|
||||||
|
* Then just jump to the exception return code above.
|
||||||
|
*/
|
||||||
|
|
||||||
|
j exception_return
|
||||||
|
addiu sp, a0, -16 /* in delay slot */
|
||||||
|
.end asm_usermode
|
438
kern/arch/mips/locore/trap.c
Normal file
438
kern/arch/mips/locore/trap.c
Normal file
@ -0,0 +1,438 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#include <mips/specialreg.h>
|
||||||
|
#include <mips/trapframe.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
#include <spl.h>
|
||||||
|
#include <thread.h>
|
||||||
|
#include <current.h>
|
||||||
|
#include <vm.h>
|
||||||
|
#include <mainbus.h>
|
||||||
|
#include <syscall.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* in exception-*.S */
|
||||||
|
extern __DEAD void asm_usermode(struct trapframe *tf);
|
||||||
|
|
||||||
|
/* called only from assembler, so not declared in a header */
|
||||||
|
void mips_trap(struct trapframe *tf);
|
||||||
|
|
||||||
|
|
||||||
|
/* Names for trap codes */
|
||||||
|
#define NTRAPCODES 13
|
||||||
|
static const char *const trapcodenames[NTRAPCODES] = {
|
||||||
|
"Interrupt",
|
||||||
|
"TLB modify trap",
|
||||||
|
"TLB miss on load",
|
||||||
|
"TLB miss on store",
|
||||||
|
"Address error on load",
|
||||||
|
"Address error on store",
|
||||||
|
"Bus error on code",
|
||||||
|
"Bus error on data",
|
||||||
|
"System call",
|
||||||
|
"Break instruction",
|
||||||
|
"Illegal instruction",
|
||||||
|
"Coprocessor unusable",
|
||||||
|
"Arithmetic overflow",
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function called when user-level code hits a fatal fault.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
void
|
||||||
|
kill_curthread(vaddr_t epc, unsigned code, vaddr_t vaddr)
|
||||||
|
{
|
||||||
|
int sig = 0;
|
||||||
|
|
||||||
|
KASSERT(code < NTRAPCODES);
|
||||||
|
switch (code) {
|
||||||
|
case EX_IRQ:
|
||||||
|
case EX_IBE:
|
||||||
|
case EX_DBE:
|
||||||
|
case EX_SYS:
|
||||||
|
/* should not be seen */
|
||||||
|
KASSERT(0);
|
||||||
|
sig = SIGABRT;
|
||||||
|
break;
|
||||||
|
case EX_MOD:
|
||||||
|
case EX_TLBL:
|
||||||
|
case EX_TLBS:
|
||||||
|
sig = SIGSEGV;
|
||||||
|
break;
|
||||||
|
case EX_ADEL:
|
||||||
|
case EX_ADES:
|
||||||
|
sig = SIGBUS;
|
||||||
|
break;
|
||||||
|
case EX_BP:
|
||||||
|
sig = SIGTRAP;
|
||||||
|
break;
|
||||||
|
case EX_RI:
|
||||||
|
sig = SIGILL;
|
||||||
|
break;
|
||||||
|
case EX_CPU:
|
||||||
|
sig = SIGSEGV;
|
||||||
|
break;
|
||||||
|
case EX_OVF:
|
||||||
|
sig = SIGFPE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* You will probably want to change this.
|
||||||
|
*/
|
||||||
|
|
||||||
|
kprintf("Fatal user mode trap %u sig %d (%s, epc 0x%x, vaddr 0x%x)\n",
|
||||||
|
code, sig, trapcodenames[code], epc, vaddr);
|
||||||
|
panic("I don't know how to handle this\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* General trap (exception) handling function for mips.
|
||||||
|
* This is called by the assembly-language exception handler once
|
||||||
|
* the trapframe has been set up.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
mips_trap(struct trapframe *tf)
|
||||||
|
{
|
||||||
|
uint32_t code;
|
||||||
|
/*bool isutlb; -- not used */
|
||||||
|
bool iskern;
|
||||||
|
int spl;
|
||||||
|
|
||||||
|
/* The trap frame is supposed to be 35 registers long. */
|
||||||
|
KASSERT(sizeof(struct trapframe)==(35*4));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extract the exception code info from the register fields.
|
||||||
|
*/
|
||||||
|
code = (tf->tf_cause & CCA_CODE) >> CCA_CODESHIFT;
|
||||||
|
/*isutlb = (tf->tf_cause & CCA_UTLB) != 0;*/
|
||||||
|
iskern = (tf->tf_status & CST_KUp) == 0;
|
||||||
|
|
||||||
|
KASSERT(code < NTRAPCODES);
|
||||||
|
|
||||||
|
/* Make sure we haven't run off our stack */
|
||||||
|
if (curthread != NULL && curthread->t_stack != NULL) {
|
||||||
|
KASSERT((vaddr_t)tf > (vaddr_t)curthread->t_stack);
|
||||||
|
KASSERT((vaddr_t)tf < (vaddr_t)(curthread->t_stack
|
||||||
|
+ STACK_SIZE));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Interrupt? Call the interrupt handler and return. */
|
||||||
|
if (code == EX_IRQ) {
|
||||||
|
int old_in;
|
||||||
|
bool doadjust;
|
||||||
|
|
||||||
|
old_in = curthread->t_in_interrupt;
|
||||||
|
curthread->t_in_interrupt = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The processor has turned interrupts off; if the
|
||||||
|
* currently recorded interrupt state is interrupts on
|
||||||
|
* (spl of 0), adjust the recorded state to match, and
|
||||||
|
* restore after processing the interrupt.
|
||||||
|
*
|
||||||
|
* How can we get an interrupt if the recorded state
|
||||||
|
* is interrupts off? Well, as things currently stand
|
||||||
|
* when the CPU finishes idling it flips interrupts on
|
||||||
|
* and off to allow things to happen, but leaves
|
||||||
|
* curspl high while doing so.
|
||||||
|
*
|
||||||
|
* While we're here, assert that the interrupt
|
||||||
|
* handling code hasn't leaked a spinlock or an
|
||||||
|
* splhigh().
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (curthread->t_curspl == 0) {
|
||||||
|
KASSERT(curthread->t_curspl == 0);
|
||||||
|
KASSERT(curthread->t_iplhigh_count == 0);
|
||||||
|
curthread->t_curspl = IPL_HIGH;
|
||||||
|
curthread->t_iplhigh_count++;
|
||||||
|
doadjust = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
doadjust = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mainbus_interrupt(tf);
|
||||||
|
|
||||||
|
if (doadjust) {
|
||||||
|
KASSERT(curthread->t_curspl == IPL_HIGH);
|
||||||
|
KASSERT(curthread->t_iplhigh_count == 1);
|
||||||
|
curthread->t_iplhigh_count--;
|
||||||
|
curthread->t_curspl = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
curthread->t_in_interrupt = old_in;
|
||||||
|
goto done2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The processor turned interrupts off when it took the trap.
|
||||||
|
*
|
||||||
|
* While we're in the kernel, and not actually handling an
|
||||||
|
* interrupt, restore the interrupt state to where it was in
|
||||||
|
* the previous context, which may be low (interrupts on).
|
||||||
|
*
|
||||||
|
* Do this by forcing splhigh(), which may do a redundant
|
||||||
|
* cpu_irqoff() but forces the stored MI interrupt state into
|
||||||
|
* sync, then restoring the previous state.
|
||||||
|
*/
|
||||||
|
spl = splhigh();
|
||||||
|
splx(spl);
|
||||||
|
|
||||||
|
/* Syscall? Call the syscall handler and return. */
|
||||||
|
if (code == EX_SYS) {
|
||||||
|
/* Interrupts should have been on while in user mode. */
|
||||||
|
KASSERT(curthread->t_curspl == 0);
|
||||||
|
KASSERT(curthread->t_iplhigh_count == 0);
|
||||||
|
|
||||||
|
DEBUG(DB_SYSCALL, "syscall: #%d, args %x %x %x %x\n",
|
||||||
|
tf->tf_v0, tf->tf_a0, tf->tf_a1, tf->tf_a2, tf->tf_a3);
|
||||||
|
|
||||||
|
syscall(tf);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ok, it wasn't any of the really easy cases.
|
||||||
|
* Call vm_fault on the TLB exceptions.
|
||||||
|
* Panic on the bus error exceptions.
|
||||||
|
*/
|
||||||
|
switch (code) {
|
||||||
|
case EX_MOD:
|
||||||
|
if (vm_fault(VM_FAULT_READONLY, tf->tf_vaddr)==0) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EX_TLBL:
|
||||||
|
if (vm_fault(VM_FAULT_READ, tf->tf_vaddr)==0) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EX_TLBS:
|
||||||
|
if (vm_fault(VM_FAULT_WRITE, tf->tf_vaddr)==0) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EX_IBE:
|
||||||
|
case EX_DBE:
|
||||||
|
/*
|
||||||
|
* This means you loaded invalid TLB entries, or
|
||||||
|
* touched invalid parts of the direct-mapped
|
||||||
|
* segments. These are serious kernel errors, so
|
||||||
|
* panic.
|
||||||
|
*
|
||||||
|
* The MIPS won't even tell you what invalid address
|
||||||
|
* caused the bus error.
|
||||||
|
*/
|
||||||
|
panic("Bus error exception, PC=0x%x\n", tf->tf_epc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we get to this point, it's a fatal fault - either it's
|
||||||
|
* one of the other exceptions, like illegal instruction, or
|
||||||
|
* it was a page fault we couldn't handle.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!iskern) {
|
||||||
|
/*
|
||||||
|
* Fatal fault in user mode.
|
||||||
|
* Kill the current user process.
|
||||||
|
*/
|
||||||
|
kill_curthread(tf->tf_epc, code, tf->tf_vaddr);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fatal fault in kernel mode.
|
||||||
|
*
|
||||||
|
* If pcb_badfaultfunc is set, we do not panic; badfaultfunc is
|
||||||
|
* set by copyin/copyout and related functions to signify that
|
||||||
|
* the addresses they're accessing are userlevel-supplied and
|
||||||
|
* not trustable. What we actually want to do is resume
|
||||||
|
* execution at the function pointed to by badfaultfunc. That's
|
||||||
|
* going to be "copyfail" (see copyinout.c), which longjmps
|
||||||
|
* back to copyin/copyout or wherever and returns EFAULT.
|
||||||
|
*
|
||||||
|
* Note that we do not just *call* this function, because that
|
||||||
|
* won't necessarily do anything. We want the control flow
|
||||||
|
* that is currently executing in copyin (or whichever), and
|
||||||
|
* is stopped while we process the exception, to *teleport* to
|
||||||
|
* copyfail.
|
||||||
|
*
|
||||||
|
* This is accomplished by changing tf->tf_epc and returning
|
||||||
|
* from the exception handler.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (curthread != NULL &&
|
||||||
|
curthread->t_machdep.tm_badfaultfunc != NULL) {
|
||||||
|
tf->tf_epc = (vaddr_t) curthread->t_machdep.tm_badfaultfunc;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Really fatal kernel-mode fault.
|
||||||
|
*/
|
||||||
|
|
||||||
|
kprintf("panic: Fatal exception %u (%s) in kernel mode\n", code,
|
||||||
|
trapcodenames[code]);
|
||||||
|
kprintf("panic: EPC 0x%x, exception vaddr 0x%x\n",
|
||||||
|
tf->tf_epc, tf->tf_vaddr);
|
||||||
|
|
||||||
|
panic("I can't handle this... I think I'll just die now...\n");
|
||||||
|
|
||||||
|
done:
|
||||||
|
/*
|
||||||
|
* Turn interrupts off on the processor, without affecting the
|
||||||
|
* stored interrupt state.
|
||||||
|
*/
|
||||||
|
cpu_irqoff();
|
||||||
|
done2:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The boot thread can get here (e.g. on interrupt return) but
|
||||||
|
* since it doesn't go to userlevel, it can't be returning to
|
||||||
|
* userlevel, so there's no need to set cputhreads[] and
|
||||||
|
* cpustacks[]. Just return.
|
||||||
|
*/
|
||||||
|
if (curthread->t_stack == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cputhreads[curcpu->c_number] = (vaddr_t)curthread;
|
||||||
|
cpustacks[curcpu->c_number] = (vaddr_t)curthread->t_stack + STACK_SIZE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This assertion will fail if either
|
||||||
|
* (1) curthread->t_stack is corrupted, or
|
||||||
|
* (2) the trap frame is somehow on the wrong kernel stack.
|
||||||
|
*
|
||||||
|
* If cpustacks[] is corrupted, the next trap back to the
|
||||||
|
* kernel will (most likely) hang the system, so it's better
|
||||||
|
* to find out now.
|
||||||
|
*/
|
||||||
|
KASSERT(SAME_STACK(cpustacks[curcpu->c_number]-1, (vaddr_t)tf));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function for entering user mode.
|
||||||
|
*
|
||||||
|
* This should not be used by threads returning from traps - they
|
||||||
|
* should just return from mips_trap(). It should be used by threads
|
||||||
|
* entering user mode for the first time - whether the child thread in
|
||||||
|
* a fork(), or into a brand-new address space after exec(), or when
|
||||||
|
* starting the first userlevel program.
|
||||||
|
*
|
||||||
|
* It works by jumping into the exception return code.
|
||||||
|
*
|
||||||
|
* mips_usermode is common code for this. It cannot usefully be called
|
||||||
|
* outside the mips port, but should be called from one of the
|
||||||
|
* following places:
|
||||||
|
* - enter_new_process, for use by exec and equivalent.
|
||||||
|
* - enter_forked_process, in syscall.c, for use by fork.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
mips_usermode(struct trapframe *tf)
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interrupts should be off within the kernel while entering
|
||||||
|
* user mode. However, while in user mode, interrupts should
|
||||||
|
* be on. To interact properly with the spl-handling logic
|
||||||
|
* above, we explicitly call spl0() and then call cpu_irqoff().
|
||||||
|
*/
|
||||||
|
spl0();
|
||||||
|
cpu_irqoff();
|
||||||
|
|
||||||
|
cputhreads[curcpu->c_number] = (vaddr_t)curthread;
|
||||||
|
cpustacks[curcpu->c_number] = (vaddr_t)curthread->t_stack + STACK_SIZE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This assertion will fail if either
|
||||||
|
* (1) cpustacks[] is corrupted, or
|
||||||
|
* (2) the trap frame is not on our own kernel stack, or
|
||||||
|
* (3) the boot thread tries to enter user mode.
|
||||||
|
*
|
||||||
|
* If cpustacks[] is corrupted, the next trap back to the
|
||||||
|
* kernel will (most likely) hang the system, so it's better
|
||||||
|
* to find out now.
|
||||||
|
*
|
||||||
|
* It's necessary for the trap frame used here to be on the
|
||||||
|
* current thread's own stack. It cannot correctly be on
|
||||||
|
* either another thread's stack or in the kernel heap.
|
||||||
|
* (Exercise: why?)
|
||||||
|
*/
|
||||||
|
KASSERT(SAME_STACK(cpustacks[curcpu->c_number]-1, (vaddr_t)tf));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This actually does it. See exception-*.S.
|
||||||
|
*/
|
||||||
|
asm_usermode(tf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* enter_new_process: go to user mode after loading an executable.
|
||||||
|
*
|
||||||
|
* Performs the necessary initialization so that the user program will
|
||||||
|
* get the arguments supplied in argc/argv (note that argv must be a
|
||||||
|
* user-level address) and the environment pointer env (ditto), and
|
||||||
|
* begin executing at the specified entry point. The stack pointer is
|
||||||
|
* initialized from the stackptr argument. Note that passing argc/argv
|
||||||
|
* may use additional stack space on some other platforms (but not on
|
||||||
|
* mips).
|
||||||
|
*
|
||||||
|
* Unless you implement execve() that passes environments around, just
|
||||||
|
* pass NULL for the environment.
|
||||||
|
*
|
||||||
|
* Works by creating an ersatz trapframe.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
enter_new_process(int argc, userptr_t argv, userptr_t env,
|
||||||
|
vaddr_t stack, vaddr_t entry)
|
||||||
|
{
|
||||||
|
struct trapframe tf;
|
||||||
|
|
||||||
|
bzero(&tf, sizeof(tf));
|
||||||
|
|
||||||
|
tf.tf_status = CST_IRQMASK | CST_IEp | CST_KUp;
|
||||||
|
tf.tf_epc = entry;
|
||||||
|
tf.tf_a0 = argc;
|
||||||
|
tf.tf_a1 = (vaddr_t)argv;
|
||||||
|
tf.tf_a2 = (vaddr_t)env;
|
||||||
|
tf.tf_sp = stack;
|
||||||
|
|
||||||
|
mips_usermode(&tf);
|
||||||
|
}
|
161
kern/arch/mips/syscall/syscall.c
Normal file
161
kern/arch/mips/syscall/syscall.c
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <kern/errno.h>
|
||||||
|
#include <kern/syscall.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#include <mips/trapframe.h>
|
||||||
|
#include <thread.h>
|
||||||
|
#include <current.h>
|
||||||
|
#include <syscall.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* System call dispatcher.
|
||||||
|
*
|
||||||
|
* A pointer to the trapframe created during exception entry (in
|
||||||
|
* exception-*.S) is passed in.
|
||||||
|
*
|
||||||
|
* The calling conventions for syscalls are as follows: Like ordinary
|
||||||
|
* function calls, the first 4 32-bit arguments are passed in the 4
|
||||||
|
* argument registers a0-a3. 64-bit arguments are passed in *aligned*
|
||||||
|
* pairs of registers, that is, either a0/a1 or a2/a3. This means that
|
||||||
|
* if the first argument is 32-bit and the second is 64-bit, a1 is
|
||||||
|
* unused.
|
||||||
|
*
|
||||||
|
* This much is the same as the calling conventions for ordinary
|
||||||
|
* function calls. In addition, the system call number is passed in
|
||||||
|
* the v0 register.
|
||||||
|
*
|
||||||
|
* On successful return, the return value is passed back in the v0
|
||||||
|
* register, or v0 and v1 if 64-bit. This is also like an ordinary
|
||||||
|
* function call, and additionally the a3 register is also set to 0 to
|
||||||
|
* indicate success.
|
||||||
|
*
|
||||||
|
* On an error return, the error code is passed back in the v0
|
||||||
|
* register, and the a3 register is set to 1 to indicate failure.
|
||||||
|
* (Userlevel code takes care of storing the error code in errno and
|
||||||
|
* returning the value -1 from the actual userlevel syscall function.
|
||||||
|
* See src/user/lib/libc/arch/mips/syscalls-mips.S and related files.)
|
||||||
|
*
|
||||||
|
* Upon syscall return the program counter stored in the trapframe
|
||||||
|
* must be incremented by one instruction; otherwise the exception
|
||||||
|
* return code will restart the "syscall" instruction and the system
|
||||||
|
* call will repeat forever.
|
||||||
|
*
|
||||||
|
* If you run out of registers (which happens quickly with 64-bit
|
||||||
|
* values) further arguments must be fetched from the user-level
|
||||||
|
* stack, starting at sp+16 to skip over the slots for the
|
||||||
|
* registerized values, with copyin().
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
syscall(struct trapframe *tf)
|
||||||
|
{
|
||||||
|
int callno;
|
||||||
|
int32_t retval;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
KASSERT(curthread != NULL);
|
||||||
|
KASSERT(curthread->t_curspl == 0);
|
||||||
|
KASSERT(curthread->t_iplhigh_count == 0);
|
||||||
|
|
||||||
|
callno = tf->tf_v0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize retval to 0. Many of the system calls don't
|
||||||
|
* really return a value, just 0 for success and -1 on
|
||||||
|
* error. Since retval is the value returned on success,
|
||||||
|
* initialize it to 0 by default; thus it's not necessary to
|
||||||
|
* deal with it except for calls that return other values,
|
||||||
|
* like write.
|
||||||
|
*/
|
||||||
|
|
||||||
|
retval = 0;
|
||||||
|
|
||||||
|
switch (callno) {
|
||||||
|
case SYS_reboot:
|
||||||
|
err = sys_reboot(tf->tf_a0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYS___time:
|
||||||
|
err = sys___time((userptr_t)tf->tf_a0,
|
||||||
|
(userptr_t)tf->tf_a1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Add stuff here */
|
||||||
|
|
||||||
|
default:
|
||||||
|
kprintf("Unknown syscall %d\n", callno);
|
||||||
|
err = ENOSYS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
/*
|
||||||
|
* Return the error code. This gets converted at
|
||||||
|
* userlevel to a return value of -1 and the error
|
||||||
|
* code in errno.
|
||||||
|
*/
|
||||||
|
tf->tf_v0 = err;
|
||||||
|
tf->tf_a3 = 1; /* signal an error */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Success. */
|
||||||
|
tf->tf_v0 = retval;
|
||||||
|
tf->tf_a3 = 0; /* signal no error */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now, advance the program counter, to avoid restarting
|
||||||
|
* the syscall over and over again.
|
||||||
|
*/
|
||||||
|
|
||||||
|
tf->tf_epc += 4;
|
||||||
|
|
||||||
|
/* Make sure the syscall code didn't forget to lower spl */
|
||||||
|
KASSERT(curthread->t_curspl == 0);
|
||||||
|
/* ...or leak any spinlocks */
|
||||||
|
KASSERT(curthread->t_iplhigh_count == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enter user mode for a newly forked process.
|
||||||
|
*
|
||||||
|
* This function is provided as a reminder. You need to write
|
||||||
|
* both it and the code that calls it.
|
||||||
|
*
|
||||||
|
* Thus, you can trash it and do things another way if you prefer.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
enter_forked_process(struct trapframe *tf)
|
||||||
|
{
|
||||||
|
(void)tf;
|
||||||
|
}
|
309
kern/arch/mips/thread/cpu.c
Normal file
309
kern/arch/mips/thread/cpu.c
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CPU control functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#include <mips/specialreg.h>
|
||||||
|
#include <mips/trapframe.h>
|
||||||
|
#include <platform/maxcpus.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
#include <thread.h>
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Startup and exception-time stack hook.
|
||||||
|
*
|
||||||
|
* The MIPS lacks a good way to find the current CPU, current thread,
|
||||||
|
* or current thread stack upon trap entry from user mode. To deal
|
||||||
|
* with this, we store the CPU number (our number, not the hardware
|
||||||
|
* number) in a nonessential field in the MMU, which is about the only
|
||||||
|
* place possible, and then use that to index cpustacks[]. This gets
|
||||||
|
* us the value to load as the stack pointer. We can then also load
|
||||||
|
* curthread from cputhreads[] by parallel indexing.
|
||||||
|
*
|
||||||
|
* These arrays are also used to start up new CPUs, for roughly the
|
||||||
|
* same reasons.
|
||||||
|
*
|
||||||
|
* The values in the current cpu's slots in these arrays are updated
|
||||||
|
* with the current thread's information in trap.c before heading to
|
||||||
|
* userlevel, as well as being initialized in cpu_machdep_init below.
|
||||||
|
* This means that (unless something really horrible happens) on entry
|
||||||
|
* to the kernel, and when a new CPU starts up in cpu_start_secondary,
|
||||||
|
* they will have the information needed to figure out who we are and
|
||||||
|
* proceed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
vaddr_t cpustacks[MAXCPUS];
|
||||||
|
vaddr_t cputhreads[MAXCPUS];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do machine-dependent initialization of the cpu structure or things
|
||||||
|
* associated with a new cpu. Note that we're not running on the new
|
||||||
|
* cpu when this is called.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
cpu_machdep_init(struct cpu *c)
|
||||||
|
{
|
||||||
|
vaddr_t stackpointer;
|
||||||
|
|
||||||
|
KASSERT(c->c_number < MAXCPUS);
|
||||||
|
|
||||||
|
if (c->c_curthread->t_stack == NULL) {
|
||||||
|
/* boot cpu; don't need to do anything here */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*
|
||||||
|
* Stick the stack in cpustacks[], and thread pointer
|
||||||
|
* in cputhreads[].
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* stack base address */
|
||||||
|
stackpointer = (vaddr_t) c->c_curthread->t_stack;
|
||||||
|
/* since stacks grow down, get the top */
|
||||||
|
stackpointer += STACK_SIZE;
|
||||||
|
|
||||||
|
cpustacks[c->c_number] = stackpointer;
|
||||||
|
cputhreads[c->c_number] = (vaddr_t)c->c_curthread;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the type name of the currently running CPU.
|
||||||
|
*
|
||||||
|
* For now, assume we're running on System/161 so we can use the
|
||||||
|
* System/161 processor-ID values.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SYS161_PRID_ORIG 0x000003ff
|
||||||
|
#define SYS161_PRID_2X 0x000000a1
|
||||||
|
|
||||||
|
static inline
|
||||||
|
uint32_t
|
||||||
|
cpu_getprid(void)
|
||||||
|
{
|
||||||
|
uint32_t prid;
|
||||||
|
|
||||||
|
__asm volatile("mfc0 %0,$15" : "=r" (prid));
|
||||||
|
return prid;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
uint32_t
|
||||||
|
cpu_getfeatures(void)
|
||||||
|
{
|
||||||
|
uint32_t features;
|
||||||
|
|
||||||
|
__asm volatile(".set push;" /* save assembler mode */
|
||||||
|
".set mips32;" /* allow mips32 instructions */
|
||||||
|
"mfc0 %0,$15,1;" /* get cop0 reg 15 sel 1 */
|
||||||
|
".set pop" /* restore assembler mode */
|
||||||
|
: "=r" (features));
|
||||||
|
return features;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
uint32_t
|
||||||
|
cpu_getifeatures(void)
|
||||||
|
{
|
||||||
|
uint32_t features;
|
||||||
|
|
||||||
|
__asm volatile(".set push;" /* save assembler mode */
|
||||||
|
".set mips32;" /* allow mips32 instructions */
|
||||||
|
"mfc0 %0,$15,2;" /* get cop0 reg 15 sel 2 */
|
||||||
|
".set pop" /* restore assembler mode */
|
||||||
|
: "=r" (features));
|
||||||
|
return features;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cpu_identify(char *buf, size_t max)
|
||||||
|
{
|
||||||
|
uint32_t prid;
|
||||||
|
uint32_t features;
|
||||||
|
|
||||||
|
prid = cpu_getprid();
|
||||||
|
switch (prid) {
|
||||||
|
case SYS161_PRID_ORIG:
|
||||||
|
snprintf(buf, max, "MIPS/161 (System/161 1.x and pre-2.x)");
|
||||||
|
break;
|
||||||
|
case SYS161_PRID_2X:
|
||||||
|
features = cpu_getfeatures();
|
||||||
|
snprintf(buf, max, "MIPS/161 (System/161 2.x) features 0x%x",
|
||||||
|
features);
|
||||||
|
features = cpu_getifeatures();
|
||||||
|
if (features != 0) {
|
||||||
|
kprintf("WARNING: unknown CPU incompatible features "
|
||||||
|
"0x%x\n", features);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
snprintf(buf, max, "32-bit MIPS (unknown type, CPU ID 0x%x)",
|
||||||
|
prid);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interrupt control.
|
||||||
|
*
|
||||||
|
* While the mips actually has on-chip interrupt priority masking, in
|
||||||
|
* the interests of simplicity, we don't use it. Instead we use
|
||||||
|
* coprocessor 0 register 12 (the system coprocessor "status"
|
||||||
|
* register) bit 0, IEc, which is the global interrupt enable flag.
|
||||||
|
* (IEc stands for interrupt-enable-current.)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* gcc inline assembly to get at the status register.
|
||||||
|
*
|
||||||
|
* Pipeline hazards:
|
||||||
|
* - there must be at least one cycle between GET_STATUS
|
||||||
|
* and SET_STATUS;
|
||||||
|
* - it may take up to three cycles after SET_STATUS for the
|
||||||
|
* interrupt state to really change.
|
||||||
|
*
|
||||||
|
* These considerations do not (currently) apply to System/161,
|
||||||
|
* however.
|
||||||
|
*/
|
||||||
|
#define GET_STATUS(x) __asm volatile("mfc0 %0,$12" : "=r" (x))
|
||||||
|
#define SET_STATUS(x) __asm volatile("mtc0 %0,$12" :: "r" (x))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interrupts on.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
cpu_irqon(void)
|
||||||
|
{
|
||||||
|
uint32_t x;
|
||||||
|
|
||||||
|
GET_STATUS(x);
|
||||||
|
x |= CST_IEc;
|
||||||
|
SET_STATUS(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interrupts off.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
cpu_irqoff(void)
|
||||||
|
{
|
||||||
|
uint32_t x;
|
||||||
|
|
||||||
|
GET_STATUS(x);
|
||||||
|
x &= ~(uint32_t)CST_IEc;
|
||||||
|
SET_STATUS(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used below.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
void
|
||||||
|
cpu_irqonoff(void)
|
||||||
|
{
|
||||||
|
uint32_t x, xon, xoff;
|
||||||
|
|
||||||
|
GET_STATUS(x);
|
||||||
|
xon = x | CST_IEc;
|
||||||
|
xoff = x & ~(uint32_t)CST_IEc;
|
||||||
|
SET_STATUS(xon);
|
||||||
|
__asm volatile("nop; nop; nop; nop");
|
||||||
|
SET_STATUS(xoff);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Idling.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* gcc inline assembly for the WAIT instruction.
|
||||||
|
*
|
||||||
|
* mips r2k/r3k has no idle instruction at all.
|
||||||
|
*
|
||||||
|
* However, to avoid completely overloading the computing cluster, we
|
||||||
|
* appropriate the mips32 WAIT instruction.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
wait(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The WAIT instruction goes into powersave mode until an
|
||||||
|
* interrupt is trying to occur.
|
||||||
|
*
|
||||||
|
* Then switch interrupts on and off again, so we actually
|
||||||
|
* take the interrupt.
|
||||||
|
*
|
||||||
|
* Note that the precise behavior of this instruction in the
|
||||||
|
* System/161 simulator is partly guesswork. This code may not
|
||||||
|
* work on a real mips.
|
||||||
|
*/
|
||||||
|
__asm volatile(
|
||||||
|
".set push;" /* save assembler mode */
|
||||||
|
".set mips32;" /* allow MIPS32 instructions */
|
||||||
|
".set volatile;" /* avoid unwanted optimization */
|
||||||
|
"wait;" /* suspend until interrupted */
|
||||||
|
".set pop" /* restore assembler mode */
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Idle the processor until something happens.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
cpu_idle(void)
|
||||||
|
{
|
||||||
|
wait();
|
||||||
|
cpu_irqonoff();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Halt the CPU permanently.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
cpu_halt(void)
|
||||||
|
{
|
||||||
|
cpu_irqoff();
|
||||||
|
while (1) {
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
}
|
99
kern/arch/mips/thread/switch.S
Normal file
99
kern/arch/mips/thread/switch.S
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assembly language context switch code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kern/mips/regdefs.h>
|
||||||
|
|
||||||
|
.text
|
||||||
|
.set noreorder
|
||||||
|
|
||||||
|
.globl switchframe_switch
|
||||||
|
.type switchframe_switch,@function
|
||||||
|
.ent switchframe_switch
|
||||||
|
switchframe_switch:
|
||||||
|
/*
|
||||||
|
* a0 contains the address of the switchframe pointer in the old thread.
|
||||||
|
* a1 contains the address of the switchframe pointer in the new thread.
|
||||||
|
*
|
||||||
|
* The switchframe pointer is really the stack pointer. The other
|
||||||
|
* registers get saved on the stack, namely:
|
||||||
|
*
|
||||||
|
* s0-s6, s8
|
||||||
|
* gp, ra
|
||||||
|
*
|
||||||
|
* The order must match <mips/switchframe.h>.
|
||||||
|
*
|
||||||
|
* Note that while we'd ordinarily need to save s7 too, because we
|
||||||
|
* use it to hold curthread saving it would interfere with the way
|
||||||
|
* curthread is managed by thread.c. So we'll just let thread.c
|
||||||
|
* manage it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Allocate stack space for saving 10 registers. 10*4 = 40 */
|
||||||
|
addi sp, sp, -40
|
||||||
|
|
||||||
|
/* Save the registers */
|
||||||
|
sw ra, 36(sp)
|
||||||
|
sw gp, 32(sp)
|
||||||
|
sw s8, 28(sp)
|
||||||
|
sw s6, 24(sp)
|
||||||
|
sw s5, 20(sp)
|
||||||
|
sw s4, 16(sp)
|
||||||
|
sw s3, 12(sp)
|
||||||
|
sw s2, 8(sp)
|
||||||
|
sw s1, 4(sp)
|
||||||
|
sw s0, 0(sp)
|
||||||
|
|
||||||
|
/* Store the old stack pointer in the old thread */
|
||||||
|
sw sp, 0(a0)
|
||||||
|
|
||||||
|
/* Get the new stack pointer from the new thread */
|
||||||
|
lw sp, 0(a1)
|
||||||
|
nop /* delay slot for load */
|
||||||
|
|
||||||
|
/* Now, restore the registers */
|
||||||
|
lw s0, 0(sp)
|
||||||
|
lw s1, 4(sp)
|
||||||
|
lw s2, 8(sp)
|
||||||
|
lw s3, 12(sp)
|
||||||
|
lw s4, 16(sp)
|
||||||
|
lw s5, 20(sp)
|
||||||
|
lw s6, 24(sp)
|
||||||
|
lw s8, 28(sp)
|
||||||
|
lw gp, 32(sp)
|
||||||
|
lw ra, 36(sp)
|
||||||
|
nop /* delay slot for load */
|
||||||
|
|
||||||
|
/* and return. */
|
||||||
|
j ra
|
||||||
|
addi sp, sp, 40 /* in delay slot */
|
||||||
|
.end switchframe_switch
|
98
kern/arch/mips/thread/switchframe.c
Normal file
98
kern/arch/mips/thread/switchframe.c
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#include <thread.h>
|
||||||
|
#include <threadprivate.h>
|
||||||
|
|
||||||
|
#include "switchframe.h"
|
||||||
|
|
||||||
|
/* in threadstart.S */
|
||||||
|
extern void mips_threadstart(/* arguments are in unusual registers */);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function to initialize the switchframe of a new thread, which is
|
||||||
|
* *not* the one that is currently running.
|
||||||
|
*
|
||||||
|
* The new thread should, when it is run the first time, end up calling
|
||||||
|
* thread_startup(entrypoint, data1, data2).
|
||||||
|
*
|
||||||
|
* We arrange for this by creating a phony switchframe for
|
||||||
|
* switchframe_switch() to switch to. The only trouble is that the
|
||||||
|
* switchframe doesn't include the argument registers a0-a3. So we
|
||||||
|
* store the arguments in the s* registers, and use a bit of asm
|
||||||
|
* (mips_threadstart) to move them and then jump to thread_startup.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
switchframe_init(struct thread *thread,
|
||||||
|
void (*entrypoint)(void *data1, unsigned long data2),
|
||||||
|
void *data1, unsigned long data2)
|
||||||
|
{
|
||||||
|
vaddr_t stacktop;
|
||||||
|
struct switchframe *sf;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MIPS stacks grow down. t_stack is just a hunk of memory, so
|
||||||
|
* get the other end of it. Then set up a switchframe on the
|
||||||
|
* top of the stack.
|
||||||
|
*/
|
||||||
|
stacktop = ((vaddr_t)thread->t_stack) + STACK_SIZE;
|
||||||
|
sf = ((struct switchframe *) stacktop) - 1;
|
||||||
|
|
||||||
|
/* Zero out the switchframe. */
|
||||||
|
bzero(sf, sizeof(*sf));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now set the important parts: pass through the three arguments,
|
||||||
|
* and set the return address register to the place we want
|
||||||
|
* execution to begin.
|
||||||
|
*
|
||||||
|
* Thus, when switchframe_switch does its "j ra", it will
|
||||||
|
* actually jump to mips_threadstart, which will move the
|
||||||
|
* arguments into the right register and jump to
|
||||||
|
* thread_startup().
|
||||||
|
*
|
||||||
|
* Note that this means that when we call switchframe_switch()
|
||||||
|
* in thread_switch(), we may not come back out the same way
|
||||||
|
* in the next thread. (Though we will come back out the same
|
||||||
|
* way when we later come back to the same thread again.)
|
||||||
|
*
|
||||||
|
* This has implications for code at the bottom of
|
||||||
|
* thread_switch, described in thread.c.
|
||||||
|
*/
|
||||||
|
sf->sf_s0 = (uint32_t)entrypoint;
|
||||||
|
sf->sf_s1 = (uint32_t)data1;
|
||||||
|
sf->sf_s2 = (uint32_t)data2;
|
||||||
|
sf->sf_ra = (uint32_t)mips_threadstart;
|
||||||
|
|
||||||
|
/* Set ->t_context, and we're done. */
|
||||||
|
thread->t_context = sf;
|
||||||
|
}
|
52
kern/arch/mips/thread/switchframe.h
Normal file
52
kern/arch/mips/thread/switchframe.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MIPS_SWITCHFRAME_H_
|
||||||
|
#define _MIPS_SWITCHFRAME_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure describing what is saved on the stack during a context switch.
|
||||||
|
*
|
||||||
|
* This must agree with the code in switch.S.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct switchframe {
|
||||||
|
uint32_t sf_s0;
|
||||||
|
uint32_t sf_s1;
|
||||||
|
uint32_t sf_s2;
|
||||||
|
uint32_t sf_s3;
|
||||||
|
uint32_t sf_s4;
|
||||||
|
uint32_t sf_s5;
|
||||||
|
uint32_t sf_s6;
|
||||||
|
uint32_t sf_s8;
|
||||||
|
uint32_t sf_gp;
|
||||||
|
uint32_t sf_ra;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _MIPS_SWITCHFRAME_H_ */
|
49
kern/arch/mips/thread/thread_machdep.c
Normal file
49
kern/arch/mips/thread/thread_machdep.c
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Functions for handling struct thread_machdep.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#include <thread.h>
|
||||||
|
#include <threadprivate.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
thread_machdep_init(struct thread_machdep *tm)
|
||||||
|
{
|
||||||
|
tm->tm_badfaultfunc = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
thread_machdep_cleanup(struct thread_machdep *tm)
|
||||||
|
{
|
||||||
|
KASSERT(tm->tm_badfaultfunc == NULL);
|
||||||
|
}
|
68
kern/arch/mips/thread/threadstart.S
Normal file
68
kern/arch/mips/thread/threadstart.S
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assembler-level thread startup trampoline.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kern/mips/regdefs.h>
|
||||||
|
|
||||||
|
.text
|
||||||
|
.set noreorder
|
||||||
|
|
||||||
|
.globl mips_threadstart
|
||||||
|
.type mips_threadstart,@function
|
||||||
|
.ent mips_threadstart
|
||||||
|
mips_threadstart:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This code doesn't take normal arguments. It's reached when
|
||||||
|
* switchframe_switch switches to a new thread. switchframe_switch
|
||||||
|
* does "j ra"; ra gets preloaded in switchframe_init to come here.
|
||||||
|
*
|
||||||
|
* Our arguments are in callee-save registers, as follows:
|
||||||
|
*
|
||||||
|
* s0 entrypoint
|
||||||
|
* s1 data1
|
||||||
|
* s2 data2
|
||||||
|
*
|
||||||
|
* We need to rearrange these so as to call the normal C function
|
||||||
|
* thread_startup(void (*entrypoint)(), void *data1, unsigned long data2).
|
||||||
|
*/
|
||||||
|
|
||||||
|
addiu sp, sp, -16 /* make our stack frame */
|
||||||
|
|
||||||
|
move ra, $0 /* clear return addr so we're top of the call stack */
|
||||||
|
|
||||||
|
move a0, s0 /* load arguments and call */
|
||||||
|
move a1, s1
|
||||||
|
j thread_startup
|
||||||
|
move a2, s2 /* (in delay slot) */
|
||||||
|
|
||||||
|
.end mips_threadstart
|
427
kern/arch/mips/vm/dumbvm.c
Normal file
427
kern/arch/mips/vm/dumbvm.c
Normal file
@ -0,0 +1,427 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <kern/errno.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#include <spl.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
#include <spinlock.h>
|
||||||
|
#include <proc.h>
|
||||||
|
#include <current.h>
|
||||||
|
#include <mips/tlb.h>
|
||||||
|
#include <addrspace.h>
|
||||||
|
#include <vm.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dumb MIPS-only "VM system" that is intended to only be just barely
|
||||||
|
* enough to struggle off the ground. You should replace all of this
|
||||||
|
* code while doing the VM assignment. In fact, starting in that
|
||||||
|
* assignment, this file is not included in your kernel!
|
||||||
|
*
|
||||||
|
* NOTE: it's been found over the years that students often begin on
|
||||||
|
* the VM assignment by copying dumbvm.c and trying to improve it.
|
||||||
|
* This is not recommended. dumbvm is (more or less intentionally) not
|
||||||
|
* a good design reference. The first recommendation would be: do not
|
||||||
|
* look at dumbvm at all. The second recommendation would be: if you
|
||||||
|
* do, be sure to review it from the perspective of comparing it to
|
||||||
|
* what a VM system is supposed to do, and understanding what corners
|
||||||
|
* it's cutting (there are many) and why, and more importantly, how.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* under dumbvm, always have 72k of user stack */
|
||||||
|
/* (this must be > 64K so argument blocks of size ARG_MAX will fit) */
|
||||||
|
#define DUMBVM_STACKPAGES 18
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wrap ram_stealmem in a spinlock.
|
||||||
|
*/
|
||||||
|
static struct spinlock stealmem_lock = SPINLOCK_INITIALIZER;
|
||||||
|
|
||||||
|
void
|
||||||
|
vm_bootstrap(void)
|
||||||
|
{
|
||||||
|
/* Do nothing. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if we're in a context that can sleep. While most of the
|
||||||
|
* operations in dumbvm don't in fact sleep, in a real VM system many
|
||||||
|
* of them would. In those, assert that sleeping is ok. This helps
|
||||||
|
* avoid the situation where syscall-layer code that works ok with
|
||||||
|
* dumbvm starts blowing up during the VM assignment.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
void
|
||||||
|
dumbvm_can_sleep(void)
|
||||||
|
{
|
||||||
|
if (CURCPU_EXISTS()) {
|
||||||
|
/* must not hold spinlocks */
|
||||||
|
KASSERT(curcpu->c_spinlocks == 0);
|
||||||
|
|
||||||
|
/* must not be in an interrupt handler */
|
||||||
|
KASSERT(curthread->t_in_interrupt == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
paddr_t
|
||||||
|
getppages(unsigned long npages)
|
||||||
|
{
|
||||||
|
paddr_t addr;
|
||||||
|
|
||||||
|
spinlock_acquire(&stealmem_lock);
|
||||||
|
|
||||||
|
addr = ram_stealmem(npages);
|
||||||
|
|
||||||
|
spinlock_release(&stealmem_lock);
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate/free some kernel-space virtual pages */
|
||||||
|
vaddr_t
|
||||||
|
alloc_kpages(unsigned npages)
|
||||||
|
{
|
||||||
|
paddr_t pa;
|
||||||
|
|
||||||
|
dumbvm_can_sleep();
|
||||||
|
pa = getppages(npages);
|
||||||
|
if (pa==0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return PADDR_TO_KVADDR(pa);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
free_kpages(vaddr_t addr)
|
||||||
|
{
|
||||||
|
/* nothing - leak the memory. */
|
||||||
|
|
||||||
|
(void)addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
vm_tlbshootdown(const struct tlbshootdown *ts)
|
||||||
|
{
|
||||||
|
(void)ts;
|
||||||
|
panic("dumbvm tried to do tlb shootdown?!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
vm_fault(int faulttype, vaddr_t faultaddress)
|
||||||
|
{
|
||||||
|
vaddr_t vbase1, vtop1, vbase2, vtop2, stackbase, stacktop;
|
||||||
|
paddr_t paddr;
|
||||||
|
int i;
|
||||||
|
uint32_t ehi, elo;
|
||||||
|
struct addrspace *as;
|
||||||
|
int spl;
|
||||||
|
|
||||||
|
faultaddress &= PAGE_FRAME;
|
||||||
|
|
||||||
|
DEBUG(DB_VM, "dumbvm: fault: 0x%x\n", faultaddress);
|
||||||
|
|
||||||
|
switch (faulttype) {
|
||||||
|
case VM_FAULT_READONLY:
|
||||||
|
/* We always create pages read-write, so we can't get this */
|
||||||
|
panic("dumbvm: got VM_FAULT_READONLY\n");
|
||||||
|
case VM_FAULT_READ:
|
||||||
|
case VM_FAULT_WRITE:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curproc == NULL) {
|
||||||
|
/*
|
||||||
|
* No process. This is probably a kernel fault early
|
||||||
|
* in boot. Return EFAULT so as to panic instead of
|
||||||
|
* getting into an infinite faulting loop.
|
||||||
|
*/
|
||||||
|
return EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
as = proc_getas();
|
||||||
|
if (as == NULL) {
|
||||||
|
/*
|
||||||
|
* No address space set up. This is probably also a
|
||||||
|
* kernel fault early in boot.
|
||||||
|
*/
|
||||||
|
return EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assert that the address space has been set up properly. */
|
||||||
|
KASSERT(as->as_vbase1 != 0);
|
||||||
|
KASSERT(as->as_pbase1 != 0);
|
||||||
|
KASSERT(as->as_npages1 != 0);
|
||||||
|
KASSERT(as->as_vbase2 != 0);
|
||||||
|
KASSERT(as->as_pbase2 != 0);
|
||||||
|
KASSERT(as->as_npages2 != 0);
|
||||||
|
KASSERT(as->as_stackpbase != 0);
|
||||||
|
KASSERT((as->as_vbase1 & PAGE_FRAME) == as->as_vbase1);
|
||||||
|
KASSERT((as->as_pbase1 & PAGE_FRAME) == as->as_pbase1);
|
||||||
|
KASSERT((as->as_vbase2 & PAGE_FRAME) == as->as_vbase2);
|
||||||
|
KASSERT((as->as_pbase2 & PAGE_FRAME) == as->as_pbase2);
|
||||||
|
KASSERT((as->as_stackpbase & PAGE_FRAME) == as->as_stackpbase);
|
||||||
|
|
||||||
|
vbase1 = as->as_vbase1;
|
||||||
|
vtop1 = vbase1 + as->as_npages1 * PAGE_SIZE;
|
||||||
|
vbase2 = as->as_vbase2;
|
||||||
|
vtop2 = vbase2 + as->as_npages2 * PAGE_SIZE;
|
||||||
|
stackbase = USERSTACK - DUMBVM_STACKPAGES * PAGE_SIZE;
|
||||||
|
stacktop = USERSTACK;
|
||||||
|
|
||||||
|
if (faultaddress >= vbase1 && faultaddress < vtop1) {
|
||||||
|
paddr = (faultaddress - vbase1) + as->as_pbase1;
|
||||||
|
}
|
||||||
|
else if (faultaddress >= vbase2 && faultaddress < vtop2) {
|
||||||
|
paddr = (faultaddress - vbase2) + as->as_pbase2;
|
||||||
|
}
|
||||||
|
else if (faultaddress >= stackbase && faultaddress < stacktop) {
|
||||||
|
paddr = (faultaddress - stackbase) + as->as_stackpbase;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make sure it's page-aligned */
|
||||||
|
KASSERT((paddr & PAGE_FRAME) == paddr);
|
||||||
|
|
||||||
|
/* Disable interrupts on this CPU while frobbing the TLB. */
|
||||||
|
spl = splhigh();
|
||||||
|
|
||||||
|
for (i=0; i<NUM_TLB; i++) {
|
||||||
|
tlb_read(&ehi, &elo, i);
|
||||||
|
if (elo & TLBLO_VALID) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ehi = faultaddress;
|
||||||
|
elo = paddr | TLBLO_DIRTY | TLBLO_VALID;
|
||||||
|
DEBUG(DB_VM, "dumbvm: 0x%x -> 0x%x\n", faultaddress, paddr);
|
||||||
|
tlb_write(ehi, elo, i);
|
||||||
|
splx(spl);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
kprintf("dumbvm: Ran out of TLB entries - cannot handle page fault\n");
|
||||||
|
splx(spl);
|
||||||
|
return EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct addrspace *
|
||||||
|
as_create(void)
|
||||||
|
{
|
||||||
|
struct addrspace *as = kmalloc(sizeof(struct addrspace));
|
||||||
|
if (as==NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
as->as_vbase1 = 0;
|
||||||
|
as->as_pbase1 = 0;
|
||||||
|
as->as_npages1 = 0;
|
||||||
|
as->as_vbase2 = 0;
|
||||||
|
as->as_pbase2 = 0;
|
||||||
|
as->as_npages2 = 0;
|
||||||
|
as->as_stackpbase = 0;
|
||||||
|
|
||||||
|
return as;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
as_destroy(struct addrspace *as)
|
||||||
|
{
|
||||||
|
dumbvm_can_sleep();
|
||||||
|
kfree(as);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
as_activate(void)
|
||||||
|
{
|
||||||
|
int i, spl;
|
||||||
|
struct addrspace *as;
|
||||||
|
|
||||||
|
as = proc_getas();
|
||||||
|
if (as == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable interrupts on this CPU while frobbing the TLB. */
|
||||||
|
spl = splhigh();
|
||||||
|
|
||||||
|
for (i=0; i<NUM_TLB; i++) {
|
||||||
|
tlb_write(TLBHI_INVALID(i), TLBLO_INVALID(), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
splx(spl);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
as_deactivate(void)
|
||||||
|
{
|
||||||
|
/* nothing */
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
as_define_region(struct addrspace *as, vaddr_t vaddr, size_t sz,
|
||||||
|
int readable, int writeable, int executable)
|
||||||
|
{
|
||||||
|
size_t npages;
|
||||||
|
|
||||||
|
dumbvm_can_sleep();
|
||||||
|
|
||||||
|
/* Align the region. First, the base... */
|
||||||
|
sz += vaddr & ~(vaddr_t)PAGE_FRAME;
|
||||||
|
vaddr &= PAGE_FRAME;
|
||||||
|
|
||||||
|
/* ...and now the length. */
|
||||||
|
sz = (sz + PAGE_SIZE - 1) & PAGE_FRAME;
|
||||||
|
|
||||||
|
npages = sz / PAGE_SIZE;
|
||||||
|
|
||||||
|
/* We don't use these - all pages are read-write */
|
||||||
|
(void)readable;
|
||||||
|
(void)writeable;
|
||||||
|
(void)executable;
|
||||||
|
|
||||||
|
if (as->as_vbase1 == 0) {
|
||||||
|
as->as_vbase1 = vaddr;
|
||||||
|
as->as_npages1 = npages;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (as->as_vbase2 == 0) {
|
||||||
|
as->as_vbase2 = vaddr;
|
||||||
|
as->as_npages2 = npages;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Support for more than two regions is not available.
|
||||||
|
*/
|
||||||
|
kprintf("dumbvm: Warning: too many regions\n");
|
||||||
|
return ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
as_zero_region(paddr_t paddr, unsigned npages)
|
||||||
|
{
|
||||||
|
bzero((void *)PADDR_TO_KVADDR(paddr), npages * PAGE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
as_prepare_load(struct addrspace *as)
|
||||||
|
{
|
||||||
|
KASSERT(as->as_pbase1 == 0);
|
||||||
|
KASSERT(as->as_pbase2 == 0);
|
||||||
|
KASSERT(as->as_stackpbase == 0);
|
||||||
|
|
||||||
|
dumbvm_can_sleep();
|
||||||
|
|
||||||
|
as->as_pbase1 = getppages(as->as_npages1);
|
||||||
|
if (as->as_pbase1 == 0) {
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
as->as_pbase2 = getppages(as->as_npages2);
|
||||||
|
if (as->as_pbase2 == 0) {
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
as->as_stackpbase = getppages(DUMBVM_STACKPAGES);
|
||||||
|
if (as->as_stackpbase == 0) {
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
as_zero_region(as->as_pbase1, as->as_npages1);
|
||||||
|
as_zero_region(as->as_pbase2, as->as_npages2);
|
||||||
|
as_zero_region(as->as_stackpbase, DUMBVM_STACKPAGES);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
as_complete_load(struct addrspace *as)
|
||||||
|
{
|
||||||
|
dumbvm_can_sleep();
|
||||||
|
(void)as;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
as_define_stack(struct addrspace *as, vaddr_t *stackptr)
|
||||||
|
{
|
||||||
|
KASSERT(as->as_stackpbase != 0);
|
||||||
|
|
||||||
|
*stackptr = USERSTACK;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
as_copy(struct addrspace *old, struct addrspace **ret)
|
||||||
|
{
|
||||||
|
struct addrspace *new;
|
||||||
|
|
||||||
|
dumbvm_can_sleep();
|
||||||
|
|
||||||
|
new = as_create();
|
||||||
|
if (new==NULL) {
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
new->as_vbase1 = old->as_vbase1;
|
||||||
|
new->as_npages1 = old->as_npages1;
|
||||||
|
new->as_vbase2 = old->as_vbase2;
|
||||||
|
new->as_npages2 = old->as_npages2;
|
||||||
|
|
||||||
|
/* (Mis)use as_prepare_load to allocate some physical memory. */
|
||||||
|
if (as_prepare_load(new)) {
|
||||||
|
as_destroy(new);
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
KASSERT(new->as_pbase1 != 0);
|
||||||
|
KASSERT(new->as_pbase2 != 0);
|
||||||
|
KASSERT(new->as_stackpbase != 0);
|
||||||
|
|
||||||
|
memmove((void *)PADDR_TO_KVADDR(new->as_pbase1),
|
||||||
|
(const void *)PADDR_TO_KVADDR(old->as_pbase1),
|
||||||
|
old->as_npages1*PAGE_SIZE);
|
||||||
|
|
||||||
|
memmove((void *)PADDR_TO_KVADDR(new->as_pbase2),
|
||||||
|
(const void *)PADDR_TO_KVADDR(old->as_pbase2),
|
||||||
|
old->as_npages2*PAGE_SIZE);
|
||||||
|
|
||||||
|
memmove((void *)PADDR_TO_KVADDR(new->as_stackpbase),
|
||||||
|
(const void *)PADDR_TO_KVADDR(old->as_stackpbase),
|
||||||
|
DUMBVM_STACKPAGES*PAGE_SIZE);
|
||||||
|
|
||||||
|
*ret = new;
|
||||||
|
return 0;
|
||||||
|
}
|
153
kern/arch/mips/vm/ram.c
Normal file
153
kern/arch/mips/vm/ram.c
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#include <vm.h>
|
||||||
|
#include <mainbus.h>
|
||||||
|
|
||||||
|
|
||||||
|
vaddr_t firstfree; /* first free virtual address; set by start.S */
|
||||||
|
|
||||||
|
static paddr_t firstpaddr; /* address of first free physical page */
|
||||||
|
static paddr_t lastpaddr; /* one past end of last free physical page */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called very early in system boot to figure out how much physical
|
||||||
|
* RAM is available.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ram_bootstrap(void)
|
||||||
|
{
|
||||||
|
size_t ramsize;
|
||||||
|
|
||||||
|
/* Get size of RAM. */
|
||||||
|
ramsize = mainbus_ramsize();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the same as the last physical address, as long as
|
||||||
|
* we have less than 512 megabytes of memory. If we had more,
|
||||||
|
* we wouldn't be able to access it all through kseg0 and
|
||||||
|
* everything would get a lot more complicated. This is not a
|
||||||
|
* case we are going to worry about.
|
||||||
|
*/
|
||||||
|
if (ramsize > 512*1024*1024) {
|
||||||
|
ramsize = 512*1024*1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastpaddr = ramsize;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get first free virtual address from where start.S saved it.
|
||||||
|
* Convert to physical address.
|
||||||
|
*/
|
||||||
|
firstpaddr = firstfree - MIPS_KSEG0;
|
||||||
|
|
||||||
|
kprintf("%uk physical memory available\n",
|
||||||
|
(lastpaddr-firstpaddr)/1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is for allocating physical memory prior to VM
|
||||||
|
* initialization.
|
||||||
|
*
|
||||||
|
* The pages it hands back will not be reported to the VM system when
|
||||||
|
* the VM system calls ram_getsize(). If it's desired to free up these
|
||||||
|
* pages later on after bootup is complete, some mechanism for adding
|
||||||
|
* them to the VM system's page management must be implemented.
|
||||||
|
* Alternatively, one can do enough VM initialization early so that
|
||||||
|
* this function is never needed.
|
||||||
|
*
|
||||||
|
* Note: while the error return value of 0 is a legal physical address,
|
||||||
|
* it's not a legal *allocatable* physical address, because it's the
|
||||||
|
* page with the exception handlers on it.
|
||||||
|
*
|
||||||
|
* This function should not be called once the VM system is initialized,
|
||||||
|
* so it is not synchronized.
|
||||||
|
*/
|
||||||
|
paddr_t
|
||||||
|
ram_stealmem(unsigned long npages)
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
paddr_t paddr;
|
||||||
|
|
||||||
|
size = npages * PAGE_SIZE;
|
||||||
|
|
||||||
|
if (firstpaddr + size > lastpaddr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
paddr = firstpaddr;
|
||||||
|
firstpaddr += size;
|
||||||
|
|
||||||
|
return paddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is intended to be called by the VM system when it
|
||||||
|
* initializes in order to find out what memory it has available to
|
||||||
|
* manage. Physical memory begins at physical address 0 and ends with
|
||||||
|
* the address returned by this function. We assume that physical
|
||||||
|
* memory is contiguous. This is not universally true, but is true on
|
||||||
|
* the MIPS platforms we intend to run on.
|
||||||
|
*
|
||||||
|
* lastpaddr is constant once set by ram_bootstrap(), so this function
|
||||||
|
* need not be synchronized.
|
||||||
|
*
|
||||||
|
* It is recommended, however, that this function be used only to
|
||||||
|
* initialize the VM system, after which the VM system should take
|
||||||
|
* charge of knowing what memory exists.
|
||||||
|
*/
|
||||||
|
paddr_t
|
||||||
|
ram_getsize(void)
|
||||||
|
{
|
||||||
|
return lastpaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is intended to be called by the VM system when it
|
||||||
|
* initializes in order to find out what memory it has available to
|
||||||
|
* manage.
|
||||||
|
*
|
||||||
|
* It can only be called once, and once called ram_stealmem() will
|
||||||
|
* no longer work, as that would invalidate the result it returned
|
||||||
|
* and lead to multiple things using the same memory.
|
||||||
|
*
|
||||||
|
* This function should not be called once the VM system is initialized,
|
||||||
|
* so it is not synchronized.
|
||||||
|
*/
|
||||||
|
paddr_t
|
||||||
|
ram_getfirstfree(void)
|
||||||
|
{
|
||||||
|
paddr_t ret;
|
||||||
|
|
||||||
|
ret = firstpaddr;
|
||||||
|
firstpaddr = lastpaddr = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
204
kern/arch/mips/vm/tlb-mips161.S
Normal file
204
kern/arch/mips/vm/tlb-mips161.S
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kern/mips/regdefs.h>
|
||||||
|
#include <mips/specialreg.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TLB handling for the MIPS-161.
|
||||||
|
*
|
||||||
|
* The MIPS-161 uses the simpler MIPS-1 (r2000/r3000) TLB rather
|
||||||
|
* than the paired-page TLB of later MIPS models.
|
||||||
|
*
|
||||||
|
* However, we handle MIPS32 pipeline hazards. If you want to run on
|
||||||
|
* a real MIPS-1, change the ssnops to plain nops and check where and
|
||||||
|
* how many you need in the matching processor docs.
|
||||||
|
*
|
||||||
|
* (ssnop means "superscalar nop"; it exists because the pipeline
|
||||||
|
* hazards require a fixed number of cycles, and a superscalar CPU can
|
||||||
|
* potentially issue arbitrarily many nops in one cycle.)
|
||||||
|
*/
|
||||||
|
|
||||||
|
.text
|
||||||
|
.set noreorder
|
||||||
|
.set mips32 /* so we can use ssnop */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tlb_random: use the "tlbwr" instruction to write a TLB entry
|
||||||
|
* into a (very pseudo-) random slot in the TLB.
|
||||||
|
*
|
||||||
|
* Pipeline hazard: must wait between setting entryhi/lo and
|
||||||
|
* doing the tlbwr. Use two cycles; some processors may vary.
|
||||||
|
*/
|
||||||
|
.globl tlb_random
|
||||||
|
.type tlb_random,@function
|
||||||
|
.ent tlb_random
|
||||||
|
tlb_random:
|
||||||
|
mtc0 a0, c0_entryhi /* store the passed entry into the */
|
||||||
|
mtc0 a1, c0_entrylo /* tlb entry registers */
|
||||||
|
ssnop /* wait for pipeline hazard */
|
||||||
|
ssnop
|
||||||
|
tlbwr /* do it */
|
||||||
|
j ra
|
||||||
|
nop
|
||||||
|
.end tlb_random
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tlb_write: use the "tlbwi" instruction to write a TLB entry
|
||||||
|
* into a selected slot in the TLB.
|
||||||
|
*
|
||||||
|
* Pipeline hazard: must wait between setting entryhi/lo and
|
||||||
|
* doing the tlbwi. Use two cycles; some processors may vary.
|
||||||
|
*/
|
||||||
|
.text
|
||||||
|
.globl tlb_write
|
||||||
|
.type tlb_write,@function
|
||||||
|
.ent tlb_write
|
||||||
|
tlb_write:
|
||||||
|
mtc0 a0, c0_entryhi /* store the passed entry into the */
|
||||||
|
mtc0 a1, c0_entrylo /* tlb entry registers */
|
||||||
|
sll t0, a2, CIN_INDEXSHIFT /* shift the passed index into place */
|
||||||
|
mtc0 t0, c0_index /* store the shifted index into the index register */
|
||||||
|
ssnop /* wait for pipeline hazard */
|
||||||
|
ssnop
|
||||||
|
tlbwi /* do it */
|
||||||
|
j ra
|
||||||
|
nop
|
||||||
|
.end tlb_write
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tlb_read: use the "tlbr" instruction to read a TLB entry
|
||||||
|
* from a selected slot in the TLB.
|
||||||
|
*
|
||||||
|
* Pipeline hazard: must wait between setting c0_index and
|
||||||
|
* doing the tlbr. Use two cycles; some processors may vary.
|
||||||
|
* Similarly, three more cycles before reading c0_entryhi/lo.
|
||||||
|
*/
|
||||||
|
.text
|
||||||
|
.globl tlb_read
|
||||||
|
.type tlb_read,@function
|
||||||
|
.ent tlb_read
|
||||||
|
tlb_read:
|
||||||
|
sll t0, a2, CIN_INDEXSHIFT /* shift the passed index into place */
|
||||||
|
mtc0 t0, c0_index /* store the shifted index into the index register */
|
||||||
|
ssnop /* wait for pipeline hazard */
|
||||||
|
ssnop
|
||||||
|
tlbr /* do it */
|
||||||
|
ssnop /* wait for pipeline hazard */
|
||||||
|
ssnop
|
||||||
|
ssnop
|
||||||
|
mfc0 t0, c0_entryhi /* get the tlb entry out of the */
|
||||||
|
mfc0 t1, c0_entrylo /* tlb entry registers */
|
||||||
|
sw t0, 0(a0) /* store through the passed pointer */
|
||||||
|
j ra
|
||||||
|
sw t1, 0(a1) /* store (in delay slot) */
|
||||||
|
.end tlb_read
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tlb_probe: use the "tlbp" instruction to find the index in the
|
||||||
|
* TLB of a TLB entry matching the relevant parts of the one supplied.
|
||||||
|
*
|
||||||
|
* Pipeline hazard: must wait between setting c0_entryhi/lo and
|
||||||
|
* doing the tlbp. Use two cycles; some processors may vary.
|
||||||
|
* Similarly, two more cycles before reading c0_index.
|
||||||
|
*/
|
||||||
|
.text
|
||||||
|
.globl tlb_probe
|
||||||
|
.type tlb_probe,@function
|
||||||
|
.ent tlb_probe
|
||||||
|
tlb_probe:
|
||||||
|
mtc0 a0, c0_entryhi /* store the passed entry into the */
|
||||||
|
mtc0 a1, c0_entrylo /* tlb entry registers */
|
||||||
|
ssnop /* wait for pipeline hazard */
|
||||||
|
ssnop
|
||||||
|
tlbp /* do it */
|
||||||
|
ssnop /* wait for pipeline hazard */
|
||||||
|
ssnop
|
||||||
|
mfc0 t0, c0_index /* fetch the index back in t0 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the high bit (CIN_P) of c0_index is set, the probe failed.
|
||||||
|
* The high bit is not set <--> c0_index (now in t0) >= 0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bgez t0, 1f /* did probe succeed? if so, skip forward */
|
||||||
|
nop /* delay slot */
|
||||||
|
addi v0, z0, -1 /* set return value to -1 to indicate failure */
|
||||||
|
j ra /* done */
|
||||||
|
nop /* delay slot */
|
||||||
|
|
||||||
|
1:
|
||||||
|
/* succeeded - get the index field from the index register value */
|
||||||
|
andi t1, t0, CIN_INDEX /* mask off the field */
|
||||||
|
j ra /* done */
|
||||||
|
sra v0, t1, CIN_INDEXSHIFT /* shift it (in delay slot) */
|
||||||
|
.end tlb_probe
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tlb_reset
|
||||||
|
*
|
||||||
|
* Initialize the TLB. At processor startup, the TLB state is completely
|
||||||
|
* undefined. So be sure to avoid creating any duplicates. Also make sure
|
||||||
|
* that the initialization entries don't duplicate the INVALID entries
|
||||||
|
* defined in tlb.h. (This way you can write the invalid entries in
|
||||||
|
* without having to use tlbp to find out if they're going to cause dups.)
|
||||||
|
*
|
||||||
|
* This function is not defined in tlb.h because it's only called from
|
||||||
|
* start.S.
|
||||||
|
*
|
||||||
|
* Pipeline hazards are as above.
|
||||||
|
*/
|
||||||
|
.text
|
||||||
|
.globl tlb_reset
|
||||||
|
.type tlb_reset,@function
|
||||||
|
.ent tlb_reset
|
||||||
|
tlb_reset:
|
||||||
|
li t0, 0 /* t0 <- tlb index number (shifted) */
|
||||||
|
li t1, 0x81000000 /* t1 <- tlb reset vaddr */
|
||||||
|
1:
|
||||||
|
mtc0 $0, c0_entrylo /* set up proposed tlb entry for reset */
|
||||||
|
mtc0 t1, c0_entryhi
|
||||||
|
ssnop /* wait for pipeline hazard */
|
||||||
|
ssnop
|
||||||
|
tlbp /* check if it already exists */
|
||||||
|
ssnop /* wait for pipeline hazard */
|
||||||
|
ssnop
|
||||||
|
mfc0 t2, c0_index
|
||||||
|
bgez t2, 1b /* if it does, loop back */
|
||||||
|
addiu t1, t1, 0x1000 /* next vaddr (in delay slot) */
|
||||||
|
mtc0 t0, c0_index /* doesn't exist, set index to write to */
|
||||||
|
ssnop /* wait for pipeline hazard */
|
||||||
|
ssnop
|
||||||
|
addiu t0, t0, 0x100 /* next tlb index (shifted) */
|
||||||
|
bne t0, 0x4000, 1b /* if it's not the last tlb index, loop */
|
||||||
|
tlbwi /* write tlb entry (in delay slot) */
|
||||||
|
j ra /* done */
|
||||||
|
nop /* delay slot */
|
||||||
|
.end tlb_reset
|
34
kern/arch/sys161/conf/conf.arch
Normal file
34
kern/arch/sys161/conf/conf.arch
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
#
|
||||||
|
# Platform-dependent sources for System/161.
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# locore
|
||||||
|
#
|
||||||
|
|
||||||
|
# Cache handling for the kind of MIPS we have
|
||||||
|
platform sys161 file arch/mips/locore/cache-mips161.S
|
||||||
|
|
||||||
|
# Exception handling (assembler entry points) for the kind of MIPS we have
|
||||||
|
platform sys161 file arch/mips/locore/exception-mips1.S
|
||||||
|
|
||||||
|
#
|
||||||
|
# VM
|
||||||
|
#
|
||||||
|
|
||||||
|
# TLB handling for the kind of MIPS we have
|
||||||
|
platform sys161 file arch/mips/vm/tlb-mips161.S
|
||||||
|
|
||||||
|
#
|
||||||
|
# Devices. We have LAMEbus.
|
||||||
|
#
|
||||||
|
|
||||||
|
platform sys161 file arch/sys161/dev/lamebus_machdep.c
|
||||||
|
include dev/lamebus/conf.lamebus
|
||||||
|
|
||||||
|
#
|
||||||
|
# Startup and initialization.
|
||||||
|
#
|
||||||
|
platform sys161 file arch/sys161/main/start.S
|
344
kern/arch/sys161/dev/lamebus_machdep.c
Normal file
344
kern/arch/sys161/dev/lamebus_machdep.c
Normal file
@ -0,0 +1,344 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <kern/unistd.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#include <mips/specialreg.h>
|
||||||
|
#include <mips/trapframe.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
#include <spl.h>
|
||||||
|
#include <clock.h>
|
||||||
|
#include <thread.h>
|
||||||
|
#include <current.h>
|
||||||
|
#include <membar.h>
|
||||||
|
#include <synch.h>
|
||||||
|
#include <mainbus.h>
|
||||||
|
#include <sys161/bus.h>
|
||||||
|
#include <lamebus/lamebus.h>
|
||||||
|
#include <lamebus/ltrace.h>
|
||||||
|
#include "autoconf.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CPU frequency used by the on-chip timer.
|
||||||
|
*
|
||||||
|
* Note that we really ought to measure the CPU frequency against the
|
||||||
|
* real-time clock instead of compiling it in like this.
|
||||||
|
*/
|
||||||
|
#define CPU_FREQUENCY 25000000 /* 25 MHz */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access to the on-chip timer.
|
||||||
|
*
|
||||||
|
* The c0_count register increments on every cycle; when the value
|
||||||
|
* matches the c0_compare register, the timer interrupt line is
|
||||||
|
* asserted. Writing to c0_compare again clears the interrupt.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
void
|
||||||
|
mips_timer_set(uint32_t count)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* $11 == c0_compare; we can't use the symbolic name inside
|
||||||
|
* the asm string.
|
||||||
|
*/
|
||||||
|
__asm volatile(
|
||||||
|
".set push;" /* save assembler mode */
|
||||||
|
".set mips32;" /* allow MIPS32 registers */
|
||||||
|
"mtc0 %0, $11;" /* do it */
|
||||||
|
".set pop" /* restore assembler mode */
|
||||||
|
:: "r" (count));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LAMEbus data for the system. (We have only one LAMEbus per system.)
|
||||||
|
* This does not need to be locked, because it's constant once
|
||||||
|
* initialized, and initialized before we start other threads or CPUs.
|
||||||
|
*/
|
||||||
|
static struct lamebus_softc *lamebus;
|
||||||
|
|
||||||
|
void
|
||||||
|
mainbus_bootstrap(void)
|
||||||
|
{
|
||||||
|
/* Interrupts should be off (and have been off since startup) */
|
||||||
|
KASSERT(curthread->t_curspl > 0);
|
||||||
|
|
||||||
|
/* Initialize the system LAMEbus data */
|
||||||
|
lamebus = lamebus_init();
|
||||||
|
|
||||||
|
/* Probe CPUs (should these be done as device attachments instead?) */
|
||||||
|
lamebus_find_cpus(lamebus);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print the device name for the main bus.
|
||||||
|
*/
|
||||||
|
kprintf("lamebus0 (system main bus)\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now we can take interrupts without croaking, so turn them on.
|
||||||
|
* Some device probes might require being able to get interrupts.
|
||||||
|
*/
|
||||||
|
|
||||||
|
spl0();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now probe all the devices attached to the bus.
|
||||||
|
* (This amounts to all devices.)
|
||||||
|
*/
|
||||||
|
autoconf_lamebus(lamebus, 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configure the MIPS on-chip timer to interrupt HZ times a second.
|
||||||
|
*/
|
||||||
|
mips_timer_set(CPU_FREQUENCY / HZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start all secondary CPUs.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
mainbus_start_cpus(void)
|
||||||
|
{
|
||||||
|
lamebus_start_cpus(lamebus);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function to generate the memory address (in the uncached segment)
|
||||||
|
* for the specified offset into the specified slot's region of the
|
||||||
|
* LAMEbus.
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
lamebus_map_area(struct lamebus_softc *bus, int slot, uint32_t offset)
|
||||||
|
{
|
||||||
|
uint32_t address;
|
||||||
|
|
||||||
|
(void)bus; // not needed
|
||||||
|
|
||||||
|
KASSERT(slot >= 0 && slot < LB_NSLOTS);
|
||||||
|
|
||||||
|
address = LB_BASEADDR + slot*LB_SLOT_SIZE + offset;
|
||||||
|
return (void *)address;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read a 32-bit register from a LAMEbus device.
|
||||||
|
*/
|
||||||
|
uint32_t
|
||||||
|
lamebus_read_register(struct lamebus_softc *bus, int slot, uint32_t offset)
|
||||||
|
{
|
||||||
|
uint32_t *ptr;
|
||||||
|
|
||||||
|
ptr = lamebus_map_area(bus, slot, offset);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure the load happens after anything the device has
|
||||||
|
* been doing.
|
||||||
|
*/
|
||||||
|
membar_load_load();
|
||||||
|
|
||||||
|
return *ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write a 32-bit register of a LAMEbus device.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
lamebus_write_register(struct lamebus_softc *bus, int slot,
|
||||||
|
uint32_t offset, uint32_t val)
|
||||||
|
{
|
||||||
|
uint32_t *ptr;
|
||||||
|
|
||||||
|
ptr = lamebus_map_area(bus, slot, offset);
|
||||||
|
*ptr = val;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure the store happens before we do anything else to
|
||||||
|
* the device.
|
||||||
|
*/
|
||||||
|
membar_store_store();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Power off the system.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
mainbus_poweroff(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Note that lamebus_write_register() doesn't actually access
|
||||||
|
* the bus argument, so this will still work if we get here
|
||||||
|
* before the bus is initialized.
|
||||||
|
*/
|
||||||
|
lamebus_poweroff(lamebus);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reboot the system.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
mainbus_reboot(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The MIPS doesn't appear to have any on-chip reset.
|
||||||
|
* LAMEbus doesn't have a reset control, so we just
|
||||||
|
* power off instead of rebooting. This would not be
|
||||||
|
* so great in a real system, but it's fine for what
|
||||||
|
* we're doing.
|
||||||
|
*/
|
||||||
|
kprintf("Cannot reboot - powering off instead, sorry.\n");
|
||||||
|
mainbus_poweroff();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Halt the system.
|
||||||
|
* On some systems, this would return to the boot monitor. But we don't
|
||||||
|
* have one.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
mainbus_halt(void)
|
||||||
|
{
|
||||||
|
cpu_halt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called to reset the system from panic().
|
||||||
|
*
|
||||||
|
* By the time we get here, the system may well be sufficiently hosed
|
||||||
|
* as to panic recursively if we do much of anything. So just power off.
|
||||||
|
* (We'd reboot, but System/161 doesn't do that.)
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
mainbus_panic(void)
|
||||||
|
{
|
||||||
|
mainbus_poweroff();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function to get the size of installed physical RAM from the LAMEbus
|
||||||
|
* controller.
|
||||||
|
*/
|
||||||
|
uint32_t
|
||||||
|
mainbus_ramsize(void)
|
||||||
|
{
|
||||||
|
uint32_t ramsize;
|
||||||
|
|
||||||
|
ramsize = lamebus_ramsize();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the same as the last physical address, as long as
|
||||||
|
* we have less than 508 megabytes of memory. The LAMEbus I/O
|
||||||
|
* area occupies the space between 508 megabytes and 512
|
||||||
|
* megabytes, so if we had more RAM than this it would have to
|
||||||
|
* be discontiguous. This is not a case we are going to worry
|
||||||
|
* about.
|
||||||
|
*/
|
||||||
|
if (ramsize > 508*1024*1024) {
|
||||||
|
ramsize = 508*1024*1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ramsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send IPI.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
mainbus_send_ipi(struct cpu *target)
|
||||||
|
{
|
||||||
|
lamebus_assert_ipi(lamebus, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Trigger the debugger.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
mainbus_debugger(void)
|
||||||
|
{
|
||||||
|
ltrace_stop(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interrupt dispatcher.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Wiring of LAMEbus interrupts to bits in the cause register */
|
||||||
|
#define LAMEBUS_IRQ_BIT 0x00000400 /* all system bus slots */
|
||||||
|
#define LAMEBUS_IPI_BIT 0x00000800 /* inter-processor interrupt */
|
||||||
|
#define MIPS_TIMER_BIT 0x00008000 /* on-chip timer */
|
||||||
|
|
||||||
|
void
|
||||||
|
mainbus_interrupt(struct trapframe *tf)
|
||||||
|
{
|
||||||
|
uint32_t cause;
|
||||||
|
bool seen = false;
|
||||||
|
|
||||||
|
/* interrupts should be off */
|
||||||
|
KASSERT(curthread->t_curspl > 0);
|
||||||
|
|
||||||
|
cause = tf->tf_cause;
|
||||||
|
if (cause & LAMEBUS_IRQ_BIT) {
|
||||||
|
lamebus_interrupt(lamebus);
|
||||||
|
seen = true;
|
||||||
|
}
|
||||||
|
if (cause & LAMEBUS_IPI_BIT) {
|
||||||
|
interprocessor_interrupt();
|
||||||
|
lamebus_clear_ipi(lamebus, curcpu);
|
||||||
|
seen = true;
|
||||||
|
}
|
||||||
|
if (cause & MIPS_TIMER_BIT) {
|
||||||
|
/* Reset the timer (this clears the interrupt) */
|
||||||
|
mips_timer_set(CPU_FREQUENCY / HZ);
|
||||||
|
/* and call hardclock */
|
||||||
|
hardclock();
|
||||||
|
seen = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!seen) {
|
||||||
|
if ((cause & CCA_IRQS) == 0) {
|
||||||
|
/*
|
||||||
|
* Don't panic here; this can happen if an
|
||||||
|
* interrupt line asserts (very) briefly and
|
||||||
|
* turns off again before we get as far as
|
||||||
|
* reading the cause register. This was
|
||||||
|
* actually seen... once.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*
|
||||||
|
* But if we get an interrupt on an interrupt
|
||||||
|
* line that's not supposed to be wired up,
|
||||||
|
* complain.
|
||||||
|
*/
|
||||||
|
panic("Unknown interrupt; cause register is %08x\n",
|
||||||
|
cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
60
kern/arch/sys161/include/bus.h
Normal file
60
kern/arch/sys161/include/bus.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SYS161_BUS_H_
|
||||||
|
#define _SYS161_BUS_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generic bus interface file.
|
||||||
|
*
|
||||||
|
* The only bus on System/161 is LAMEbus.
|
||||||
|
* This would need to be a bit more complicated if that weren't the case.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <machine/vm.h> /* for MIPS_KSEG1 */
|
||||||
|
#include <lamebus/lamebus.h> /* for LAMEbus definitions */
|
||||||
|
|
||||||
|
#define bus_write_register(bus, slot, offset, val) \
|
||||||
|
lamebus_write_register(bus, slot, offset, val)
|
||||||
|
|
||||||
|
#define bus_read_register(bus, slot, offset) \
|
||||||
|
lamebus_read_register(bus, slot, offset)
|
||||||
|
|
||||||
|
#define bus_map_area(bus, slot, offset) \
|
||||||
|
lamebus_map_area(bus, slot, offset)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Machine-dependent LAMEbus definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Base address of the LAMEbus mapping area */
|
||||||
|
#define LB_BASEADDR (MIPS_KSEG1 + 0x1fe00000)
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _SYS161_BUS_H_ */
|
44
kern/arch/sys161/include/maxcpus.h
Normal file
44
kern/arch/sys161/include/maxcpus.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _SYS161_MAXCPUS_H_
|
||||||
|
#define _SYS161_MAXCPUS_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For various reasons (see mips/cpu.c) it's desirable to have a
|
||||||
|
* fixed-size per-cpu array in the data segment. This is
|
||||||
|
* platform-dependent rather than processor-dependent because there's
|
||||||
|
* nothing about the processor that determines how many CPUs can
|
||||||
|
* exist; however, any real platform has *some* limit. For System/161,
|
||||||
|
* the limit is 32.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MAXCPUS 32
|
||||||
|
|
||||||
|
#endif /* _SYS161_MAXCPUS_H_ */
|
335
kern/arch/sys161/main/start.S
Normal file
335
kern/arch/sys161/main/start.S
Normal file
@ -0,0 +1,335 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kern/mips/regdefs.h>
|
||||||
|
#include <mips/specialreg.h>
|
||||||
|
|
||||||
|
.set noreorder
|
||||||
|
|
||||||
|
.text
|
||||||
|
.globl __start
|
||||||
|
.type __start,@function
|
||||||
|
.ent __start
|
||||||
|
__start:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stack frame. We save the return address register, even though
|
||||||
|
* it contains nothing useful. This is for gdb's benefit when it
|
||||||
|
* comes disassembling. We also need 16 bytes for making a call,
|
||||||
|
* and we have to align to an 8-byte (64-bit) boundary, so the
|
||||||
|
* total frame size is 24.
|
||||||
|
*
|
||||||
|
* Note that the frame here must match the frame we set up below
|
||||||
|
* when we switch off the bootup stack. Otherwise, gdb gets very
|
||||||
|
* confused.
|
||||||
|
*/
|
||||||
|
.frame sp, 24, $0 /* 24-byte sp-relative frame; return addr on stack */
|
||||||
|
.mask 0x80000000, -4 /* register 31 (ra) saved at (sp+24)-4 */
|
||||||
|
addiu sp, sp, -24
|
||||||
|
sw ra, 20(sp)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The System/161 loader sets up a boot stack for the first
|
||||||
|
* processor at the top of physical memory, and passes us a single
|
||||||
|
* string argument. The string lives on the very top of the stack.
|
||||||
|
* We get its address in a0.
|
||||||
|
*
|
||||||
|
* The kernel loads at virtual address 0x80000200, which is
|
||||||
|
* physical address 0x00000200. The space immediately below this
|
||||||
|
* is reserved for the exception vector code.
|
||||||
|
*
|
||||||
|
* The symbol _end is generated by the linker. It's the address of
|
||||||
|
* the end of the kernel. It's not a variable; the *value* of the
|
||||||
|
* _end symbol itself is this address. In C you'd use "&_end".
|
||||||
|
*
|
||||||
|
* We set up the memory map like this:
|
||||||
|
*
|
||||||
|
* top of memory
|
||||||
|
* free memory
|
||||||
|
* P + 0x1000
|
||||||
|
* first thread's stack (1 page)
|
||||||
|
* P
|
||||||
|
* wasted space (< 1 page)
|
||||||
|
* copy of the boot string
|
||||||
|
* _end
|
||||||
|
* kernel
|
||||||
|
* 0x80000200
|
||||||
|
* exception handlers
|
||||||
|
* 0x80000000
|
||||||
|
*
|
||||||
|
* where P is the next whole page after copying the argument string.
|
||||||
|
*/
|
||||||
|
|
||||||
|
la s0, _end /* stash _end in a saved register */
|
||||||
|
|
||||||
|
move a1, a0 /* move bootstring to the second argument */
|
||||||
|
move a0, s0 /* make _end the first argument */
|
||||||
|
jal strcpy /* call strcpy(_end, bootstring) */
|
||||||
|
nop /* delay slot */
|
||||||
|
|
||||||
|
move a0, s0 /* make _end the first argument again */
|
||||||
|
jal strlen /* call strlen(_end) */
|
||||||
|
nop
|
||||||
|
|
||||||
|
add t0, s0, v0 /* add in the length of the string */
|
||||||
|
addi t0, t0, 1 /* and the null terminator */
|
||||||
|
|
||||||
|
|
||||||
|
addi t0, t0, 4095 /* round up to next page boundary */
|
||||||
|
li t1, 0xfffff000
|
||||||
|
and t0, t0, t1
|
||||||
|
|
||||||
|
addi t0, t0, 4096 /* add one page to hold the stack */
|
||||||
|
|
||||||
|
move sp, t0 /* start the kernel stack for the first thread here */
|
||||||
|
|
||||||
|
sw t0, firstfree /* remember the first free page for later */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* At this point, s0 contains the boot argument string, and no other
|
||||||
|
* registers contain anything interesting (except the stack pointer).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now set up a stack frame on the real kernel stack: a dummy saved
|
||||||
|
* return address and four argument slots for making function calls,
|
||||||
|
* plus a wasted slot for alignment.
|
||||||
|
*
|
||||||
|
* (This needs to match the stack frame set up at the top of the
|
||||||
|
* function, or the debugger gets confused.)
|
||||||
|
*/
|
||||||
|
addiu sp, sp, -24
|
||||||
|
sw $0, 20(sp)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now, copy the exception handler code onto the first page of memory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
li a0, EXADDR_UTLB
|
||||||
|
la a1, mips_utlb_handler
|
||||||
|
la a2, mips_utlb_end
|
||||||
|
sub a2, a2, a1
|
||||||
|
jal memmove
|
||||||
|
nop
|
||||||
|
|
||||||
|
li a0, EXADDR_GENERAL
|
||||||
|
la a1, mips_general_handler
|
||||||
|
la a2, mips_general_end
|
||||||
|
sub a2, a2, a1
|
||||||
|
jal memmove
|
||||||
|
nop
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flush the instruction cache to make sure the above changes show
|
||||||
|
* through to instruction fetch.
|
||||||
|
*/
|
||||||
|
jal mips_flushicache
|
||||||
|
nop
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the TLB.
|
||||||
|
*/
|
||||||
|
jal tlb_reset
|
||||||
|
nop
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load NULL into the register we use for curthread.
|
||||||
|
*/
|
||||||
|
li s7, 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up the status register.
|
||||||
|
*
|
||||||
|
* The MIPS has six hardware interrupt lines and two software interrupts.
|
||||||
|
* These are individually maskable in the status register. However, we
|
||||||
|
* don't use this feature (for simplicity) - we only use the master
|
||||||
|
* interrupt enable/disable flag in bit 0. So enable all of those bits
|
||||||
|
* now and forget about them.
|
||||||
|
*
|
||||||
|
* The BEV bit in the status register, if set, causes the processor to
|
||||||
|
* jump to a different set of hardwired exception handling addresses.
|
||||||
|
* This is so that the kernel's exception handling code can be loaded
|
||||||
|
* into RAM and that the boot ROM's exception handling code can be ROM.
|
||||||
|
* This flag is normally set at boot time, and we need to be sure to
|
||||||
|
* clear it.
|
||||||
|
*
|
||||||
|
* The KUo/IEo/KUp/IEp/KUc/IEc bits should all start at zero.
|
||||||
|
*
|
||||||
|
* We also want all the other random control bits (mostly for cache
|
||||||
|
* stuff) set to zero.
|
||||||
|
*
|
||||||
|
* Thus, the actual value we write is CST_IRQMASK.
|
||||||
|
*/
|
||||||
|
|
||||||
|
li t0, CST_IRQMASK /* get value */
|
||||||
|
mtc0 t0, c0_status /* set status register */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load the CPU number into the PTBASE field of the CONTEXT
|
||||||
|
* register. This is necessary to read from cpustacks[] and
|
||||||
|
* cputhreads[] on trap entry from user mode. See further
|
||||||
|
* discussions elsewhere.
|
||||||
|
*
|
||||||
|
* Because the boot CPU is CPU 0, we can just send 0.
|
||||||
|
*/
|
||||||
|
mtc0 $0, c0_context
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load the GP register. This is a MIPS ABI feature; the GP
|
||||||
|
* register points to an address in the middle of the data segment,
|
||||||
|
* so data can be accessed relative to GP using one instruction
|
||||||
|
* instead of the two it takes to set up a full 32-bit address.
|
||||||
|
*/
|
||||||
|
la gp, _gp
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We're all set up!
|
||||||
|
* Fetch the copy of the bootstring as the argument, and call main.
|
||||||
|
*/
|
||||||
|
jal kmain
|
||||||
|
move a0, s0 /* in delay slot */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* kmain shouldn't return. panic.
|
||||||
|
* Loop back just in case panic returns too.
|
||||||
|
*/
|
||||||
|
1:
|
||||||
|
la a0, panicstr
|
||||||
|
jal panic
|
||||||
|
nop /* delay slot */
|
||||||
|
j 1b
|
||||||
|
nop /* delay slot */
|
||||||
|
.end __start
|
||||||
|
|
||||||
|
.rdata
|
||||||
|
panicstr:
|
||||||
|
.asciz "kmain returned\n"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CPUs started after the boot CPU come here.
|
||||||
|
*/
|
||||||
|
.text
|
||||||
|
.globl cpu_start_secondary
|
||||||
|
.type cpu_start_secondary,@function
|
||||||
|
.ent cpu_start_secondary
|
||||||
|
cpu_start_secondary:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When we get here our stack points to the CRAM area of the bus
|
||||||
|
* controller per-CPU space. This means we can, with a bit of
|
||||||
|
* caution, call C functions, but nothing very deeply nesting.
|
||||||
|
* However, we don't need to.
|
||||||
|
*
|
||||||
|
* The a0 register contains the value that was put in the second
|
||||||
|
* word of the CRAM area, which is the (software) cpu number for
|
||||||
|
* indexing cpustacks[]. None of the other registers contain
|
||||||
|
* anything useful.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stack frame. We save the return address register, even though
|
||||||
|
* it contains nothing useful. This is for gdb's benefit when it
|
||||||
|
* comes disassembling. We also need 16 bytes for making a call,
|
||||||
|
* and 4 bytes for alignment, so the total frame size is 24.
|
||||||
|
*
|
||||||
|
* Note that the frame here must match the frame we set up below
|
||||||
|
* when we switch stacks. Otherwise, gdb gets very confused.
|
||||||
|
*/
|
||||||
|
.frame sp, 24, $0 /* 24-byte sp-relative frame; return addr on stack */
|
||||||
|
.mask 0x80000000, -4 /* register 31 (ra) saved at (sp+24)-4 */
|
||||||
|
addiu sp, sp, -24
|
||||||
|
sw ra, 20(sp)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fetch the stack out of cpustacks[].
|
||||||
|
*/
|
||||||
|
lui t0, %hi(cpustacks) /* load upper half of cpustacks base addr */
|
||||||
|
sll v0, a0, 2 /* get byte index for array (multiply by 4) */
|
||||||
|
addu t0, t0, v0 /* add it in */
|
||||||
|
lw sp, %lo(cpustacks)(t0) /* get the stack pointer */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now fetch curthread out of cputhreads[].
|
||||||
|
*/
|
||||||
|
lui t0, %hi(cputhreads) /* load upper half of cpustacks base addr */
|
||||||
|
sll v0, a0, 2 /* get byte index for array (multiply by 4) */
|
||||||
|
addu t0, t0, v0 /* add it in */
|
||||||
|
lw s7, %lo(cputhreads)(t0) /* load curthread register */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the TLB.
|
||||||
|
*/
|
||||||
|
jal tlb_reset
|
||||||
|
nop
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up the status register, as described above.
|
||||||
|
*/
|
||||||
|
li t0, CST_IRQMASK /* get value */
|
||||||
|
mtc0 t0, c0_status /* set status register */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load the CPU number into the PTBASE field of the CONTEXT
|
||||||
|
* register, as described above.
|
||||||
|
*/
|
||||||
|
sll v0, a0, CTX_PTBASESHIFT
|
||||||
|
mtc0 v0, c0_context
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the on-chip timer interrupt.
|
||||||
|
*
|
||||||
|
* This should be set to CPU_FREQUENCY/HZ, but we don't have either
|
||||||
|
* of those values here, so we'll arbitrarily set it to 100,000. It
|
||||||
|
* will get reset to the right thing after it first fires.
|
||||||
|
*/
|
||||||
|
li v0, 100000
|
||||||
|
mtc0 v0, c0_compare
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load the GP register.
|
||||||
|
*/
|
||||||
|
la gp, _gp
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up a stack frame. Store zero into the return address slot so
|
||||||
|
* we show as the top of the stack.
|
||||||
|
*/
|
||||||
|
addiu sp, sp, -24
|
||||||
|
sw z0, 20(sp)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Off to MI code. Pass the cpu number as the argument; it's already
|
||||||
|
* in the a0 register.
|
||||||
|
*/
|
||||||
|
j cpu_hatch
|
||||||
|
nop /* delay slot for jump */
|
||||||
|
.end cpu_start_secondary
|
34
kern/conf/DUMBVM
Normal file
34
kern/conf/DUMBVM
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# Kernel config file using dumbvm.
|
||||||
|
# This should be used until you have your own VM system.
|
||||||
|
|
||||||
|
include conf/conf.kern # get definitions of available options
|
||||||
|
|
||||||
|
debug # Compile with debug info and -Og.
|
||||||
|
#debugonly # Compile with debug info only (no -Og).
|
||||||
|
#options hangman # Deadlock detection. (off by default)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Device drivers for hardware.
|
||||||
|
#
|
||||||
|
device lamebus0 # System/161 main bus
|
||||||
|
device emu* at lamebus* # Emulator passthrough filesystem
|
||||||
|
device ltrace* at lamebus* # trace161 trace control device
|
||||||
|
device ltimer* at lamebus* # Timer device
|
||||||
|
device lrandom* at lamebus* # Random device
|
||||||
|
device lhd* at lamebus* # Disk device
|
||||||
|
device lser* at lamebus* # Serial port
|
||||||
|
#device lscreen* at lamebus* # Text screen (not supported yet)
|
||||||
|
#device lnet* at lamebus* # Network interface (not supported yet)
|
||||||
|
device beep0 at ltimer* # Abstract beep handler device
|
||||||
|
device con0 at lser* # Abstract console on serial port
|
||||||
|
#device con0 at lscreen* # Abstract console on screen (not supported)
|
||||||
|
device rtclock0 at ltimer* # Abstract realtime clock
|
||||||
|
device random0 at lrandom* # Abstract randomness device
|
||||||
|
|
||||||
|
#options net # Network stack (not supported)
|
||||||
|
options semfs # Semaphores for userland
|
||||||
|
|
||||||
|
options sfs # Always use the file system
|
||||||
|
#options netfs # You might write this as a project.
|
||||||
|
|
||||||
|
options dumbvm # Chewing gum and baling wire.
|
37
kern/conf/DUMBVM-OPT
Normal file
37
kern/conf/DUMBVM-OPT
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# Kernel config file using dumbvm.
|
||||||
|
# This should be used until you have your own VM system.
|
||||||
|
#
|
||||||
|
# This config builds with optimization for performance testing.
|
||||||
|
#
|
||||||
|
|
||||||
|
include conf/conf.kern # get definitions of available options
|
||||||
|
|
||||||
|
#debug # Optimizing compile (no debug).
|
||||||
|
#debugonly
|
||||||
|
options noasserts # Disable assertions.
|
||||||
|
|
||||||
|
#
|
||||||
|
# Device drivers for hardware.
|
||||||
|
#
|
||||||
|
device lamebus0 # System/161 main bus
|
||||||
|
device emu* at lamebus* # Emulator passthrough filesystem
|
||||||
|
device ltrace* at lamebus* # trace161 trace control device
|
||||||
|
device ltimer* at lamebus* # Timer device
|
||||||
|
device lrandom* at lamebus* # Random device
|
||||||
|
device lhd* at lamebus* # Disk device
|
||||||
|
device lser* at lamebus* # Serial port
|
||||||
|
#device lscreen* at lamebus* # Text screen (not supported yet)
|
||||||
|
#device lnet* at lamebus* # Network interface (not supported yet)
|
||||||
|
device beep0 at ltimer* # Abstract beep handler device
|
||||||
|
device con0 at lser* # Abstract console on serial port
|
||||||
|
#device con0 at lscreen* # Abstract console on screen (not supported)
|
||||||
|
device rtclock0 at ltimer* # Abstract realtime clock
|
||||||
|
device random0 at lrandom* # Abstract randomness device
|
||||||
|
|
||||||
|
#options net # Network stack (not supported)
|
||||||
|
options semfs # Semaphores for userland
|
||||||
|
|
||||||
|
options sfs # Always use the file system
|
||||||
|
#options netfs # You might write this as a project.
|
||||||
|
|
||||||
|
options dumbvm # Chewing gum and baling wire.
|
35
kern/conf/GENERIC
Normal file
35
kern/conf/GENERIC
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# Kernel config file for an ordinary, generic kernel.
|
||||||
|
# This config file should be used once you start working on
|
||||||
|
# your own VM system.
|
||||||
|
|
||||||
|
include conf/conf.kern # get definitions of available options
|
||||||
|
|
||||||
|
debug # Compile with debug info.
|
||||||
|
#debugonly # Compile with debug info only (no -Og).
|
||||||
|
#options hangman # Deadlock detection. (off by default)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Device drivers for hardware.
|
||||||
|
#
|
||||||
|
device lamebus0 # System/161 main bus
|
||||||
|
device emu* at lamebus* # Emulator passthrough filesystem
|
||||||
|
device ltrace* at lamebus* # trace161 trace control device
|
||||||
|
device ltimer* at lamebus* # Timer device
|
||||||
|
device lrandom* at lamebus* # Random device
|
||||||
|
device lhd* at lamebus* # Disk device
|
||||||
|
device lser* at lamebus* # Serial port
|
||||||
|
#device lscreen* at lamebus* # Text screen (not supported yet)
|
||||||
|
#device lnet* at lamebus* # Network interface (not supported yet)
|
||||||
|
device beep0 at ltimer* # Abstract beep handler device
|
||||||
|
device con0 at lser* # Abstract console on serial port
|
||||||
|
#device con0 at lscreen* # Abstract console on screen (not supported)
|
||||||
|
device rtclock0 at ltimer* # Abstract realtime clock
|
||||||
|
device random0 at lrandom* # Abstract randomness device
|
||||||
|
|
||||||
|
#options net # Network stack (not supported)
|
||||||
|
options semfs # Semaphores for userland
|
||||||
|
|
||||||
|
options sfs # Always use the file system
|
||||||
|
#options netfs # You might write this as a project.
|
||||||
|
|
||||||
|
#options dumbvm # Use your own VM system now.
|
37
kern/conf/GENERIC-OPT
Normal file
37
kern/conf/GENERIC-OPT
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# Kernel config file for an ordinary, generic kernel.
|
||||||
|
# This config file should be used once you start working on
|
||||||
|
# your own VM system.
|
||||||
|
#
|
||||||
|
# This config builds with optimization for performance testing.
|
||||||
|
|
||||||
|
include conf/conf.kern # get definitions of available options
|
||||||
|
|
||||||
|
#debug # Optimizing compile (no debug).
|
||||||
|
#debugonly
|
||||||
|
options noasserts # Disable assertions.
|
||||||
|
|
||||||
|
#
|
||||||
|
# Device drivers for hardware.
|
||||||
|
#
|
||||||
|
device lamebus0 # System/161 main bus
|
||||||
|
device emu* at lamebus* # Emulator passthrough filesystem
|
||||||
|
device ltrace* at lamebus* # trace161 trace control device
|
||||||
|
device ltimer* at lamebus* # Timer device
|
||||||
|
device lrandom* at lamebus* # Random device
|
||||||
|
device lhd* at lamebus* # Disk device
|
||||||
|
device lser* at lamebus* # Serial port
|
||||||
|
#device lscreen* at lamebus* # Text screen (not supported yet)
|
||||||
|
#device lnet* at lamebus* # Network interface (not supported yet)
|
||||||
|
device beep0 at ltimer* # Abstract beep handler device
|
||||||
|
device con0 at lser* # Abstract console on serial port
|
||||||
|
#device con0 at lscreen* # Abstract console on screen (not supported)
|
||||||
|
device rtclock0 at ltimer* # Abstract realtime clock
|
||||||
|
device random0 at lrandom* # Abstract randomness device
|
||||||
|
|
||||||
|
#options net # Network stack (not supported)
|
||||||
|
options semfs # Semaphores for userland
|
||||||
|
|
||||||
|
options sfs # Always use the file system
|
||||||
|
#options netfs # You might write this as a project.
|
||||||
|
|
||||||
|
#options dumbvm # Use your own VM system now.
|
443
kern/conf/conf.kern
Normal file
443
kern/conf/conf.kern
Normal file
@ -0,0 +1,443 @@
|
|||||||
|
#
|
||||||
|
# Machine-independent kernel config definitions.
|
||||||
|
#
|
||||||
|
# The idea is that the files, options, and facilities in the system
|
||||||
|
# are declared by conf.kern and the various files it includes. Then a
|
||||||
|
# kernel config (such as ASST1, or GENERIC, or TEST, or whatever) is
|
||||||
|
# used to select options and facilities for a particular kernel build.
|
||||||
|
#
|
||||||
|
# To add new files to the system, you need to edit this file (or
|
||||||
|
# others like it) and rerun the config script.
|
||||||
|
#
|
||||||
|
# Note: when running the config script, be sure to be in the
|
||||||
|
# right directory (the same one this file is in) and run it as
|
||||||
|
# "./config", not just "config" - in the latter case you will
|
||||||
|
# probably get the host system's kernel config utility, which
|
||||||
|
# will likely make a mess and produce mysterious error messages.
|
||||||
|
#
|
||||||
|
# The documentation for the syntax of these files follows.
|
||||||
|
#
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
#
|
||||||
|
# Kernel config file syntax:
|
||||||
|
#
|
||||||
|
# The syntax for including the system definition is:
|
||||||
|
#
|
||||||
|
# include conf.kern
|
||||||
|
#
|
||||||
|
# This should come first. This is because the system must be
|
||||||
|
# defined before you can do much else useful.
|
||||||
|
#
|
||||||
|
# You can also include other files using the same syntax.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# The syntax for turning on a kernel compile option is:
|
||||||
|
#
|
||||||
|
# options optname
|
||||||
|
#
|
||||||
|
# A previous "defoption" must have been seen first. See below
|
||||||
|
# for more information.
|
||||||
|
#
|
||||||
|
# The act of compiling with debug info is (has to be) handled
|
||||||
|
# specially, and is just "debug" without the "options".
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# The syntax for turning on a device driver is:
|
||||||
|
#
|
||||||
|
# device foo%
|
||||||
|
# device foo% at bar%
|
||||||
|
#
|
||||||
|
# where the % is either a number or a star, which is treated as
|
||||||
|
# a wildcard. The first line enables a device foo that is not
|
||||||
|
# supposed to be "attached" to anything. The second line enables
|
||||||
|
# a device foo that is attached to a device bar. For more
|
||||||
|
# information about what this means, see below.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
############################################################
|
||||||
|
#
|
||||||
|
# Kernel definition file syntax:
|
||||||
|
#
|
||||||
|
# Note: All source file names are relative to the top directory of the
|
||||||
|
# kernel source, that is, src/kern.
|
||||||
|
#
|
||||||
|
# The syntax for adding a regular source file is:
|
||||||
|
#
|
||||||
|
# [machine M | platform P] file sourcefile.c
|
||||||
|
#
|
||||||
|
# Such a file is always included automatically in every kernel
|
||||||
|
# built for machine M, or platform P, or all kernels.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# The syntax for defining optional source files is:
|
||||||
|
#
|
||||||
|
# defoption optname
|
||||||
|
# [machine M | platform P] optfile optname sourcefile.c
|
||||||
|
# [machine M | platform P] optofffile optname sourcefile.c
|
||||||
|
#
|
||||||
|
# "defoption" declares the name of a kernel option. These are
|
||||||
|
# then turned on by including "options optname" in a
|
||||||
|
# kernel config.
|
||||||
|
#
|
||||||
|
# Source files added with optfile are compiled in if the option
|
||||||
|
# specified is enabled. Source files added with optofffile are
|
||||||
|
# compiled in if the option specified is not enabled.
|
||||||
|
#
|
||||||
|
# Additionally, a file "opt-optname.h" is created in the compile
|
||||||
|
# directory, which defines a C preprocessor symbol OPT_OPTNAME.
|
||||||
|
# This symbol is #defined to either 0 or 1 in the logical way.
|
||||||
|
# Thus, you can have small bits of code that are enabled or
|
||||||
|
# disabled by particular options by writing constructs like
|
||||||
|
#
|
||||||
|
# #include "opt-foo.h"
|
||||||
|
# #if OPT_FOO
|
||||||
|
# code();
|
||||||
|
# #else
|
||||||
|
# other_code();
|
||||||
|
# #endif
|
||||||
|
#
|
||||||
|
# *** Be sure to use #if and not #ifdef - you want the value
|
||||||
|
# of the symbol.
|
||||||
|
# *** Be sure to remember to include the header file for the
|
||||||
|
# option - if you don't, cpp will silently assume it is 0,
|
||||||
|
# which can be quite frustrating.
|
||||||
|
#
|
||||||
|
# The defoption must be seen before any optional file
|
||||||
|
# declarations that use it.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# The syntax for defining device drivers is:
|
||||||
|
#
|
||||||
|
# defdevice devname sourcefile.c
|
||||||
|
# defattach devname% otherdevname% sourcefile.c
|
||||||
|
# pseudoattach devname%
|
||||||
|
#
|
||||||
|
# Declare a device driver and its "attachment(s)". (The device
|
||||||
|
# driver can then be selectively included or not included in any
|
||||||
|
# particular kernel by using the "device" statement in the
|
||||||
|
# kernel config file.)
|
||||||
|
#
|
||||||
|
# The specified source files are only compiled if the device
|
||||||
|
# is enabled.
|
||||||
|
#
|
||||||
|
# The % is either a specific number N, meaning "only the Nth
|
||||||
|
# such device can be attached this way", or a star (*), meaning
|
||||||
|
# "any such device can be attached this way".
|
||||||
|
#
|
||||||
|
# In OS/161, device drivers are conceptually organized into
|
||||||
|
# trees. This mimics the organization of real hardware, where
|
||||||
|
# several expansion cards are plugged into one bus and there
|
||||||
|
# might be several devices on each expansion card and so forth.
|
||||||
|
#
|
||||||
|
# There can be any number of these trees. However, devices at
|
||||||
|
# the root of each tree must be able to probe and "find"
|
||||||
|
# themselves completely on their own. This generally means that
|
||||||
|
# they are either all software with no hardware, or they are the
|
||||||
|
# system main bus which is located in a machine-dependent way.
|
||||||
|
#
|
||||||
|
# Software-only devices are known as "pseudo-devices". These
|
||||||
|
# are "attached" with the pseudoattach directive; functions
|
||||||
|
# of the form
|
||||||
|
#
|
||||||
|
# pseudoattach_devname
|
||||||
|
#
|
||||||
|
# are called from autoconf.c to create instances as requested.
|
||||||
|
# These calls are made from the function pseudoconfig(), which
|
||||||
|
# should be called from dev/init.c after hardware device
|
||||||
|
# initialization completes. The pseudoattach functions should
|
||||||
|
# perform all setup and initialization necessary. (No
|
||||||
|
# config_devname function will be called.)
|
||||||
|
#
|
||||||
|
# Devices with attachments are automatically probed and
|
||||||
|
# configured from code in autoconf.c. This file is generated
|
||||||
|
# by the config script. It contains functions called
|
||||||
|
# "autoconf_devname", for each device. These functions call
|
||||||
|
# other functions, which are supplied by device drivers,
|
||||||
|
# which have the following hardwired names:
|
||||||
|
#
|
||||||
|
# attach_devname1_to_devname2
|
||||||
|
#
|
||||||
|
# A "devname2" device has been found and configured;
|
||||||
|
# this function attempts to probe the devname2 for
|
||||||
|
# a "devname1" device. Returns NULL if nothing was
|
||||||
|
# found.
|
||||||
|
#
|
||||||
|
# config_devname
|
||||||
|
#
|
||||||
|
# A "devname" device has been found. This function
|
||||||
|
# can then perform initialization that's shared
|
||||||
|
# among all the possible things it can be attached
|
||||||
|
# to.
|
||||||
|
#
|
||||||
|
# The idea is that there can be multiple attachments for
|
||||||
|
# the same device to different underlying devices. In the
|
||||||
|
# real world this can be used to great effect when you have,
|
||||||
|
# for instance, the same ethernet chipset used on both PCI
|
||||||
|
# and ISA cards - the chipset behaves the same way in both
|
||||||
|
# cases, but the probe and attach logic is very different.
|
||||||
|
#
|
||||||
|
# The attach_foo_to_bar functions are put in the files
|
||||||
|
# specified with defattach; the config_foo function (and
|
||||||
|
# generally the rest of the driver for the foo device) is
|
||||||
|
# put in the file specified with defdevice.
|
||||||
|
#
|
||||||
|
# One selects particular attachments when including the device
|
||||||
|
# in the kernel. A top-level device with no attachments should
|
||||||
|
# be included with this syntax:
|
||||||
|
#
|
||||||
|
# device bar
|
||||||
|
#
|
||||||
|
# A pseudo-device should be included with this syntax:
|
||||||
|
#
|
||||||
|
# device bar0
|
||||||
|
#
|
||||||
|
# To make use of device foo, which can be found attached to
|
||||||
|
# device bar, one of the following syntaxes is used:
|
||||||
|
#
|
||||||
|
# device foo* at bar*
|
||||||
|
# device foo* at bar0
|
||||||
|
# device foo0 at bar*
|
||||||
|
# device foo0 at bar0
|
||||||
|
#
|
||||||
|
# depending on to what extent you want to configure only a
|
||||||
|
# specific device number.
|
||||||
|
#
|
||||||
|
# It sometimes matters what order things are handled in; probes
|
||||||
|
# occur more or less in the order things appear in the config,
|
||||||
|
# as constrained by the tree structure of the available devices.
|
||||||
|
#
|
||||||
|
# Note that OS/161 does not make extensive use of this
|
||||||
|
# functionality, and the device driver architecture outlined
|
||||||
|
# here is overkill for such a limited environment as System/161.
|
||||||
|
# However, it's similar to the way real systems are organized.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# The syntax for including other config/definition files is:
|
||||||
|
#
|
||||||
|
# include filename
|
||||||
|
#
|
||||||
|
# The filename is relative to the top of the kernel source tree.
|
||||||
|
#
|
||||||
|
# Thus,
|
||||||
|
# include conf/conf.foo includes src/kern/conf/conf.foo
|
||||||
|
#
|
||||||
|
#
|
||||||
|
############################################################
|
||||||
|
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# #
|
||||||
|
# Generic machine-independent devices. #
|
||||||
|
# #
|
||||||
|
########################################
|
||||||
|
|
||||||
|
#
|
||||||
|
# These are abstract system services we expect the system hardware to
|
||||||
|
# provide: beeping, system console I/O, and time of day clock.
|
||||||
|
#
|
||||||
|
# These come before the archinclude so that the hardware device
|
||||||
|
# definitions, which are included from there, can define attachments
|
||||||
|
# for them.
|
||||||
|
#
|
||||||
|
|
||||||
|
defdevice beep dev/generic/beep.c
|
||||||
|
defdevice con dev/generic/console.c
|
||||||
|
defdevice rtclock dev/generic/rtclock.c
|
||||||
|
defdevice random dev/generic/random.c
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# #
|
||||||
|
# Machine-dependent stuff #
|
||||||
|
# #
|
||||||
|
########################################
|
||||||
|
|
||||||
|
#
|
||||||
|
# Get the definitions for each machine and platform supported. The
|
||||||
|
# ones used will be selected by make at compile time based on the
|
||||||
|
# contents of the top-level defs.mk file.
|
||||||
|
#
|
||||||
|
# This will declare a bunch of machine-dependent source files and also
|
||||||
|
# declare all the hardware devices (since what sorts of hardware we
|
||||||
|
# expect to find is machine-dependent.)
|
||||||
|
#
|
||||||
|
|
||||||
|
include arch/mips/conf/conf.arch
|
||||||
|
include arch/sys161/conf/conf.arch
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# #
|
||||||
|
# Support code #
|
||||||
|
# #
|
||||||
|
########################################
|
||||||
|
|
||||||
|
#
|
||||||
|
# Kernel utility code
|
||||||
|
#
|
||||||
|
|
||||||
|
file lib/array.c
|
||||||
|
file lib/bitmap.c
|
||||||
|
file lib/bswap.c
|
||||||
|
file lib/kgets.c
|
||||||
|
file lib/kprintf.c
|
||||||
|
file lib/misc.c
|
||||||
|
file lib/time.c
|
||||||
|
file lib/uio.c
|
||||||
|
|
||||||
|
defoption noasserts
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Standard C functions
|
||||||
|
#
|
||||||
|
# For most of these, we take the source files from our libc. Note
|
||||||
|
# that those files have to have been hacked a bit to support this.
|
||||||
|
#
|
||||||
|
|
||||||
|
file ../common/libc/printf/__printf.c
|
||||||
|
file ../common/libc/printf/snprintf.c
|
||||||
|
file ../common/libc/stdlib/atoi.c
|
||||||
|
file ../common/libc/string/bzero.c
|
||||||
|
file ../common/libc/string/memcpy.c
|
||||||
|
file ../common/libc/string/memmove.c
|
||||||
|
file ../common/libc/string/memset.c
|
||||||
|
file ../common/libc/string/strcat.c
|
||||||
|
file ../common/libc/string/strchr.c
|
||||||
|
file ../common/libc/string/strcmp.c
|
||||||
|
file ../common/libc/string/strcpy.c
|
||||||
|
file ../common/libc/string/strlen.c
|
||||||
|
file ../common/libc/string/strrchr.c
|
||||||
|
file ../common/libc/string/strtok_r.c
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# #
|
||||||
|
# Core kernel source files #
|
||||||
|
# #
|
||||||
|
########################################
|
||||||
|
|
||||||
|
#
|
||||||
|
# Thread system
|
||||||
|
#
|
||||||
|
|
||||||
|
file thread/clock.c
|
||||||
|
file thread/spl.c
|
||||||
|
file thread/spinlock.c
|
||||||
|
file thread/synch.c
|
||||||
|
file thread/thread.c
|
||||||
|
file thread/threadlist.c
|
||||||
|
|
||||||
|
defoption hangman
|
||||||
|
optfile hangman thread/hangman.c
|
||||||
|
|
||||||
|
#
|
||||||
|
# Process system
|
||||||
|
#
|
||||||
|
|
||||||
|
file proc/proc.c
|
||||||
|
|
||||||
|
#
|
||||||
|
# Virtual memory system
|
||||||
|
# (you will probably want to add stuff here while doing the VM assignment)
|
||||||
|
#
|
||||||
|
|
||||||
|
file vm/kmalloc.c
|
||||||
|
|
||||||
|
optofffile dumbvm vm/addrspace.c
|
||||||
|
|
||||||
|
#
|
||||||
|
# Network
|
||||||
|
# (nothing here yet)
|
||||||
|
#
|
||||||
|
|
||||||
|
defoption net
|
||||||
|
#optfile net net/net.c
|
||||||
|
|
||||||
|
#
|
||||||
|
# VFS layer
|
||||||
|
#
|
||||||
|
|
||||||
|
file vfs/device.c
|
||||||
|
file vfs/vfscwd.c
|
||||||
|
file vfs/vfsfail.c
|
||||||
|
file vfs/vfslist.c
|
||||||
|
file vfs/vfslookup.c
|
||||||
|
file vfs/vfspath.c
|
||||||
|
file vfs/vnode.c
|
||||||
|
|
||||||
|
#
|
||||||
|
# VFS devices
|
||||||
|
#
|
||||||
|
|
||||||
|
file vfs/devnull.c
|
||||||
|
|
||||||
|
#
|
||||||
|
# System call layer
|
||||||
|
# (You will probably want to add stuff here while doing the basic system
|
||||||
|
# calls assignment.)
|
||||||
|
#
|
||||||
|
|
||||||
|
file syscall/loadelf.c
|
||||||
|
file syscall/runprogram.c
|
||||||
|
file syscall/time_syscalls.c
|
||||||
|
|
||||||
|
#
|
||||||
|
# Startup and initialization
|
||||||
|
#
|
||||||
|
|
||||||
|
file main/main.c
|
||||||
|
file main/menu.c
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# #
|
||||||
|
# Filesystems #
|
||||||
|
# #
|
||||||
|
########################################
|
||||||
|
|
||||||
|
#
|
||||||
|
# semfs (fake filesystem providing userlevel semaphores)
|
||||||
|
#
|
||||||
|
defoption semfs
|
||||||
|
optfile semfs fs/semfs/semfs_fsops.c
|
||||||
|
optfile semfs fs/semfs/semfs_obj.c
|
||||||
|
optfile semfs fs/semfs/semfs_vnops.c
|
||||||
|
|
||||||
|
#
|
||||||
|
# sfs (the small/simple filesystem)
|
||||||
|
#
|
||||||
|
|
||||||
|
defoption sfs
|
||||||
|
optfile sfs fs/sfs/sfs_balloc.c
|
||||||
|
optfile sfs fs/sfs/sfs_bmap.c
|
||||||
|
optfile sfs fs/sfs/sfs_dir.c
|
||||||
|
optfile sfs fs/sfs/sfs_fsops.c
|
||||||
|
optfile sfs fs/sfs/sfs_inode.c
|
||||||
|
optfile sfs fs/sfs/sfs_io.c
|
||||||
|
optfile sfs fs/sfs/sfs_vnops.c
|
||||||
|
|
||||||
|
#
|
||||||
|
# netfs (the networked filesystem - you might write this as one assignment)
|
||||||
|
#
|
||||||
|
defoption netfs
|
||||||
|
#optfile netfs fs/netfs/netfs_fs.c # or whatever
|
||||||
|
|
||||||
|
#
|
||||||
|
# Note that "emufs" is completely contained in the "emu" device.
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# #
|
||||||
|
# Test code #
|
||||||
|
# #
|
||||||
|
########################################
|
||||||
|
|
||||||
|
file test/arraytest.c
|
||||||
|
file test/bitmaptest.c
|
||||||
|
file test/threadlisttest.c
|
||||||
|
file test/threadtest.c
|
||||||
|
file test/tt3.c
|
||||||
|
file test/synchtest.c
|
||||||
|
file test/semunit.c
|
||||||
|
file test/kmalloctest.c
|
||||||
|
file test/fstest.c
|
||||||
|
optfile net test/nettest.c
|
1068
kern/conf/config
Executable file
1068
kern/conf/config
Executable file
File diff suppressed because it is too large
Load Diff
67
kern/conf/newvers.sh
Executable file
67
kern/conf/newvers.sh
Executable file
@ -0,0 +1,67 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# newvers.sh - increment build number in current directory (a build directory)
|
||||||
|
# and emit vers.c.
|
||||||
|
# The build number is kept in the file "version".
|
||||||
|
#
|
||||||
|
# Usage: newvers.sh CONFIGNAME
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
# The President and Fellows of Harvard College.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions
|
||||||
|
# are met:
|
||||||
|
# 1. Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution.
|
||||||
|
# 3. Neither the name of the University nor the names of its contributors
|
||||||
|
# may be used to endorse or promote products derived from this software
|
||||||
|
# without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
# SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
|
||||||
|
if [ ! -f autoconf.c ]; then
|
||||||
|
#
|
||||||
|
# If there's no file autoconf.c, we are in the wrong place.
|
||||||
|
#
|
||||||
|
echo "$0: Not in a kernel build directory"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "x$1" = x ]; then
|
||||||
|
echo "Usage: $0 CONFIGNAME"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
CONFIG="$1"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Get and increment the version number
|
||||||
|
#
|
||||||
|
|
||||||
|
VERS=`cat version 2>/dev/null || echo 0`
|
||||||
|
VERS=`expr $VERS + 1`
|
||||||
|
echo "$VERS" > version
|
||||||
|
|
||||||
|
#
|
||||||
|
# Write vers.c
|
||||||
|
#
|
||||||
|
|
||||||
|
echo '/* This file is automatically generated. Edits will be lost.*/' > vers.c
|
||||||
|
echo "const int buildversion = $VERS;" >> vers.c
|
||||||
|
echo 'const char buildconfig[] = "'"$CONFIG"'";' >> vers.c
|
71
kern/dev/generic/beep.c
Normal file
71
kern/dev/generic/beep.c
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <kern/errno.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#include <generic/beep.h>
|
||||||
|
#include "autoconf.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Machine-independent generic beep "device".
|
||||||
|
*
|
||||||
|
* Basically, all we do is remember something that can be used for
|
||||||
|
* beeping, and provide the beep() function to the rest of the kernel.
|
||||||
|
*
|
||||||
|
* The kernel config mechanism can be used to explicitly choose which
|
||||||
|
* of the available beeping devices to use, if more than one is
|
||||||
|
* available.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static struct beep_softc *the_beep = NULL;
|
||||||
|
|
||||||
|
int
|
||||||
|
config_beep(struct beep_softc *bs, int unit)
|
||||||
|
{
|
||||||
|
/* We use only the first beep device. */
|
||||||
|
if (unit!=0) {
|
||||||
|
return ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
KASSERT(the_beep==NULL);
|
||||||
|
the_beep = bs;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
beep(void)
|
||||||
|
{
|
||||||
|
if (the_beep!=NULL) {
|
||||||
|
the_beep->bs_beep(the_beep->bs_devdata);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
kprintf("beep: Warning: no beep device\n");
|
||||||
|
}
|
||||||
|
}
|
43
kern/dev/generic/beep.h
Normal file
43
kern/dev/generic/beep.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _GENERIC_BEEP_H_
|
||||||
|
#define _GENERIC_BEEP_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The device info for the generic MI beep device - a function
|
||||||
|
* to call and a context pointer for it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct beep_softc {
|
||||||
|
void *bs_devdata;
|
||||||
|
void (*bs_beep)(void *devdata);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _GENERIC_BEEP_H_ */
|
397
kern/dev/generic/console.c
Normal file
397
kern/dev/generic/console.c
Normal file
@ -0,0 +1,397 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Machine (and hardware) independent console driver.
|
||||||
|
*
|
||||||
|
* We expose a simple interface to the rest of the kernel: "putch" to
|
||||||
|
* print a character, "getch" to read one.
|
||||||
|
*
|
||||||
|
* As long as the device we're connected to does, we allow printing in
|
||||||
|
* an interrupt handler or with interrupts off (by polling),
|
||||||
|
* transparently to the caller. Note that getch by polling is not
|
||||||
|
* supported, although such support could be added without undue
|
||||||
|
* difficulty.
|
||||||
|
*
|
||||||
|
* Note that nothing happens until we have a device to write to. A
|
||||||
|
* buffer of size DELAYBUFSIZE is used to hold output that is
|
||||||
|
* generated before this point. This means that (1) using kprintf for
|
||||||
|
* debugging problems that occur early in initialization is awkward,
|
||||||
|
* and (2) if the system crashes before we find a console, no output
|
||||||
|
* at all may appear.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <kern/errno.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#include <uio.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
#include <thread.h>
|
||||||
|
#include <current.h>
|
||||||
|
#include <synch.h>
|
||||||
|
#include <generic/console.h>
|
||||||
|
#include <vfs.h>
|
||||||
|
#include <device.h>
|
||||||
|
#include "autoconf.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The console device.
|
||||||
|
*/
|
||||||
|
static struct con_softc *the_console = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lock so user I/Os are atomic.
|
||||||
|
* We use two locks so readers waiting for input don't lock out writers.
|
||||||
|
*/
|
||||||
|
static struct lock *con_userlock_read = NULL;
|
||||||
|
static struct lock *con_userlock_write = NULL;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is for accumulating characters printed before the
|
||||||
|
* console is set up. Upon console setup they are dumped
|
||||||
|
* to the actual console; thenceforth this space is unused.
|
||||||
|
*/
|
||||||
|
#define DELAYBUFSIZE 1024
|
||||||
|
static char delayed_outbuf[DELAYBUFSIZE];
|
||||||
|
static size_t delayed_outbuf_pos=0;
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
putch_delayed(int ch)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* No synchronization needed: called only during system startup
|
||||||
|
* by main thread.
|
||||||
|
*/
|
||||||
|
|
||||||
|
KASSERT(delayed_outbuf_pos < sizeof(delayed_outbuf));
|
||||||
|
delayed_outbuf[delayed_outbuf_pos++] = ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
flush_delay_buf(void)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i=0; i<delayed_outbuf_pos; i++) {
|
||||||
|
putch(delayed_outbuf[i]);
|
||||||
|
}
|
||||||
|
delayed_outbuf_pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print a character, using polling instead of interrupts to wait for
|
||||||
|
* I/O completion.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
void
|
||||||
|
putch_polled(struct con_softc *cs, int ch)
|
||||||
|
{
|
||||||
|
cs->cs_sendpolled(cs->cs_devdata, ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print a character, using interrupts to wait for I/O completion.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
void
|
||||||
|
putch_intr(struct con_softc *cs, int ch)
|
||||||
|
{
|
||||||
|
P(cs->cs_wsem);
|
||||||
|
cs->cs_send(cs->cs_devdata, ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read a character, using interrupts to wait for I/O completion.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int
|
||||||
|
getch_intr(struct con_softc *cs)
|
||||||
|
{
|
||||||
|
unsigned char ret;
|
||||||
|
|
||||||
|
P(cs->cs_rsem);
|
||||||
|
ret = cs->cs_gotchars[cs->cs_gotchars_tail];
|
||||||
|
cs->cs_gotchars_tail =
|
||||||
|
(cs->cs_gotchars_tail + 1) % CONSOLE_INPUT_BUFFER_SIZE;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called from underlying device when a read-ready interrupt occurs.
|
||||||
|
*
|
||||||
|
* Note: if gotchars_head == gotchars_tail, the buffer is empty. Thus
|
||||||
|
* if gotchars_head+1 == gotchars_tail, the buffer is full. A slightly
|
||||||
|
* tidier way to implement this check (that avoids wasting a slot,
|
||||||
|
* too) would be with a second semaphore used with a nonblocking P,
|
||||||
|
* but we don't have that in OS/161.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
con_input(void *vcs, int ch)
|
||||||
|
{
|
||||||
|
struct con_softc *cs = vcs;
|
||||||
|
unsigned nexthead;
|
||||||
|
|
||||||
|
nexthead = (cs->cs_gotchars_head + 1) % CONSOLE_INPUT_BUFFER_SIZE;
|
||||||
|
if (nexthead == cs->cs_gotchars_tail) {
|
||||||
|
/* overflow; drop character */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cs->cs_gotchars[cs->cs_gotchars_head] = ch;
|
||||||
|
cs->cs_gotchars_head = nexthead;
|
||||||
|
|
||||||
|
V(cs->cs_rsem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called from underlying device when a write-done interrupt occurs.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
con_start(void *vcs)
|
||||||
|
{
|
||||||
|
struct con_softc *cs = vcs;
|
||||||
|
|
||||||
|
V(cs->cs_wsem);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exported interface.
|
||||||
|
*
|
||||||
|
* Warning: putch must work even in an interrupt handler or with
|
||||||
|
* interrupts disabled, and before the console is probed. getch need
|
||||||
|
* not, and does not.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
putch(int ch)
|
||||||
|
{
|
||||||
|
struct con_softc *cs = the_console;
|
||||||
|
|
||||||
|
if (cs==NULL) {
|
||||||
|
putch_delayed(ch);
|
||||||
|
}
|
||||||
|
else if (curthread->t_in_interrupt ||
|
||||||
|
curthread->t_curspl > 0 ||
|
||||||
|
curcpu->c_spinlocks > 0) {
|
||||||
|
putch_polled(cs, ch);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
putch_intr(cs, ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
getch(void)
|
||||||
|
{
|
||||||
|
struct con_softc *cs = the_console;
|
||||||
|
KASSERT(cs != NULL);
|
||||||
|
KASSERT(!curthread->t_in_interrupt && curthread->t_iplhigh_count == 0);
|
||||||
|
|
||||||
|
return getch_intr(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VFS interface functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
static
|
||||||
|
int
|
||||||
|
con_eachopen(struct device *dev, int openflags)
|
||||||
|
{
|
||||||
|
(void)dev;
|
||||||
|
(void)openflags;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int
|
||||||
|
con_io(struct device *dev, struct uio *uio)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
char ch;
|
||||||
|
struct lock *lk;
|
||||||
|
|
||||||
|
(void)dev; // unused
|
||||||
|
|
||||||
|
if (uio->uio_rw==UIO_READ) {
|
||||||
|
lk = con_userlock_read;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lk = con_userlock_write;
|
||||||
|
}
|
||||||
|
|
||||||
|
KASSERT(lk != NULL);
|
||||||
|
lock_acquire(lk);
|
||||||
|
|
||||||
|
while (uio->uio_resid > 0) {
|
||||||
|
if (uio->uio_rw==UIO_READ) {
|
||||||
|
ch = getch();
|
||||||
|
if (ch=='\r') {
|
||||||
|
ch = '\n';
|
||||||
|
}
|
||||||
|
result = uiomove(&ch, 1, uio);
|
||||||
|
if (result) {
|
||||||
|
lock_release(lk);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (ch=='\n') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = uiomove(&ch, 1, uio);
|
||||||
|
if (result) {
|
||||||
|
lock_release(lk);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (ch=='\n') {
|
||||||
|
putch('\r');
|
||||||
|
}
|
||||||
|
putch(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lock_release(lk);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int
|
||||||
|
con_ioctl(struct device *dev, int op, userptr_t data)
|
||||||
|
{
|
||||||
|
/* No ioctls. */
|
||||||
|
(void)dev;
|
||||||
|
(void)op;
|
||||||
|
(void)data;
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct device_ops console_devops = {
|
||||||
|
.devop_eachopen = con_eachopen,
|
||||||
|
.devop_io = con_io,
|
||||||
|
.devop_ioctl = con_ioctl,
|
||||||
|
};
|
||||||
|
|
||||||
|
static
|
||||||
|
int
|
||||||
|
attach_console_to_vfs(struct con_softc *cs)
|
||||||
|
{
|
||||||
|
struct device *dev;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
dev = kmalloc(sizeof(*dev));
|
||||||
|
if (dev==NULL) {
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->d_ops = &console_devops;
|
||||||
|
dev->d_blocks = 0;
|
||||||
|
dev->d_blocksize = 1;
|
||||||
|
dev->d_data = cs;
|
||||||
|
|
||||||
|
result = vfs_adddev("con", dev, 0);
|
||||||
|
if (result) {
|
||||||
|
kfree(dev);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Config routine called by autoconf.c after we are attached to something.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
config_con(struct con_softc *cs, int unit)
|
||||||
|
{
|
||||||
|
struct semaphore *rsem, *wsem;
|
||||||
|
struct lock *rlk, *wlk;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only allow one system console.
|
||||||
|
* Further devices that could be the system console are ignored.
|
||||||
|
*
|
||||||
|
* Do not hardwire the console to be "con1" instead of "con0",
|
||||||
|
* or these asserts will go off.
|
||||||
|
*/
|
||||||
|
if (unit>0) {
|
||||||
|
KASSERT(the_console!=NULL);
|
||||||
|
return ENODEV;
|
||||||
|
}
|
||||||
|
KASSERT(the_console==NULL);
|
||||||
|
|
||||||
|
rsem = sem_create("console read", 0);
|
||||||
|
if (rsem == NULL) {
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
wsem = sem_create("console write", 1);
|
||||||
|
if (wsem == NULL) {
|
||||||
|
sem_destroy(rsem);
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
rlk = lock_create("console-lock-read");
|
||||||
|
if (rlk == NULL) {
|
||||||
|
sem_destroy(rsem);
|
||||||
|
sem_destroy(wsem);
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
wlk = lock_create("console-lock-write");
|
||||||
|
if (wlk == NULL) {
|
||||||
|
lock_destroy(rlk);
|
||||||
|
sem_destroy(rsem);
|
||||||
|
sem_destroy(wsem);
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
cs->cs_rsem = rsem;
|
||||||
|
cs->cs_wsem = wsem;
|
||||||
|
cs->cs_gotchars_head = 0;
|
||||||
|
cs->cs_gotchars_tail = 0;
|
||||||
|
|
||||||
|
the_console = cs;
|
||||||
|
con_userlock_read = rlk;
|
||||||
|
con_userlock_write = wlk;
|
||||||
|
|
||||||
|
flush_delay_buf();
|
||||||
|
|
||||||
|
return attach_console_to_vfs(cs);
|
||||||
|
}
|
68
kern/dev/generic/console.h
Normal file
68
kern/dev/generic/console.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _GENERIC_CONSOLE_H_
|
||||||
|
#define _GENERIC_CONSOLE_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Device data for the hardware-independent system console.
|
||||||
|
*
|
||||||
|
* devdata, send, and sendpolled are provided by the underlying
|
||||||
|
* device, and are to be initialized by the attach routine.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CONSOLE_INPUT_BUFFER_SIZE 32
|
||||||
|
|
||||||
|
struct con_softc {
|
||||||
|
/* initialized by attach routine */
|
||||||
|
void *cs_devdata;
|
||||||
|
void (*cs_send)(void *devdata, int ch);
|
||||||
|
void (*cs_sendpolled)(void *devdata, int ch);
|
||||||
|
|
||||||
|
/* initialized by config routine */
|
||||||
|
struct semaphore *cs_rsem;
|
||||||
|
struct semaphore *cs_wsem;
|
||||||
|
unsigned char cs_gotchars[CONSOLE_INPUT_BUFFER_SIZE];
|
||||||
|
unsigned cs_gotchars_head; /* next slot to put a char in */
|
||||||
|
unsigned cs_gotchars_tail; /* next slot to take a char out */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Functions called by lower-level drivers
|
||||||
|
*/
|
||||||
|
void con_input(/*struct con_softc*/ void *cs, int ch);
|
||||||
|
void con_start(/*struct con_softc*/ void *cs);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Functions called by higher-level code
|
||||||
|
*
|
||||||
|
* putch/getch - see <lib.h>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* _GENERIC_CONSOLE_H_ */
|
158
kern/dev/generic/random.c
Normal file
158
kern/dev/generic/random.c
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <kern/errno.h>
|
||||||
|
#include <kern/fcntl.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#include <uio.h>
|
||||||
|
#include <vfs.h>
|
||||||
|
#include <generic/random.h>
|
||||||
|
#include "autoconf.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Machine-independent generic randomness device.
|
||||||
|
*
|
||||||
|
* Remembers something that's a random source, and provides random()
|
||||||
|
* and randmax() to the rest of the kernel.
|
||||||
|
*
|
||||||
|
* The kernel config mechanism can be used to explicitly choose which
|
||||||
|
* of the available random sources to use, if more than one is
|
||||||
|
* available.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static struct random_softc *the_random = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VFS device functions.
|
||||||
|
* open: allow reading only.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int
|
||||||
|
randeachopen(struct device *dev, int openflags)
|
||||||
|
{
|
||||||
|
(void)dev;
|
||||||
|
|
||||||
|
if (openflags != O_RDONLY) {
|
||||||
|
return EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VFS I/O function. Hand off to implementation.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int
|
||||||
|
randio(struct device *dev, struct uio *uio)
|
||||||
|
{
|
||||||
|
struct random_softc *rs = dev->d_data;
|
||||||
|
|
||||||
|
if (uio->uio_rw != UIO_READ) {
|
||||||
|
return EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rs->rs_read(rs->rs_devdata, uio);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VFS ioctl function.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int
|
||||||
|
randioctl(struct device *dev, int op, userptr_t data)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We don't support any ioctls.
|
||||||
|
*/
|
||||||
|
(void)dev;
|
||||||
|
(void)op;
|
||||||
|
(void)data;
|
||||||
|
return EIOCTL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct device_ops random_devops = {
|
||||||
|
.devop_eachopen = randeachopen,
|
||||||
|
.devop_io = randio,
|
||||||
|
.devop_ioctl = randioctl,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Config function.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
config_random(struct random_softc *rs, int unit)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
/* We use only the first random device. */
|
||||||
|
if (unit!=0) {
|
||||||
|
return ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
KASSERT(the_random==NULL);
|
||||||
|
the_random = rs;
|
||||||
|
|
||||||
|
rs->rs_dev.d_ops = &random_devops;
|
||||||
|
rs->rs_dev.d_blocks = 0;
|
||||||
|
rs->rs_dev.d_blocksize = 1;
|
||||||
|
rs->rs_dev.d_data = rs;
|
||||||
|
|
||||||
|
/* Add the VFS device structure to the VFS device list. */
|
||||||
|
result = vfs_adddev("random", &rs->rs_dev, 0);
|
||||||
|
if (result) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Random number functions exported to the rest of the kernel.
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
random(void)
|
||||||
|
{
|
||||||
|
if (the_random==NULL) {
|
||||||
|
panic("No random device\n");
|
||||||
|
}
|
||||||
|
return the_random->rs_random(the_random->rs_devdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
randmax(void)
|
||||||
|
{
|
||||||
|
if (the_random==NULL) {
|
||||||
|
panic("No random device\n");
|
||||||
|
}
|
||||||
|
return the_random->rs_randmax(the_random->rs_devdata);
|
||||||
|
}
|
46
kern/dev/generic/random.h
Normal file
46
kern/dev/generic/random.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _GENERIC_RANDOM_H_
|
||||||
|
#define _GENERIC_RANDOM_H_
|
||||||
|
|
||||||
|
#include <device.h>
|
||||||
|
struct uio;
|
||||||
|
|
||||||
|
struct random_softc {
|
||||||
|
/* Initialized by lower-level attach routine */
|
||||||
|
void *rs_devdata;
|
||||||
|
uint32_t (*rs_random)(void *devdata);
|
||||||
|
uint32_t (*rs_randmax)(void *devdata);
|
||||||
|
int (*rs_read)(void *devdata, struct uio *uio);
|
||||||
|
|
||||||
|
struct device rs_dev;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _GENERIC_RANDOM_H_ */
|
70
kern/dev/generic/rtclock.c
Normal file
70
kern/dev/generic/rtclock.c
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Machine-independent generic clock "device".
|
||||||
|
*
|
||||||
|
* Basically, all we do is remember something that can be used for
|
||||||
|
* handling requests for the current time, and provide the gettime()
|
||||||
|
* function to the rest of the kernel.
|
||||||
|
*
|
||||||
|
* The kernel config mechanism can be used to explicitly choose which
|
||||||
|
* of the available clocks to use, if more than one is available.
|
||||||
|
*
|
||||||
|
* The system will panic if gettime() is called and there is no clock.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <kern/errno.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#include <clock.h>
|
||||||
|
#include <generic/rtclock.h>
|
||||||
|
#include "autoconf.h"
|
||||||
|
|
||||||
|
static struct rtclock_softc *the_clock = NULL;
|
||||||
|
|
||||||
|
int
|
||||||
|
config_rtclock(struct rtclock_softc *rtc, int unit)
|
||||||
|
{
|
||||||
|
/* We use only the first clock device. */
|
||||||
|
if (unit!=0) {
|
||||||
|
return ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
KASSERT(the_clock==NULL);
|
||||||
|
the_clock = rtc;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gettime(struct timespec *ts)
|
||||||
|
{
|
||||||
|
KASSERT(the_clock!=NULL);
|
||||||
|
the_clock->rtc_gettime(the_clock->rtc_devdata, ts);
|
||||||
|
}
|
45
kern/dev/generic/rtclock.h
Normal file
45
kern/dev/generic/rtclock.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _GENERIC_RTCLOCK_H_
|
||||||
|
#define _GENERIC_RTCLOCK_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The device info for the generic MI clock device - a function
|
||||||
|
* to call and a context pointer for it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct timespec;
|
||||||
|
|
||||||
|
struct rtclock_softc {
|
||||||
|
void *rtc_devdata;
|
||||||
|
void (*rtc_gettime)(void *devdata, struct timespec *);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _GENERIC_RTCLOCK_H_ */
|
55
kern/dev/lamebus/beep_ltimer.c
Normal file
55
kern/dev/lamebus/beep_ltimer.c
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attachment code for having the generic beep device use the LAMEbus
|
||||||
|
* ltimer device for beeping.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#include <generic/beep.h>
|
||||||
|
#include <lamebus/ltimer.h>
|
||||||
|
#include "autoconf.h"
|
||||||
|
|
||||||
|
struct beep_softc *
|
||||||
|
attach_beep_to_ltimer(int beepno, struct ltimer_softc *ls)
|
||||||
|
{
|
||||||
|
struct beep_softc *bs = kmalloc(sizeof(struct beep_softc));
|
||||||
|
if (bs==NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)beepno; // unused
|
||||||
|
|
||||||
|
bs->bs_devdata = ls;
|
||||||
|
bs->bs_beep = ltimer_beep;
|
||||||
|
|
||||||
|
return bs;
|
||||||
|
}
|
59
kern/dev/lamebus/con_lscreen.c
Normal file
59
kern/dev/lamebus/con_lscreen.c
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attachment code for having the generic console device use the LAMEbus
|
||||||
|
* screen device.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#include <generic/console.h>
|
||||||
|
#include <lamebus/lscreen.h>
|
||||||
|
#include "autoconf.h"
|
||||||
|
|
||||||
|
struct con_softc *
|
||||||
|
attach_con_to_lscreen(int consno, struct lscreen_softc *ls)
|
||||||
|
{
|
||||||
|
struct con_softc *cs = kmalloc(sizeof(struct con_softc));
|
||||||
|
if (cs==NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cs->cs_devdata = ls;
|
||||||
|
cs->cs_send = lscreen_write;
|
||||||
|
cs->cs_sendpolled = lscreen_write;
|
||||||
|
|
||||||
|
ls->ls_devdata = cs;
|
||||||
|
ls->ls_start = con_start;
|
||||||
|
ls->ls_input = con_input;
|
||||||
|
|
||||||
|
return cs;
|
||||||
|
}
|
||||||
|
|
61
kern/dev/lamebus/con_lser.c
Normal file
61
kern/dev/lamebus/con_lser.c
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
* The President and Fellows of Harvard College.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attachment code for having the generic console device use the LAMEbus
|
||||||
|
* serial device.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#include <generic/console.h>
|
||||||
|
#include <lamebus/lser.h>
|
||||||
|
#include "autoconf.h"
|
||||||
|
|
||||||
|
struct con_softc *
|
||||||
|
attach_con_to_lser(int consno, struct lser_softc *ls)
|
||||||
|
{
|
||||||
|
struct con_softc *cs = kmalloc(sizeof(struct con_softc));
|
||||||
|
if (cs==NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)consno; // unused
|
||||||
|
|
||||||
|
cs->cs_devdata = ls;
|
||||||
|
cs->cs_send = lser_write;
|
||||||
|
cs->cs_sendpolled = lser_writepolled;
|
||||||
|
|
||||||
|
ls->ls_devdata = cs;
|
||||||
|
ls->ls_start = con_start;
|
||||||
|
ls->ls_input = con_input;
|
||||||
|
|
||||||
|
return cs;
|
||||||
|
}
|
||||||
|
|
57
kern/dev/lamebus/conf.lamebus
Normal file
57
kern/dev/lamebus/conf.lamebus
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#
|
||||||
|
# Kernel config definitions for LAMEbus devices.
|
||||||
|
#
|
||||||
|
# See conf/conf.kern for more information.
|
||||||
|
#
|
||||||
|
|
||||||
|
# System main bus.
|
||||||
|
defdevice lamebus dev/lamebus/lamebus.c
|
||||||
|
|
||||||
|
# Timer.
|
||||||
|
defdevice ltimer dev/lamebus/ltimer.c
|
||||||
|
defattach ltimer* lamebus* dev/lamebus/ltimer_att.c
|
||||||
|
|
||||||
|
# Random.
|
||||||
|
defdevice lrandom dev/lamebus/lrandom.c
|
||||||
|
defattach lrandom* lamebus* dev/lamebus/lrandom_att.c
|
||||||
|
|
||||||
|
# Disk.
|
||||||
|
defdevice lhd dev/lamebus/lhd.c
|
||||||
|
defattach lhd* lamebus* dev/lamebus/lhd_att.c
|
||||||
|
|
||||||
|
# Serial port.
|
||||||
|
defdevice lser dev/lamebus/lser.c
|
||||||
|
defattach lser* lamebus* dev/lamebus/lser_att.c
|
||||||
|
|
||||||
|
# Text screen.
|
||||||
|
defdevice lscreen dev/lamebus/lscreen.c
|
||||||
|
defattach lscreen* lamebus* dev/lamebus/lscreen_att.c
|
||||||
|
|
||||||
|
# Network interface.
|
||||||
|
defdevice lnet dev/lamebus/lnet.c
|
||||||
|
defattach lnet* lamebus* dev/lamebus/lnet_att.c
|
||||||
|
|
||||||
|
# Trace control device.
|
||||||
|
defdevice ltrace dev/lamebus/ltrace.c
|
||||||
|
defattach ltrace* lamebus* dev/lamebus/ltrace_att.c
|
||||||
|
|
||||||
|
# Emulator passthrough filesystem.
|
||||||
|
defdevice emu dev/lamebus/emu.c
|
||||||
|
defattach emu* lamebus* dev/lamebus/emu_att.c
|
||||||
|
|
||||||
|
#
|
||||||
|
# Attachments to generic interface devices
|
||||||
|
#
|
||||||
|
|
||||||
|
# Consoles.
|
||||||
|
defattach con0 lser* dev/lamebus/con_lser.c
|
||||||
|
defattach con0 lscreen* dev/lamebus/con_lscreen.c
|
||||||
|
|
||||||
|
# Beeper.
|
||||||
|
defattach beep* ltimer* dev/lamebus/beep_ltimer.c
|
||||||
|
|
||||||
|
# Clock.
|
||||||
|
defattach rtclock* ltimer* dev/lamebus/rtclock_ltimer.c
|
||||||
|
|
||||||
|
# Random.
|
||||||
|
defattach random0 lrandom* dev/lamebus/random_lrandom.c
|
1357
kern/dev/lamebus/emu.c
Normal file
1357
kern/dev/lamebus/emu.c
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user