/branches/rcu/contrib/toolchain/toolchain.ppc32.sh |
---|
16,7 → 16,7 |
} |
BINUTILS_VERSION="2.17" |
GCC_VERSION="4.1.1" |
GCC_VERSION="4.1.2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2" |
29,7 → 29,6 |
PLATFORM="ppc" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
HOST="i686-pc-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
81,7 → 80,7 |
echo ">>> Compiling and installing binutils" |
cd "${BINUTILSDIR}" |
check_error $? "Change directory failed." |
./configure "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
check_error $? "Error configuring binutils." |
make all install |
check_error $? "Error compiling/installing binutils." |
89,7 → 88,7 |
echo ">>> Compiling and installing GCC" |
cd "${OBJDIR}" |
check_error $? "Change directory failed." |
"${GCCDIR}/configure" "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared |
"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared |
check_error $? "Error configuring GCC." |
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc |
check_error $? "Error compiling/installing GCC." |
/branches/rcu/contrib/toolchain/toolchain.amd64.sh |
---|
16,7 → 16,7 |
} |
BINUTILS_VERSION="2.17" |
GCC_VERSION="4.1.1" |
GCC_VERSION="4.1.2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2" |
29,7 → 29,6 |
PLATFORM="amd64" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
HOST="i686-pc-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
81,7 → 80,7 |
echo ">>> Compiling and installing binutils" |
cd "${BINUTILSDIR}" |
check_error $? "Change directory failed." |
./configure "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
check_error $? "Error configuring binutils." |
make all install |
check_error $? "Error compiling/installing binutils." |
89,7 → 88,7 |
echo ">>> Compiling and installing GCC" |
cd "${OBJDIR}" |
check_error $? "Change directory failed." |
"${GCCDIR}/configure" "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared |
"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared |
check_error $? "Error configuring GCC." |
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc |
check_error $? "Error compiling/installing GCC." |
/branches/rcu/contrib/toolchain/toolchain.ppc64.sh |
---|
16,7 → 16,7 |
} |
BINUTILS_VERSION="2.17" |
GCC_VERSION="4.1.1" |
GCC_VERSION="4.1.2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2" |
29,7 → 29,6 |
PLATFORM="ppc64" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
HOST="i686-pc-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
81,7 → 80,7 |
echo ">>> Compiling and installing binutils" |
cd "${BINUTILSDIR}" |
check_error $? "Change directory failed." |
./configure "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
check_error $? "Error configuring binutils." |
make all install |
check_error $? "Error compiling/installing binutils." |
89,7 → 88,7 |
echo ">>> Compiling and installing GCC" |
cd "${OBJDIR}" |
check_error $? "Change directory failed." |
"${GCCDIR}/configure" "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared |
"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared |
check_error $? "Error configuring GCC." |
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc |
check_error $? "Error compiling/installing GCC." |
/branches/rcu/contrib/toolchain/toolchain.ia32.sh |
---|
16,7 → 16,7 |
} |
BINUTILS_VERSION="2.17" |
GCC_VERSION="4.1.1" |
GCC_VERSION="4.1.2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2" |
29,7 → 29,6 |
PLATFORM="i686" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-pc-linux-gnu" |
HOST="i686-pc-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
81,7 → 80,7 |
echo ">>> Compiling and installing binutils" |
cd "${BINUTILSDIR}" |
check_error $? "Change directory failed." |
./configure "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
check_error $? "Error configuring binutils." |
make all install |
check_error $? "Error compiling/installing binutils." |
89,9 → 88,9 |
echo ">>> Compiling and installing GCC" |
cd "${OBJDIR}" |
check_error $? "Change directory failed." |
"${GCCDIR}/configure" "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared |
"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared |
check_error $? "Error configuring GCC." |
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc all-target-libobjc install-target-libobjc |
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc |
check_error $? "Error compiling/installing GCC." |
echo |
/branches/rcu/contrib/toolchain/toolchain.mipsel32.sh |
---|
16,7 → 16,7 |
} |
BINUTILS_VERSION="2.17" |
GCC_VERSION="4.1.1" |
GCC_VERSION="4.1.2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2" |
29,7 → 29,6 |
PLATFORM="mipsel" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
HOST="i686-pc-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
81,7 → 80,7 |
echo ">>> Compiling and installing binutils" |
cd "${BINUTILSDIR}" |
check_error $? "Change directory failed." |
./configure "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
check_error $? "Error configuring binutils." |
make all install |
check_error $? "Error compiling/installing binutils." |
89,7 → 88,7 |
echo ">>> Compiling and installing GCC" |
cd "${OBJDIR}" |
check_error $? "Change directory failed." |
"${GCCDIR}/configure" "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared |
"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared |
check_error $? "Error configuring GCC." |
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc |
check_error $? "Error compiling/installing GCC." |
/branches/rcu/contrib/toolchain/toolchain.sparc64.sh |
---|
16,7 → 16,7 |
} |
BINUTILS_VERSION="2.17" |
GCC_VERSION="4.1.1" |
GCC_VERSION="4.1.2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2" |
29,7 → 29,6 |
PLATFORM="sparc64" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
HOST="i686-pc-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
81,7 → 80,7 |
echo ">>> Compiling and installing binutils" |
cd "${BINUTILSDIR}" |
check_error $? "Change directory failed." |
./configure "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
check_error $? "Error configuring binutils." |
make all install |
check_error $? "Error compiling/installing binutils." |
89,9 → 88,9 |
echo ">>> Compiling and installing GCC" |
cd "${OBJDIR}" |
check_error $? "Change directory failed." |
"${GCCDIR}/configure" "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared |
"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared |
check_error $? "Error configuring GCC." |
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc all-target-libobjc install-target-libobjc |
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc |
check_error $? "Error compiling/installing GCC." |
echo |
/branches/rcu/contrib/toolchain/toolchain.ia64.sh |
---|
16,7 → 16,7 |
} |
BINUTILS_VERSION="2.17" |
GCC_VERSION="4.1.1" |
GCC_VERSION="4.1.2" |
INCLUDES="ia64-pc-gnu-linux_includes.tar.bz2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
31,7 → 31,6 |
PLATFORM="ia64" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-pc-linux-gnu" |
HOST="i686-pc-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
INCLUDESDIR="${WORKDIR}/include" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
90,7 → 89,7 |
echo ">>> Compiling and installing binutils" |
cd "${BINUTILSDIR}" |
check_error $? "Change directory failed." |
./configure "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
check_error $? "Error configuring binutils." |
make all install |
check_error $? "Error compiling/installing binutils." |
98,7 → 97,7 |
echo ">>> Compiling and installing GCC" |
cd "${OBJDIR}" |
check_error $? "Change directory failed." |
"${GCCDIR}/configure" "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj "--with-headers=${INCLUDESDIR}" --disable-shared |
"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj "--with-headers=${INCLUDESDIR}" --disable-shared |
check_error $? "Error configuring GCC." |
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc |
check_error $? "Error compiling/installing GCC." |
/branches/rcu/contrib/toolchain/toolchain.arm32.sh |
---|
16,7 → 16,7 |
} |
BINUTILS_VERSION="2.17" |
GCC_VERSION="4.1.1" |
GCC_VERSION="4.1.2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2" |
29,7 → 29,6 |
PLATFORM="arm" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
HOST="i86pc-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
81,7 → 80,7 |
echo ">>> Compiling and installing binutils" |
cd "${BINUTILSDIR}" |
check_error $? "Change directory failed." |
./configure "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
check_error $? "Error configuring binutils." |
make all install |
check_error $? "Error compiling/installing binutils." |
89,7 → 88,7 |
echo ">>> Compiling and installing GCC" |
cd "${OBJDIR}" |
check_error $? "Change directory failed." |
"${GCCDIR}/configure" "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared |
"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared |
check_error $? "Error configuring GCC." |
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc |
check_error $? "Error compiling/installing GCC." |
/branches/rcu/contrib/toolchain/toolchain.mipseb32.sh |
---|
16,7 → 16,7 |
} |
BINUTILS_VERSION="2.16.1" |
GCC_VERSION="4.1.1" |
GCC_VERSION="4.1.2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2" |
29,7 → 29,6 |
PLATFORM="mips" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-sgi-irix5" |
HOST="i686-pc-linux-gnu" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
81,7 → 80,7 |
echo ">>> Compiling and installing binutils" |
cd "${BINUTILSDIR}" |
check_error $? "Change directory failed." |
./configure "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
check_error $? "Error configuring binutils." |
make all install |
check_error $? "Error compiling/installing binutils." |
89,7 → 88,7 |
echo ">>> Compiling and installing GCC" |
cd "${OBJDIR}" |
check_error $? "Change directory failed." |
"${GCCDIR}/configure" "--host=${HOST}" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared |
"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared |
check_error $? "Error configuring GCC." |
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc |
check_error $? "Error compiling/installing GCC." |
/branches/rcu/kernel/test/test.c |
---|
63,3 → 63,4 |
/** @} |
*/ |
/branches/rcu/kernel/test/test.h |
---|
77,3 → 77,4 |
/** @} |
*/ |
/branches/rcu/kernel/test/tasklet/tasklet1.c |
---|
52,9 → 52,9 |
tasklet_descriptor_t *tasklet_desc; |
//before we start we need to register a tasklet |
if (!gquiet) |
printf("Registering tasklet..."); |
printf("cpu:%d, Registering tasklet...", CPU->id); |
if (!gquiet) |
tasklet_desc=tasklet_register(&func, "\nTasklet called and received data from second thread\n"); |
tasklet_desc=tasklet_register(&func, "\nTasklet called and received data\n"); |
else |
tasklet_desc=tasklet_register(&func, ""); |
if (!gquiet) |
62,7 → 62,7 |
//first we'll try disabling the tasklet |
if (!gquiet) |
printf("Disabling tasklet..."); |
printf("cpu:%d, Disabling tasklet...", CPU->id); |
tasklet_disable(tasklet_desc); |
if (!gquiet) |
printf("Done!\n"); |
69,7 → 69,7 |
//we'll schedule the disabled tasklet |
if (!gquiet) |
printf("Scheduling tasklet..."); |
printf("cpu:%d, Scheduling tasklet...", CPU->id); |
tasklet_schedule(tasklet_desc); |
if (!gquiet) |
printf("Done!\n"); |
76,14 → 76,14 |
//and we'll wait if it gets called. It shouldn't however, because it's disabled |
if (!gquiet) |
printf("Waiting 1s...\n"); |
printf("cpu:%d, Waiting 1s...\n", CPU->id); |
waitq_sleep_timeout(&wq,(uint32_t) 1000000,0); |
if (!gquiet) |
printf("Done!\n"); |
printf("cpu:%d, Done!\n", CPU->id); |
//then we'll try to enable it |
if (!gquiet) |
printf("Enabling tasklet..."); |
printf("cpu:%d, Enabling tasklet...", CPU->id); |
tasklet_enable(tasklet_desc); |
if (!gquiet) |
printf("Done!\n"); |
90,14 → 90,14 |
//and wait if it gets called this time. It should because it's enabled |
if (!gquiet) |
printf("Waiting 1s...\n"); |
printf("cpu:%d, Waiting 1s...\n", CPU->id); |
waitq_sleep_timeout(&wq,(uint32_t) 1000000,0); |
if (!gquiet) |
printf("Done!\n"); |
printf("cpu:%d, Done!\n", CPU->id); |
//finally we'll free the tasklet structure |
if (!gquiet) |
printf("Freeing..."); |
printf("cpu:%d, Freeing...", CPU->id); |
tasklet_free(tasklet_desc); |
if (!gquiet) |
printf("Done!\n"); |
109,8 → 109,11 |
waitq_t wq; |
waitq_initialize(&wq); |
tasklet_descriptor_t *tasklet_desc; |
thread_t* second_thread; |
thread_t* second_thread = NULL; |
#ifdef CONFIG_SMP |
if (!quiet) |
printf("cpus:%d\n", config.cpu_active); |
if (config.cpu_active >1) { |
second_thread = thread_create(&running_tasklet, NULL, TASK, THREAD_FLAG_WIRED,"running tasklet", false); |
if (CPU->id == 0) |
123,7 → 126,7 |
//before we start we need to register a tasklet |
if (!quiet) |
printf("Registering tasklet..."); |
printf("cpu:%d, Registering tasklet...", CPU->id); |
if (!quiet) |
tasklet_desc=tasklet_register(&func, "\nTasklet called and received data\n"); |
else |
133,7 → 136,7 |
//first we'll try disabling the tasklet |
if (!quiet) |
printf("Disabling tasklet..."); |
printf("cpu:%d, Disabling tasklet...", CPU->id); |
tasklet_disable(tasklet_desc); |
if (!quiet) |
printf("Done!\n"); |
140,7 → 143,7 |
//we'll schedule the disabled tasklet |
if (!quiet) |
printf("Scheduling tasklet..."); |
printf("cpu:%d, Scheduling tasklet...", CPU->id); |
tasklet_schedule(tasklet_desc); |
if (!quiet) |
printf("Done!\n"); |
147,14 → 150,15 |
//and we'll wait if it gets called. It shouldn't however, because it's disabled |
if (!quiet) |
printf("Waiting 1s...\n"); |
printf("cpu:%d, Waiting 1s...\n", CPU->id); |
waitq_sleep_timeout(&wq,(uint32_t) 1000000,0); |
if (!quiet) |
printf("Done!\n"); |
printf("cpu:%d, Done!\n", CPU->id); |
//then we'll try to enable it |
if (!quiet) |
printf("Enabling tasklet..."); |
printf("cpu:%d, Enabling tasklet...", CPU->id); |
tasklet_enable(tasklet_desc); |
if (!quiet) |
printf("Done!\n"); |
161,14 → 165,21 |
//and wait if it gets called this time. It should because it's enabled |
if (!quiet) |
printf("Waiting 1s...\n"); |
printf("cpu:%d, Waiting 1s...\n", CPU->id); |
waitq_sleep_timeout(&wq,(uint32_t) 1000000,0); |
if (!quiet) |
printf("Done!\n"); |
printf("cpu:%d, Done!\n", CPU->id); |
#ifdef CONFIG_SMP |
if (config.cpu_active >1) { |
printf("Joining with the second thread..."); |
thread_join(second_thread); |
printf("Done\n"); |
} |
#endif |
//finally we'll free the tasklet structure |
if (!quiet) |
printf("Freeing..."); |
printf("cpu:%d, Freeing...", CPU->id); |
tasklet_free(tasklet_desc); |
if (!quiet) |
printf("Done!\n"); |
/branches/rcu/kernel/genarch/src/fb/fb.c |
---|
511,8 → 511,6 |
sysinfo_set_item_val("fb.scanline", NULL, scan); |
sysinfo_set_item_val("fb.visual", NULL, visual); |
sysinfo_set_item_val("fb.address.physical", NULL, addr); |
sysinfo_set_item_val("fb.address.color", NULL, |
PAGE_COLOR((uintptr_t) fbaddress)); |
sysinfo_set_item_val("fb.invert-colors", NULL, invert_colors); |
/* Allocate double buffer */ |
/branches/rcu/kernel/genarch/src/mm/asid.c |
---|
62,15 → 62,9 |
#include <arch/mm/asid.h> |
#include <synch/spinlock.h> |
#include <synch/mutex.h> |
#include <arch.h> |
#include <adt/list.h> |
#include <debug.h> |
/** |
* asidlock protects the asids_allocated counter. |
*/ |
SPINLOCK_INITIALIZE(asidlock); |
static count_t asids_allocated = 0; |
/** Allocate free address space identifier. |
90,7 → 84,6 |
* Check if there is an unallocated ASID. |
*/ |
spinlock_lock(&asidlock); |
if (asids_allocated == ASIDS_ALLOCABLE) { |
/* |
108,7 → 101,6 |
list_remove(tmp); |
as = list_get_instance(tmp, as_t, inactive_as_with_asid_link); |
mutex_lock_active(&as->lock); |
/* |
* Steal the ASID. |
130,8 → 122,6 |
*/ |
as_invalidate_translation_cache(as, 0, (count_t) -1); |
mutex_unlock(&as->lock); |
/* |
* Get the system rid of the stolen ASID. |
*/ |
156,8 → 146,6 |
tlb_shootdown_finalize(); |
} |
spinlock_unlock(&asidlock); |
return asid; |
} |
170,16 → 158,8 |
*/ |
void asid_put(asid_t asid) |
{ |
ipl_t ipl; |
ipl = interrupts_disable(); |
spinlock_lock(&asidlock); |
asids_allocated--; |
asid_put_arch(asid); |
spinlock_unlock(&asidlock); |
interrupts_restore(ipl); |
} |
/** @} |
/branches/rcu/kernel/genarch/src/mm/page_ht.c |
---|
55,7 → 55,8 |
static bool compare(unative_t key[], count_t keys, link_t *item); |
static void remove_callback(link_t *item); |
static void ht_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame, int flags); |
static void ht_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame, |
int flags); |
static void ht_mapping_remove(as_t *as, uintptr_t page); |
static pte_t *ht_mapping_find(as_t *as, uintptr_t page); |
136,7 → 137,8 |
t = hash_table_get_instance(item, pte_t, link); |
if (keys == PAGE_HT_KEYS) { |
return (key[KEY_AS] == (uintptr_t) t->as) && (key[KEY_PAGE] == t->page); |
return (key[KEY_AS] == (uintptr_t) t->as) && |
(key[KEY_PAGE] == t->page); |
} else { |
return (key[KEY_AS] == (uintptr_t) t->as); |
} |
175,7 → 177,10 |
void ht_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame, int flags) |
{ |
pte_t *t; |
unative_t key[2] = { (uintptr_t) as, page = ALIGN_DOWN(page, PAGE_SIZE) }; |
unative_t key[2] = { |
(uintptr_t) as, |
page = ALIGN_DOWN(page, PAGE_SIZE) |
}; |
if (!hash_table_find(&page_ht, key)) { |
t = (pte_t *) malloc(sizeof(pte_t), FRAME_ATOMIC); |
209,7 → 214,10 |
*/ |
void ht_mapping_remove(as_t *as, uintptr_t page) |
{ |
unative_t key[2] = { (uintptr_t) as, page = ALIGN_DOWN(page, PAGE_SIZE) }; |
unative_t key[2] = { |
(uintptr_t) as, |
page = ALIGN_DOWN(page, PAGE_SIZE) |
}; |
/* |
* Note that removed PTE's will be freed |
234,7 → 242,10 |
{ |
link_t *hlp; |
pte_t *t = NULL; |
unative_t key[2] = { (uintptr_t) as, page = ALIGN_DOWN(page, PAGE_SIZE) }; |
unative_t key[2] = { |
(uintptr_t) as, |
page = ALIGN_DOWN(page, PAGE_SIZE) |
}; |
hlp = hash_table_find(&page_ht, key); |
if (hlp) |
/branches/rcu/kernel/generic/include/proc/thread.h |
---|
53,10 → 53,7 |
/* Thread flags */ |
/** Thread cannot be migrated to another CPU. |
* When using this flag, the caller must set cpu in the thread_t |
* structure manually before calling thread_ready (even on uniprocessor) |
*/ |
/** Thread cannot be migrated to another CPU. */ |
#define THREAD_FLAG_WIRED (1 << 0) |
/** Thread was migrated to another CPU and has not run yet. */ |
#define THREAD_FLAG_STOLEN (1 << 1) |
/branches/rcu/kernel/generic/include/ddi/irq.h |
---|
122,14 → 122,6 |
*/ |
SPINLOCK_DECLARE(lock); |
/** Send EOI before processing the interrupt. |
* This is essential for timer interrupt which |
* has to be acknowledged before doing preemption |
* to make sure another timer interrupt will |
* be eventually generated. |
*/ |
bool preack; |
/** Unique device number. -1 if not yet assigned. */ |
devno_t devno; |
/branches/rcu/kernel/generic/include/mm/as.h |
---|
89,6 → 89,17 |
@public |
/** Protected by asidlock. */ |
link_t inactive_as_with_asid_link; |
/** |
* Number of processors on wich is this address space active. |
* Protected by asidlock. |
*/ |
count_t cpu_refcount; |
/** |
* Address space identifier. |
* Constant on architectures that do not support ASIDs. |
* Protected by asidlock. |
*/ |
asid_t asid; |
mutex_t lock; |
95,18 → 106,9 |
/** Number of references (i.e tasks that reference this as). */ |
count_t refcount; |
/** Number of processors on wich is this address space active. */ |
count_t cpu_refcount; |
/** B+tree of address space areas. */ |
btree_t as_area_btree; |
/** |
* Address space identifier. |
* Constant on architectures that do not support ASIDs. |
*/ |
asid_t asid; |
/** Non-generic content. */ |
as_genarch_t genarch; |
133,6 → 135,17 |
typedef struct as { |
/** Protected by asidlock. */ |
link_t inactive_as_with_asid_link; |
/** |
* Number of processors on wich is this address space active. |
* Protected by asidlock. |
*/ |
count_t cpu_refcount; |
/** |
* Address space identifier. |
* Constant on architectures that do not support ASIDs. |
* Protected by asidlock. |
*/ |
asid_t asid; |
mutex_t lock; |
139,18 → 152,9 |
/** Number of references (i.e tasks that reference this as). */ |
count_t refcount; |
/** Number of processors on wich is this address space active. */ |
count_t cpu_refcount; |
/** B+tree of address space areas. */ |
btree_t as_area_btree; |
/** |
* Address space identifier. |
* Constant on architectures that do not support ASIDs. |
*/ |
asid_t asid; |
/** Non-generic content. */ |
as_genarch_t genarch; |
205,7 → 209,6 |
/** Address space area structure. |
* |
* Each as_area_t structure describes one contiguous area of virtual memory. |
* In the future, it should not be difficult to support shared areas. |
*/ |
typedef struct { |
mutex_t lock; |
250,7 → 253,6 |
extern as_operations_t *as_operations; |
#endif |
SPINLOCK_EXTERN(inactive_as_with_asid_lock); |
extern link_t inactive_as_with_asid_head; |
extern void as_init(void); |
/branches/rcu/kernel/generic/src/main/main.c |
---|
246,8 → 246,6 |
task_init(); |
thread_init(); |
futex_init(); |
klog_init(); |
if (init.cnt > 0) { |
257,6 → 255,7 |
init.tasks[i].size); |
} else |
printf("No init binaries found\n"); |
ipc_init(); |
/* |
274,7 → 273,6 |
panic("can't create kinit thread\n"); |
thread_ready(t); |
//tasklets disabled for debugging purposes |
tasklet_run_tasklet_thread(k); |
/* |
/branches/rcu/kernel/generic/src/time/clock.c |
---|
104,8 → 104,6 |
* physmem_map() the clock_parea. |
*/ |
sysinfo_set_item_val("clock.cacheable", NULL, (unative_t) true); |
sysinfo_set_item_val("clock.fcolor", NULL, (unative_t) |
PAGE_COLOR(clock_parea.vbase)); |
sysinfo_set_item_val("clock.faddr", NULL, (unative_t) faddr); |
} |
/branches/rcu/kernel/generic/src/ddi/ddi.c |
---|
99,8 → 99,7 |
* @return 0 on success, EPERM if the caller lacks capabilities to use this |
* syscall, ENOENT if there is no task matching the specified ID or the |
* physical address space is not enabled for mapping and ENOMEM if there |
* was a problem in creating address space area. ENOTSUP is returned when |
* an attempt to create an illegal address alias is detected. |
* was a problem in creating address space area. |
*/ |
static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, count_t pages, int flags) |
{ |
139,20 → 138,8 |
interrupts_restore(ipl); |
return ENOENT; |
} |
#ifdef CONFIG_VIRT_IDX_DCACHE |
if (PAGE_COLOR(parea->vbase) != PAGE_COLOR(vp)) { |
/* |
* Refuse to create an illegal address alias. |
*/ |
spinlock_unlock(&parea_lock); |
interrupts_restore(ipl); |
return ENOTSUP; |
} |
#endif /* CONFIG_VIRT_IDX_DCACHE */ |
spinlock_unlock(&parea_lock); |
spinlock_lock(&TASK->lock); |
if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp, AS_AREA_ATTR_NONE, |
/branches/rcu/kernel/generic/src/ddi/irq.c |
---|
138,7 → 138,6 |
{ |
link_initialize(&irq->link); |
spinlock_initialize(&irq->lock, "irq.lock"); |
irq->preack = false; |
irq->inr = -1; |
irq->devno = -1; |
irq->trigger = (irq_trigger_t) 0; |
/branches/rcu/kernel/generic/src/console/klog.c |
---|
90,8 → 90,6 |
ddi_parea_register(&klog_parea); |
sysinfo_set_item_val("klog.faddr", NULL, (unative_t) faddr); |
sysinfo_set_item_val("klog.fcolor", NULL, (unative_t) |
PAGE_COLOR((uintptr_t) klog)); |
sysinfo_set_item_val("klog.pages", NULL, 1 << KLOG_ORDER); |
sysinfo_set_item_val("klog.devno", NULL, devno); |
sysinfo_set_item_val("klog.inr", NULL, KLOG_VIRT_INR); |
/branches/rcu/kernel/generic/src/proc/scheduler.c |
---|
61,7 → 61,6 |
#include <cpu.h> |
#include <print.h> |
#include <debug.h> |
#include <proc/tasklet.h> |
static void before_task_runs(void); |
static void before_thread_runs(void); |
227,11 → 226,7 |
* Take the first thread from the queue. |
*/ |
t = list_get_instance(r->rq_head.next, thread_t, rq_link); |
if (verbose) |
printf("cpu%d removing, rq_head %x, t: %x, next: %x, link: %x \n",CPU->id, r->rq_head, t, r->rq_head.next, t->rq_link); |
list_remove(&t->rq_link); |
if (verbose) |
printf("cpu%d removed, rq_head %x, t: %x, next: %x, link: %x \n",CPU->id, r->rq_head, t, r->rq_head.next, t->rq_link); |
spinlock_unlock(&r->lock); |
443,8 → 438,7 |
THREAD->call_me = NULL; |
THREAD->call_me_with = NULL; |
} |
if (verbose) |
printf("cpu%d, Sleeping unlocking \n", CPU->id); |
spinlock_unlock(&THREAD->lock); |
break; |
460,17 → 454,12 |
THREAD = NULL; |
} |
if (verbose) |
printf("cpu%d looking for next thread\n", CPU->id); |
THREAD = find_best_thread(); |
if (verbose) |
printf("cpu%d t locking THREAD:%x \n", CPU->id, THREAD); |
spinlock_lock(&THREAD->lock); |
priority = THREAD->priority; |
spinlock_unlock(&THREAD->lock); |
if (verbose) |
printf("cpu%d t unlocked after priority THREAD:%x \n", CPU->id, THREAD); |
relink_rq(priority); |
/branches/rcu/kernel/generic/src/proc/thread.c |
---|
238,7 → 238,6 |
cpu = CPU; |
if (t->flags & THREAD_FLAG_WIRED) { |
ASSERT(t->cpu != NULL); |
cpu = t->cpu; |
} |
t->state = Ready; |
/branches/rcu/kernel/generic/src/lib/rd.c |
---|
90,8 → 90,6 |
sysinfo_set_item_val("rd.size", NULL, dsize); |
sysinfo_set_item_val("rd.address.physical", NULL, (unative_t) |
KA2PA((void *) header + hsize)); |
sysinfo_set_item_val("rd.address.color", NULL, (unative_t) |
PAGE_COLOR((uintptr_t) header + hsize)); |
return RE_OK; |
} |
/branches/rcu/kernel/generic/src/mm/tlb.c |
---|
78,7 → 78,8 |
* @param page Virtual page address, if required by type. |
* @param count Number of pages, if required by type. |
*/ |
void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid, uintptr_t page, count_t count) |
void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid, |
uintptr_t page, count_t count) |
{ |
int i; |
107,11 → 108,11 |
/* |
* Enqueue the message. |
*/ |
cpu->tlb_messages[cpu->tlb_messages_count].type = type; |
cpu->tlb_messages[cpu->tlb_messages_count].asid = asid; |
cpu->tlb_messages[cpu->tlb_messages_count].page = page; |
cpu->tlb_messages[cpu->tlb_messages_count].count = count; |
cpu->tlb_messages_count++; |
index_t idx = cpu->tlb_messages_count++; |
cpu->tlb_messages[idx].type = type; |
cpu->tlb_messages[idx].asid = asid; |
cpu->tlb_messages[idx].page = page; |
cpu->tlb_messages[idx].count = count; |
} |
spinlock_unlock(&cpu->lock); |
} |
/branches/rcu/kernel/generic/src/mm/backend_anon.c |
---|
72,11 → 72,13 |
* @param addr Faulting virtual address. |
* @param access Access mode that caused the fault (i.e. read/write/exec). |
* |
* @return AS_PF_FAULT on failure (i.e. page fault) or AS_PF_OK on success (i.e. serviced). |
* @return AS_PF_FAULT on failure (i.e. page fault) or AS_PF_OK on success (i.e. |
* serviced). |
*/ |
int anon_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access) |
{ |
uintptr_t frame; |
bool dirty = false; |
if (!as_area_check_access(area, access)) |
return AS_PF_FAULT; |
86,7 → 88,8 |
/* |
* The area is shared, chances are that the mapping can be found |
* in the pagemap of the address space area share info structure. |
* in the pagemap of the address space area share info |
* structure. |
* In the case that the pagemap does not contain the respective |
* mapping, a new frame is allocated and the mapping is created. |
*/ |
102,7 → 105,8 |
* Just a small workaround. |
*/ |
for (i = 0; i < leaf->keys; i++) { |
if (leaf->key[i] == ALIGN_DOWN(addr, PAGE_SIZE)) { |
if (leaf->key[i] == |
ALIGN_DOWN(addr, PAGE_SIZE)) { |
allocate = false; |
break; |
} |
110,11 → 114,15 |
if (allocate) { |
frame = (uintptr_t) frame_alloc(ONE_FRAME, 0); |
memsetb(PA2KA(frame), FRAME_SIZE, 0); |
dirty = true; |
/* |
* Insert the address of the newly allocated frame to the pagemap. |
* Insert the address of the newly allocated |
* frame to the pagemap. |
*/ |
btree_insert(&area->sh_info->pagemap, ALIGN_DOWN(addr, PAGE_SIZE) - area->base, (void *) frame, leaf); |
btree_insert(&area->sh_info->pagemap, |
ALIGN_DOWN(addr, PAGE_SIZE) - area->base, |
(void *) frame, leaf); |
} |
} |
frame_reference_add(ADDR2PFN(frame)); |
137,12 → 145,13 |
*/ |
frame = (uintptr_t) frame_alloc(ONE_FRAME, 0); |
memsetb(PA2KA(frame), FRAME_SIZE, 0); |
dirty = true; |
} |
/* |
* Map 'page' to 'frame'. |
* Note that TLB shootdown is not attempted as only new information is being |
* inserted into page tables. |
* Note that TLB shootdown is not attempted as only new information is |
* being inserted into page tables. |
*/ |
page_mapping_insert(AS, addr, frame, as_area_get_flags(area)); |
if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1)) |
162,9 → 171,6 |
void anon_frame_free(as_area_t *area, uintptr_t page, uintptr_t frame) |
{ |
frame_free(frame); |
#ifdef CONFIG_VIRT_IDX_DCACHE |
dcache_flush_frame(page, frame); |
#endif |
} |
/** Share the anonymous address space area. |
184,7 → 190,8 |
* Copy used portions of the area to sh_info's page map. |
*/ |
mutex_lock(&area->sh_info->lock); |
for (cur = area->used_space.leaf_head.next; cur != &area->used_space.leaf_head; cur = cur->next) { |
for (cur = area->used_space.leaf_head.next; |
cur != &area->used_space.leaf_head; cur = cur->next) { |
btree_node_t *node; |
int i; |
198,12 → 205,17 |
pte_t *pte; |
page_table_lock(area->as, false); |
pte = page_mapping_find(area->as, base + j*PAGE_SIZE); |
ASSERT(pte && PTE_VALID(pte) && PTE_PRESENT(pte)); |
btree_insert(&area->sh_info->pagemap, (base + j*PAGE_SIZE) - area->base, |
pte = page_mapping_find(area->as, |
base + j * PAGE_SIZE); |
ASSERT(pte && PTE_VALID(pte) && |
PTE_PRESENT(pte)); |
btree_insert(&area->sh_info->pagemap, |
(base + j * PAGE_SIZE) - area->base, |
(void *) PTE_GET_FRAME(pte), NULL); |
page_table_unlock(area->as, false); |
frame_reference_add(ADDR2PFN(PTE_GET_FRAME(pte))); |
pfn_t pfn = ADDR2PFN(PTE_GET_FRAME(pte)); |
frame_reference_add(pfn); |
} |
} |
/branches/rcu/kernel/generic/src/mm/as.c |
---|
95,10 → 95,13 |
#endif |
/** |
* This lock protects inactive_as_with_asid_head list. It must be acquired |
* before as_t mutex. |
* This lock serializes access to the ASID subsystem. |
* It protects: |
* - inactive_as_with_asid_head list |
* - as->asid for each as of the as_t type |
* - asids_allocated counter |
*/ |
SPINLOCK_INITIALIZE(inactive_as_with_asid_lock); |
SPINLOCK_INITIALIZE(asidlock); |
/** |
* This list contains address spaces that are not active on any |
205,14 → 208,15 |
* Since there is no reference to this area, |
* it is safe not to lock its mutex. |
*/ |
ipl = interrupts_disable(); |
spinlock_lock(&inactive_as_with_asid_lock); |
spinlock_lock(&asidlock); |
if (as->asid != ASID_INVALID && as != AS_KERNEL) { |
if (as != AS && as->cpu_refcount == 0) |
list_remove(&as->inactive_as_with_asid_link); |
asid_put(as->asid); |
} |
spinlock_unlock(&inactive_as_with_asid_lock); |
spinlock_unlock(&asidlock); |
/* |
* Destroy address space areas of the address space. |
613,8 → 617,7 |
* such address space area, EPERM if there was a problem in accepting the area |
* or ENOMEM if there was a problem in allocating destination address space |
* area. ENOTSUP is returned if the address space area backend does not support |
* sharing or if the kernel detects an attempt to create an illegal address |
* alias. |
* sharing. |
*/ |
int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size, |
as_t *dst_as, uintptr_t dst_base, int dst_flags_mask) |
667,21 → 670,7 |
return EPERM; |
} |
#ifdef CONFIG_VIRT_IDX_DCACHE |
if (!(dst_flags_mask & AS_AREA_EXEC)) { |
if (PAGE_COLOR(src_area->base) != PAGE_COLOR(dst_base)) { |
/* |
* Refuse to create an illegal address alias. |
*/ |
mutex_unlock(&src_area->lock); |
mutex_unlock(&src_as->lock); |
interrupts_restore(ipl); |
return ENOTSUP; |
} |
} |
#endif /* CONFIG_VIRT_IDX_DCACHE */ |
/* |
* Now we are committed to sharing the area. |
* First, prepare the area for sharing. |
* Then it will be safe to unlock it. |
875,7 → 864,8 |
/** Switch address spaces. |
* |
* Note that this function cannot sleep as it is essentially a part of |
* scheduling. Sleeping here would lead to deadlock on wakeup. |
* scheduling. Sleeping here would lead to deadlock on wakeup. Another |
* thing which is forbidden in this context is locking the address space. |
* |
* @param old Old address space or NULL. |
* @param new New address space. |
882,17 → 872,12 |
*/ |
void as_switch(as_t *old_as, as_t *new_as) |
{ |
ipl_t ipl; |
bool needs_asid = false; |
spinlock_lock(&asidlock); |
ipl = interrupts_disable(); |
spinlock_lock(&inactive_as_with_asid_lock); |
/* |
* First, take care of the old address space. |
*/ |
if (old_as) { |
mutex_lock_active(&old_as->lock); |
ASSERT(old_as->cpu_refcount); |
if((--old_as->cpu_refcount == 0) && (old_as != AS_KERNEL)) { |
/* |
905,7 → 890,6 |
list_append(&old_as->inactive_as_with_asid_link, |
&inactive_as_with_asid_head); |
} |
mutex_unlock(&old_as->lock); |
/* |
* Perform architecture-specific tasks when the address space |
917,43 → 901,24 |
/* |
* Second, prepare the new address space. |
*/ |
mutex_lock_active(&new_as->lock); |
if ((new_as->cpu_refcount++ == 0) && (new_as != AS_KERNEL)) { |
if (new_as->asid != ASID_INVALID) { |
if (new_as->asid != ASID_INVALID) |
list_remove(&new_as->inactive_as_with_asid_link); |
} else { |
/* |
* Defer call to asid_get() until new_as->lock is released. |
*/ |
needs_asid = true; |
else |
new_as->asid = asid_get(); |
} |
} |
#ifdef AS_PAGE_TABLE |
SET_PTL0_ADDRESS(new_as->genarch.page_table); |
#endif |
mutex_unlock(&new_as->lock); |
if (needs_asid) { |
/* |
* Allocation of new ASID was deferred |
* until now in order to avoid deadlock. |
*/ |
asid_t asid; |
asid = asid_get(); |
mutex_lock_active(&new_as->lock); |
new_as->asid = asid; |
mutex_unlock(&new_as->lock); |
} |
spinlock_unlock(&inactive_as_with_asid_lock); |
interrupts_restore(ipl); |
/* |
* Perform architecture-specific steps. |
* (e.g. write ASID to hardware register etc.) |
*/ |
as_install_arch(new_as); |
spinlock_unlock(&asidlock); |
AS = new_as; |
} |
/branches/rcu/kernel/generic/src/mm/backend_phys.c |
---|
32,7 → 32,8 |
/** |
* @file |
* @brief Backend for address space areas backed by continuous physical memory. |
* @brief Backend for address space areas backed by continuous physical |
* memory. |
*/ |
#include <debug.h> |
62,7 → 63,8 |
* @param addr Faulting virtual address. |
* @param access Access mode that caused the fault (i.e. read/write/exec). |
* |
* @return AS_PF_FAULT on failure (i.e. page fault) or AS_PF_OK on success (i.e. serviced). |
* @return AS_PF_FAULT on failure (i.e. page fault) or AS_PF_OK on success (i.e. |
* serviced). |
*/ |
int phys_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access) |
{ |
72,7 → 74,8 |
return AS_PF_FAULT; |
ASSERT(addr - area->base < area->backend_data.frames * FRAME_SIZE); |
page_mapping_insert(AS, addr, base + (addr - area->base), as_area_get_flags(area)); |
page_mapping_insert(AS, addr, base + (addr - area->base), |
as_area_get_flags(area)); |
if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1)) |
panic("Could not insert used space.\n"); |
/branches/rcu/kernel/generic/src/mm/frame.c |
---|
70,16 → 70,19 |
typedef struct { |
count_t refcount; /**< tracking of shared frames */ |
uint8_t buddy_order; /**< buddy system block order */ |
link_t buddy_link; /**< link to the next free block inside one order */ |
link_t buddy_link; /**< link to the next free block inside one |
order */ |
void *parent; /**< If allocated by slab, this points there */ |
} frame_t; |
typedef struct { |
SPINLOCK_DECLARE(lock); /**< this lock protects everything below */ |
pfn_t base; /**< frame_no of the first frame in the frames array */ |
pfn_t base; /**< frame_no of the first frame in the frames |
array */ |
count_t count; /**< Size of zone */ |
frame_t *frames; /**< array of frame_t structures in this zone */ |
frame_t *frames; /**< array of frame_t structures in this |
zone */ |
count_t free_count; /**< number of free frame_t structures */ |
count_t busy_count; /**< number of busy frame_t structures */ |
157,8 → 160,8 |
for (i = 0; i < zones.count; i++) { |
/* Check for overflow */ |
z = zones.info[i]; |
if (overlaps(newzone->base,newzone->count, |
z->base, z->count)) { |
if (overlaps(newzone->base,newzone->count, z->base, |
z->count)) { |
printf("Zones overlap!\n"); |
return -1; |
} |
202,7 → 205,8 |
z = zones.info[i]; |
spinlock_lock(&z->lock); |
if (z->base <= frame && z->base + z->count > frame) { |
spinlock_unlock(&zones.lock); /* Unlock the global lock */ |
/* Unlock the global lock */ |
spinlock_unlock(&zones.lock); |
if (pzone) |
*pzone = i; |
return z; |
229,7 → 233,8 |
* Assume interrupts are disabled. |
* |
* @param order Size (2^order) of free space we are trying to find |
* @param pzone Pointer to preferred zone or NULL, on return contains zone number |
* @param pzone Pointer to preferred zone or NULL, on return contains zone |
* number |
*/ |
static zone_t * find_free_zone_and_lock(uint8_t order, unsigned int *pzone) |
{ |
319,7 → 324,8 |
frame = list_get_instance(block, frame_t, buddy_link); |
zone = (zone_t *) b->data; |
ASSERT(IS_BUDDY_ORDER_OK(frame_index_abs(zone, frame), frame->buddy_order)); |
ASSERT(IS_BUDDY_ORDER_OK(frame_index_abs(zone, frame), |
frame->buddy_order)); |
is_left = IS_BUDDY_LEFT_BLOCK_ABS(zone, frame); |
is_right = IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame); |
382,7 → 388,8 |
* @param block Buddy system block |
* @param order Order to set |
*/ |
static void zone_buddy_set_order(buddy_system_t *b, link_t * block, uint8_t order) { |
static void zone_buddy_set_order(buddy_system_t *b, link_t *block, |
uint8_t order) { |
frame_t * frame; |
frame = list_get_instance(block, frame_t, buddy_link); |
frame->buddy_order = order; |
560,10 → 567,10 |
z->buddy_system = (buddy_system_t *)&z[1]; |
buddy_system_create(z->buddy_system, max_order, |
&zone_buddy_system_operations, |
(void *) z); |
&zone_buddy_system_operations, (void *) z); |
z->frames = (frame_t *)((uint8_t *) z->buddy_system + buddy_conf_size(max_order)); |
z->frames = (frame_t *)((uint8_t *) z->buddy_system + |
buddy_conf_size(max_order)); |
for (i = 0; i < z->count; i++) { |
/* This marks all frames busy */ |
frame_initialize(&z->frames[i]); |
710,7 → 717,8 |
spinlock_lock(&zone1->lock); |
spinlock_lock(&zone2->lock); |
cframes = SIZE2FRAMES(zone_conf_size(zone2->base+zone2->count-zone1->base)); |
cframes = SIZE2FRAMES(zone_conf_size(zone2->base + zone2->count - |
zone1->base)); |
if (cframes == 1) |
order = 0; |
else |
803,7 → 811,8 |
/* Allocate frames _after_ the conframe */ |
/* Check sizes */ |
z->frames = (frame_t *)((uint8_t *) z->buddy_system + buddy_conf_size(max_order)); |
z->frames = (frame_t *)((uint8_t *) z->buddy_system + |
buddy_conf_size(max_order)); |
for (i = 0; i < count; i++) { |
frame_initialize(&z->frames[i]); |
} |
865,16 → 874,20 |
if (confframe >= start && confframe < start+count) { |
for (;confframe < start + count; confframe++) { |
addr = PFN2ADDR(confframe); |
if (overlaps(addr, PFN2ADDR(confcount), KA2PA(config.base), config.kernel_size)) |
if (overlaps(addr, PFN2ADDR(confcount), |
KA2PA(config.base), config.kernel_size)) |
continue; |
if (overlaps(addr, PFN2ADDR(confcount), KA2PA(config.stack_base), config.stack_size)) |
if (overlaps(addr, PFN2ADDR(confcount), |
KA2PA(config.stack_base), config.stack_size)) |
continue; |
bool overlap = false; |
count_t i; |
for (i = 0; i < init.cnt; i++) |
if (overlaps(addr, PFN2ADDR(confcount), KA2PA(init.tasks[i].addr), init.tasks[i].size)) { |
if (overlaps(addr, PFN2ADDR(confcount), |
KA2PA(init.tasks[i].addr), |
init.tasks[i].size)) { |
overlap = true; |
break; |
} |
1073,15 → 1086,21 |
/* Tell the architecture to create some memory */ |
frame_arch_init(); |
if (config.cpu_active == 1) { |
frame_mark_unavailable(ADDR2PFN(KA2PA(config.base)), SIZE2FRAMES(config.kernel_size)); |
frame_mark_unavailable(ADDR2PFN(KA2PA(config.stack_base)), SIZE2FRAMES(config.stack_size)); |
frame_mark_unavailable(ADDR2PFN(KA2PA(config.base)), |
SIZE2FRAMES(config.kernel_size)); |
frame_mark_unavailable(ADDR2PFN(KA2PA(config.stack_base)), |
SIZE2FRAMES(config.stack_size)); |
count_t i; |
for (i = 0; i < init.cnt; i++) |
frame_mark_unavailable(ADDR2PFN(KA2PA(init.tasks[i].addr)), SIZE2FRAMES(init.tasks[i].size)); |
for (i = 0; i < init.cnt; i++) { |
pfn_t pfn = ADDR2PFN(KA2PA(init.tasks[i].addr)); |
frame_mark_unavailable(pfn, |
SIZE2FRAMES(init.tasks[i].size)); |
} |
if (ballocs.size) |
frame_mark_unavailable(ADDR2PFN(KA2PA(ballocs.base)), SIZE2FRAMES(ballocs.size)); |
frame_mark_unavailable(ADDR2PFN(KA2PA(ballocs.base)), |
SIZE2FRAMES(ballocs.size)); |
/* Black list first frame, as allocating NULL would |
* fail in some places */ |
1106,7 → 1125,8 |
for (i = 0; i < zones.count; i++) { |
zone = zones.info[i]; |
spinlock_lock(&zone->lock); |
printf("%-2d %12p %12zd %12zd\n", i, PFN2ADDR(zone->base), zone->free_count, zone->busy_count); |
printf("%-2d %12p %12zd %12zd\n", i, PFN2ADDR(zone->base), |
zone->free_count, zone->busy_count); |
spinlock_unlock(&zone->lock); |
} |
spinlock_unlock(&zones.lock); |
1138,10 → 1158,14 |
spinlock_lock(&zone->lock); |
printf("Memory zone information\n"); |
printf("Zone base address: %#.*p\n", sizeof(uintptr_t) * 2, PFN2ADDR(zone->base)); |
printf("Zone size: %zd frames (%zdK)\n", zone->count, ((zone->count) * FRAME_SIZE) >> 10); |
printf("Allocated space: %zd frames (%zdK)\n", zone->busy_count, (zone->busy_count * FRAME_SIZE) >> 10); |
printf("Available space: %zd frames (%zdK)\n", zone->free_count, (zone->free_count * FRAME_SIZE) >> 10); |
printf("Zone base address: %#.*p\n", sizeof(uintptr_t) * 2, |
PFN2ADDR(zone->base)); |
printf("Zone size: %zd frames (%zdK)\n", zone->count, |
((zone->count) * FRAME_SIZE) >> 10); |
printf("Allocated space: %zd frames (%zdK)\n", zone->busy_count, |
(zone->busy_count * FRAME_SIZE) >> 10); |
printf("Available space: %zd frames (%zdK)\n", zone->free_count, |
(zone->free_count * FRAME_SIZE) >> 10); |
buddy_system_structure_print(zone->buddy_system, FRAME_SIZE); |
spinlock_unlock(&zone->lock); |
1152,3 → 1176,4 |
/** @} |
*/ |
/branches/rcu/kernel/generic/src/mm/backend_elf.c |
---|
71,7 → 71,8 |
* @param addr Faulting virtual address. |
* @param access Access mode that caused the fault (i.e. read/write/exec). |
* |
* @return AS_PF_FAULT on failure (i.e. page fault) or AS_PF_OK on success (i.e. serviced). |
* @return AS_PF_FAULT on failure (i.e. page fault) or AS_PF_OK on success (i.e. |
* serviced). |
*/ |
int elf_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access) |
{ |
80,11 → 81,13 |
btree_node_t *leaf; |
uintptr_t base, frame; |
index_t i; |
bool dirty = false; |
if (!as_area_check_access(area, access)) |
return AS_PF_FAULT; |
ASSERT((addr >= entry->p_vaddr) && (addr < entry->p_vaddr + entry->p_memsz)); |
ASSERT((addr >= entry->p_vaddr) && |
(addr < entry->p_vaddr + entry->p_memsz)); |
i = (addr - entry->p_vaddr) >> PAGE_WIDTH; |
base = (uintptr_t) (((void *) elf) + entry->p_offset); |
ASSERT(ALIGN_UP(base, FRAME_SIZE) == base); |
107,7 → 110,8 |
*/ |
for (i = 0; i < leaf->keys; i++) { |
if (leaf->key[i] == ALIGN_DOWN(addr, PAGE_SIZE)) { |
if (leaf->key[i] == |
ALIGN_DOWN(addr, PAGE_SIZE)) { |
found = true; |
break; |
} |
115,8 → 119,10 |
} |
if (frame || found) { |
frame_reference_add(ADDR2PFN(frame)); |
page_mapping_insert(AS, addr, frame, as_area_get_flags(area)); |
if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1)) |
page_mapping_insert(AS, addr, frame, |
as_area_get_flags(area)); |
if (!used_space_insert(area, |
ALIGN_DOWN(addr, PAGE_SIZE), 1)) |
panic("Could not insert used space.\n"); |
mutex_unlock(&area->sh_info->lock); |
return AS_PF_OK; |
124,10 → 130,12 |
} |
/* |
* The area is either not shared or the pagemap does not contain the mapping. |
* The area is either not shared or the pagemap does not contain the |
* mapping. |
*/ |
if (ALIGN_DOWN(addr, PAGE_SIZE) + PAGE_SIZE < entry->p_vaddr + entry->p_filesz) { |
if (ALIGN_DOWN(addr, PAGE_SIZE) + PAGE_SIZE < |
entry->p_vaddr + entry->p_filesz) { |
/* |
* Initialized portion of the segment. The memory is backed |
* directly by the content of the ELF image. Pages are |
138,11 → 146,14 |
*/ |
if (entry->p_flags & PF_W) { |
frame = (uintptr_t)frame_alloc(ONE_FRAME, 0); |
memcpy((void *) PA2KA(frame), (void *) (base + i*FRAME_SIZE), FRAME_SIZE); |
memcpy((void *) PA2KA(frame), |
(void *) (base + i * FRAME_SIZE), FRAME_SIZE); |
dirty = true; |
if (area->sh_info) { |
frame_reference_add(ADDR2PFN(frame)); |
btree_insert(&area->sh_info->pagemap, ALIGN_DOWN(addr, PAGE_SIZE) - area->base, |
btree_insert(&area->sh_info->pagemap, |
ALIGN_DOWN(addr, PAGE_SIZE) - area->base, |
(void *) frame, leaf); |
} |
149,7 → 160,8 |
} else { |
frame = KA2PA(base + i*FRAME_SIZE); |
} |
} else if (ALIGN_DOWN(addr, PAGE_SIZE) >= ALIGN_UP(entry->p_vaddr + entry->p_filesz, PAGE_SIZE)) { |
} else if (ALIGN_DOWN(addr, PAGE_SIZE) >= |
ALIGN_UP(entry->p_vaddr + entry->p_filesz, PAGE_SIZE)) { |
/* |
* This is the uninitialized portion of the segment. |
* It is not physically present in the ELF image. |
158,10 → 170,12 |
*/ |
frame = (uintptr_t)frame_alloc(ONE_FRAME, 0); |
memsetb(PA2KA(frame), FRAME_SIZE, 0); |
dirty = true; |
if (area->sh_info) { |
frame_reference_add(ADDR2PFN(frame)); |
btree_insert(&area->sh_info->pagemap, ALIGN_DOWN(addr, PAGE_SIZE) - area->base, |
btree_insert(&area->sh_info->pagemap, |
ALIGN_DOWN(addr, PAGE_SIZE) - area->base, |
(void *) frame, leaf); |
} |
175,11 → 189,14 |
size = entry->p_filesz - (i<<PAGE_WIDTH); |
frame = (uintptr_t)frame_alloc(ONE_FRAME, 0); |
memsetb(PA2KA(frame) + size, FRAME_SIZE - size, 0); |
memcpy((void *) PA2KA(frame), (void *) (base + i*FRAME_SIZE), size); |
memcpy((void *) PA2KA(frame), (void *) (base + i * FRAME_SIZE), |
size); |
dirty = true; |
if (area->sh_info) { |
frame_reference_add(ADDR2PFN(frame)); |
btree_insert(&area->sh_info->pagemap, ALIGN_DOWN(addr, PAGE_SIZE) - area->base, |
btree_insert(&area->sh_info->pagemap, |
ALIGN_DOWN(addr, PAGE_SIZE) - area->base, |
(void *) frame, leaf); |
} |
211,31 → 228,28 |
uintptr_t base; |
index_t i; |
ASSERT((page >= entry->p_vaddr) && (page < entry->p_vaddr + entry->p_memsz)); |
ASSERT((page >= entry->p_vaddr) && |
(page < entry->p_vaddr + entry->p_memsz)); |
i = (page - entry->p_vaddr) >> PAGE_WIDTH; |
base = (uintptr_t) (((void *) elf) + entry->p_offset); |
ASSERT(ALIGN_UP(base, FRAME_SIZE) == base); |
if (page + PAGE_SIZE < ALIGN_UP(entry->p_vaddr + entry->p_filesz, PAGE_SIZE)) { |
if (page + PAGE_SIZE < |
ALIGN_UP(entry->p_vaddr + entry->p_filesz, PAGE_SIZE)) { |
if (entry->p_flags & PF_W) { |
/* |
* Free the frame with the copy of writable segment data. |
* Free the frame with the copy of writable segment |
* data. |
*/ |
frame_free(frame); |
#ifdef CONFIG_VIRT_IDX_DCACHE |
dcache_flush_frame(page, frame); |
#endif |
} |
} else { |
/* |
* The frame is either anonymous memory or the mixed case (i.e. lower |
* part is backed by the ELF image and the upper is anonymous). |
* In any case, a frame needs to be freed. |
* The frame is either anonymous memory or the mixed case (i.e. |
* lower part is backed by the ELF image and the upper is |
* anonymous). In any case, a frame needs to be freed. |
*/ |
frame_free(frame); |
#ifdef CONFIG_VIRT_IDX_DCACHE |
dcache_flush_frame(page, frame); |
#endif |
} |
} |
260,10 → 274,12 |
* Find the node in which to start linear search. |
*/ |
if (area->flags & AS_AREA_WRITE) { |
node = list_get_instance(area->used_space.leaf_head.next, btree_node_t, leaf_link); |
node = list_get_instance(area->used_space.leaf_head.next, |
btree_node_t, leaf_link); |
} else { |
(void) btree_search(&area->sh_info->pagemap, start_anon, &leaf); |
node = btree_leaf_node_left_neighbour(&area->sh_info->pagemap, leaf); |
node = btree_leaf_node_left_neighbour(&area->sh_info->pagemap, |
leaf); |
if (!node) |
node = leaf; |
} |
272,7 → 288,8 |
* Copy used anonymous portions of the area to sh_info's page map. |
*/ |
mutex_lock(&area->sh_info->lock); |
for (cur = &node->leaf_link; cur != &area->used_space.leaf_head; cur = cur->next) { |
for (cur = &node->leaf_link; cur != &area->used_space.leaf_head; |
cur = cur->next) { |
int i; |
node = list_get_instance(cur, btree_node_t, leaf_link); |
294,19 → 311,26 |
pte_t *pte; |
/* |
* Skip read-only pages that are backed by the ELF image. |
* Skip read-only pages that are backed by the |
* ELF image. |
*/ |
if (!(area->flags & AS_AREA_WRITE)) |
if (base + (j + 1)*PAGE_SIZE <= start_anon) |
if (base + (j + 1) * PAGE_SIZE <= |
start_anon) |
continue; |
page_table_lock(area->as, false); |
pte = page_mapping_find(area->as, base + j*PAGE_SIZE); |
ASSERT(pte && PTE_VALID(pte) && PTE_PRESENT(pte)); |
btree_insert(&area->sh_info->pagemap, (base + j*PAGE_SIZE) - area->base, |
pte = page_mapping_find(area->as, |
base + j * PAGE_SIZE); |
ASSERT(pte && PTE_VALID(pte) && |
PTE_PRESENT(pte)); |
btree_insert(&area->sh_info->pagemap, |
(base + j * PAGE_SIZE) - area->base, |
(void *) PTE_GET_FRAME(pte), NULL); |
page_table_unlock(area->as, false); |
frame_reference_add(ADDR2PFN(PTE_GET_FRAME(pte))); |
pfn_t pfn = ADDR2PFN(PTE_GET_FRAME(pte)); |
frame_reference_add(pfn); |
} |
} |
/branches/rcu/kernel/Makefile |
---|
95,10 → 95,6 |
DEFS += -DCONFIG_VIRT_IDX_DCACHE |
endif |
ifeq ($(CONFIG_POWEROFF),y) |
DEFS += -DCONFIG_POWEROFF |
endif |
ifeq ($(CONFIG_FB),y) |
ifeq ($(ARCH),ia32) |
DEFS += -DCONFIG_VESA_WIDTH=$(CONFIG_VESA_WIDTH) |
/branches/rcu/kernel/arch/sparc64/include/mm/frame.h |
---|
35,7 → 35,20 |
#ifndef KERN_sparc64_FRAME_H_ |
#define KERN_sparc64_FRAME_H_ |
#define FRAME_WIDTH 13 /* 8K */ |
/* |
* Page size supported by the MMU. |
* For 8K there is the nasty illegal virtual aliasing problem. |
* Therefore, the kernel uses 8K only internally on the TLB and TSB levels. |
*/ |
#define MMU_FRAME_WIDTH 13 /* 8K */ |
#define MMU_FRAME_SIZE (1 << MMU_FRAME_WIDTH) |
/* |
* Page size exported to the generic memory management subsystems. |
* This page size is not directly supported by the MMU, but we can emulate |
* each 16K page with a pair of adjacent 8K pages. |
*/ |
#define FRAME_WIDTH 14 /* 16K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifdef KERNEL |
/branches/rcu/kernel/arch/sparc64/include/mm/page.h |
---|
37,11 → 37,27 |
#include <arch/mm/frame.h> |
/* |
* On the TLB and TSB level, we still use 8K pages, which are supported by the |
* MMU. |
*/ |
#define MMU_PAGE_WIDTH MMU_FRAME_WIDTH |
#define MMU_PAGE_SIZE MMU_FRAME_SIZE |
/* |
* On the page table level, we use 16K pages. 16K pages are not supported by |
* the MMU but we emulate them with pairs of 8K pages. |
*/ |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_COLOR_BITS 1 /**< 14 - 13; 2^14 == 16K == alias boundary. */ |
#define MMU_PAGES_PER_PAGE (1 << (PAGE_WIDTH - MMU_PAGE_WIDTH)) |
/* |
* With 16K pages, there is only one page color. |
*/ |
#define PAGE_COLOR_BITS 0 /**< 14 - 14; 2^14 == 16K == alias boundary. */ |
#ifdef KERNEL |
#ifndef __ASM__ |
/branches/rcu/kernel/arch/sparc64/include/mm/as.h |
---|
82,7 → 82,8 |
#ifdef CONFIG_TSB |
# include <arch/mm/tsb.h> |
# define as_invalidate_translation_cache(as, page, cnt) tsb_invalidate(as, page, cnt) |
#define as_invalidate_translation_cache(as, page, cnt) \ |
tsb_invalidate((as), (page), (cnt)) |
#else |
# define as_invalidate_translation_cache(as, page, cnt) |
#endif |
/branches/rcu/kernel/arch/sparc64/include/mm/tsb.h |
---|
112,8 → 112,8 |
struct pte; |
extern void tsb_invalidate(struct as *as, uintptr_t page, count_t pages); |
extern void itsb_pte_copy(struct pte *t); |
extern void dtsb_pte_copy(struct pte *t, bool ro); |
extern void itsb_pte_copy(struct pte *t, index_t index); |
extern void dtsb_pte_copy(struct pte *t, index_t index, bool ro); |
#endif /* !def __ASM__ */ |
/branches/rcu/kernel/arch/sparc64/include/cpu.h |
---|
39,6 → 39,10 |
#include <arch/register.h> |
#include <arch/asm.h> |
#ifdef CONFIG_SMP |
#include <arch/mm/cache.h> |
#endif |
#define MANUF_FUJITSU 0x04 |
#define MANUF_ULTRASPARC 0x17 /**< UltraSPARC I, UltraSPARC II */ |
#define MANUF_SUN 0x3e |
53,7 → 57,8 |
#define IMPL_SPARC64V 0x5 |
typedef struct { |
uint32_t mid; /**< Processor ID as read from UPA_CONFIG. */ |
uint32_t mid; /**< Processor ID as read from |
UPA_CONFIG. */ |
ver_reg_t ver; |
uint32_t clock_frequency; /**< Processor frequency in Hz. */ |
uint64_t next_tick_cmpr; /**< Next clock interrupt should be |
/branches/rcu/kernel/arch/sparc64/Makefile.inc |
---|
83,8 → 83,7 |
arch/$(ARCH)/src/fpu_context.c \ |
arch/$(ARCH)/src/dummy.s \ |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/mm/cache.c \ |
arch/$(ARCH)/src/mm/cache_asm.S \ |
arch/$(ARCH)/src/mm/cache.S \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/page.c \ |
arch/$(ARCH)/src/mm/tlb.c \ |
/branches/rcu/kernel/arch/sparc64/src/smp/ipi.c |
---|
78,9 → 78,9 |
func); |
asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_1, 0); |
asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_2, 0); |
asi_u64_write(ASI_UDB_INTR_W, (mid << |
INTR_VEC_DISPATCH_MID_SHIFT) | ASI_UDB_INTR_W_DISPATCH, |
0); |
asi_u64_write(ASI_UDB_INTR_W, |
(mid << INTR_VEC_DISPATCH_MID_SHIFT) | |
ASI_UDB_INTR_W_DISPATCH, 0); |
membar(); |
/branches/rcu/kernel/arch/sparc64/src/trap/interrupt.c |
---|
83,9 → 83,9 |
} else if (data0 > config.base) { |
/* |
* This is a cross-call. |
* data0 contains address of kernel function. |
* data0 contains address of the kernel function. |
* We call the function only after we verify |
* it is on of the supported ones. |
* it is one of the supported ones. |
*/ |
#ifdef CONFIG_SMP |
if (data0 == (uintptr_t) tlb_shootdown_ipi_recv) { |
/branches/rcu/kernel/arch/sparc64/src/mm/tlb.c |
---|
54,10 → 54,10 |
#include <arch/mm/tsb.h> |
#endif |
static void dtlb_pte_copy(pte_t *t, bool ro); |
static void itlb_pte_copy(pte_t *t); |
static void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, const |
char *str); |
static void dtlb_pte_copy(pte_t *t, index_t index, bool ro); |
static void itlb_pte_copy(pte_t *t, index_t index); |
static void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, |
const char *str); |
static void do_fast_data_access_mmu_miss_fault(istate_t *istate, |
tlb_tag_access_reg_t tag, const char *str); |
static void do_fast_data_access_protection_fault(istate_t *istate, |
92,8 → 92,8 |
* @param locked True for permanent mappings, false otherwise. |
* @param cacheable True if the mapping is cacheable, false otherwise. |
*/ |
void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, bool |
locked, bool cacheable) |
void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, |
bool locked, bool cacheable) |
{ |
tlb_tag_access_reg_t tag; |
tlb_data_t data; |
127,10 → 127,11 |
/** Copy PTE to TLB. |
* |
* @param t Page Table Entry to be copied. |
* @param ro If true, the entry will be created read-only, regardless of its w |
* field. |
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage. |
* @param ro If true, the entry will be created read-only, regardless of its |
* w field. |
*/ |
void dtlb_pte_copy(pte_t *t, bool ro) |
void dtlb_pte_copy(pte_t *t, index_t index, bool ro) |
{ |
tlb_tag_access_reg_t tag; |
tlb_data_t data; |
137,8 → 138,8 |
page_address_t pg; |
frame_address_t fr; |
pg.address = t->page; |
fr.address = t->frame; |
pg.address = t->page + (index << MMU_PAGE_WIDTH); |
fr.address = t->frame + (index << MMU_PAGE_WIDTH); |
tag.value = 0; |
tag.context = t->as->asid; |
165,8 → 166,9 |
/** Copy PTE to ITLB. |
* |
* @param t Page Table Entry to be copied. |
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage. |
*/ |
void itlb_pte_copy(pte_t *t) |
void itlb_pte_copy(pte_t *t, index_t index) |
{ |
tlb_tag_access_reg_t tag; |
tlb_data_t data; |
173,8 → 175,8 |
page_address_t pg; |
frame_address_t fr; |
pg.address = t->page; |
fr.address = t->frame; |
pg.address = t->page + (index << MMU_PAGE_WIDTH); |
fr.address = t->frame + (index << MMU_PAGE_WIDTH); |
tag.value = 0; |
tag.context = t->as->asid; |
199,6 → 201,7 |
void fast_instruction_access_mmu_miss(int n, istate_t *istate) |
{ |
uintptr_t va = ALIGN_DOWN(istate->tpc, PAGE_SIZE); |
index_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE; |
pte_t *t; |
page_table_lock(AS, true); |
209,9 → 212,9 |
* Insert it into ITLB. |
*/ |
t->a = true; |
itlb_pte_copy(t); |
itlb_pte_copy(t, index); |
#ifdef CONFIG_TSB |
itsb_pte_copy(t); |
itsb_pte_copy(t, index); |
#endif |
page_table_unlock(AS, true); |
} else { |
236,10 → 239,12 |
{ |
tlb_tag_access_reg_t tag; |
uintptr_t va; |
index_t index; |
pte_t *t; |
tag.value = dtlb_tag_access_read(); |
va = tag.vpn << PAGE_WIDTH; |
va = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE); |
index = tag.vpn % MMU_PAGES_PER_PAGE; |
if (tag.context == ASID_KERNEL) { |
if (!tag.vpn) { |
259,14 → 264,15 |
* Insert it into DTLB. |
*/ |
t->a = true; |
dtlb_pte_copy(t, true); |
dtlb_pte_copy(t, index, true); |
#ifdef CONFIG_TSB |
dtsb_pte_copy(t, true); |
dtsb_pte_copy(t, index, true); |
#endif |
page_table_unlock(AS, true); |
} else { |
/* |
* Forward the page fault to the address space page fault handler. |
* Forward the page fault to the address space page fault |
* handler. |
*/ |
page_table_unlock(AS, true); |
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) { |
281,10 → 287,12 |
{ |
tlb_tag_access_reg_t tag; |
uintptr_t va; |
index_t index; |
pte_t *t; |
tag.value = dtlb_tag_access_read(); |
va = tag.vpn << PAGE_WIDTH; |
va = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE); |
index = tag.vpn % MMU_PAGES_PER_PAGE; /* 16K-page emulation */ |
page_table_lock(AS, true); |
t = page_mapping_find(AS, va); |
296,10 → 304,11 |
*/ |
t->a = true; |
t->d = true; |
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY, va); |
dtlb_pte_copy(t, false); |
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY, |
va + index * MMU_PAGE_SIZE); |
dtlb_pte_copy(t, index, false); |
#ifdef CONFIG_TSB |
dtsb_pte_copy(t, false); |
dtsb_pte_copy(t, index, false); |
#endif |
page_table_unlock(AS, true); |
} else { |
348,8 → 357,8 |
} |
void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, const char |
*str) |
void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, |
const char *str) |
{ |
fault_if_from_uspace(istate, "%s\n", str); |
dump_istate(istate); |
356,12 → 365,12 |
panic("%s\n", str); |
} |
void do_fast_data_access_mmu_miss_fault(istate_t *istate, tlb_tag_access_reg_t |
tag, const char *str) |
void do_fast_data_access_mmu_miss_fault(istate_t *istate, |
tlb_tag_access_reg_t tag, const char *str) |
{ |
uintptr_t va; |
va = tag.vpn << PAGE_WIDTH; |
va = tag.vpn << MMU_PAGE_WIDTH; |
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d)\n", str, va, |
tag.context); |
370,12 → 379,12 |
panic("%s\n", str); |
} |
void do_fast_data_access_protection_fault(istate_t *istate, tlb_tag_access_reg_t |
tag, const char *str) |
void do_fast_data_access_protection_fault(istate_t *istate, |
tlb_tag_access_reg_t tag, const char *str) |
{ |
uintptr_t va; |
va = tag.vpn << PAGE_WIDTH; |
va = tag.vpn << MMU_PAGE_WIDTH; |
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d)\n", str, va, |
tag.context); |
481,11 → 490,11 |
ctx.context = asid; |
mmu_primary_context_write(ctx.v); |
for (i = 0; i < cnt; i++) { |
itlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_PRIMARY, page + i * |
PAGE_SIZE); |
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_PRIMARY, page + i * |
PAGE_SIZE); |
for (i = 0; i < cnt * MMU_PAGES_PER_PAGE; i++) { |
itlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_PRIMARY, |
page + i * MMU_PAGE_SIZE); |
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_PRIMARY, |
page + i * MMU_PAGE_SIZE); |
} |
mmu_primary_context_write(pc_save.v); |
/branches/rcu/kernel/arch/sparc64/src/mm/as.c |
---|
42,7 → 42,6 |
#ifdef CONFIG_TSB |
#include <arch/mm/tsb.h> |
#include <arch/memstr.h> |
#include <synch/mutex.h> |
#include <arch/asm.h> |
#include <mm/frame.h> |
#include <bitops.h> |
61,6 → 60,10 |
int as_constructor_arch(as_t *as, int flags) |
{ |
#ifdef CONFIG_TSB |
/* |
* The order must be calculated with respect to the emulated |
* 16K page size. |
*/ |
int order = fnzb32(((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) * |
sizeof(tsb_entry_t)) >> FRAME_WIDTH); |
uintptr_t tsb = (uintptr_t) frame_alloc(order, flags | FRAME_KA); |
71,8 → 74,8 |
as->arch.itsb = (tsb_entry_t *) tsb; |
as->arch.dtsb = (tsb_entry_t *) (tsb + ITSB_ENTRY_COUNT * |
sizeof(tsb_entry_t)); |
memsetb((uintptr_t) as->arch.itsb, (ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) |
* sizeof(tsb_entry_t), 0); |
memsetb((uintptr_t) as->arch.itsb, |
(ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) * sizeof(tsb_entry_t), 0); |
#endif |
return 0; |
} |
80,6 → 83,10 |
int as_destructor_arch(as_t *as) |
{ |
#ifdef CONFIG_TSB |
/* |
* The count must be calculated with respect to the emualted 16K page |
* size. |
*/ |
count_t cnt = ((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) * |
sizeof(tsb_entry_t)) >> FRAME_WIDTH; |
frame_free(KA2PA((uintptr_t) as->arch.itsb)); |
92,13 → 99,7 |
int as_create_arch(as_t *as, int flags) |
{ |
#ifdef CONFIG_TSB |
ipl_t ipl; |
ipl = interrupts_disable(); |
mutex_lock_active(&as->lock); /* completely unnecessary, but polite */ |
tsb_invalidate(as, 0, (count_t) -1); |
mutex_unlock(&as->lock); |
interrupts_restore(ipl); |
#endif |
return 0; |
} |
115,18 → 116,17 |
tlb_context_reg_t ctx; |
/* |
* Note that we don't lock the address space. |
* That's correct - we can afford it here |
* because we only read members that are |
* currently read-only. |
* Note that we don't and may not lock the address space. That's ok |
* since we only read members that are currently read-only. |
* |
* Moreover, the as->asid is protected by asidlock, which is being held. |
*/ |
/* |
* Write ASID to secondary context register. |
* The primary context register has to be set |
* from TL>0 so it will be filled from the |
* secondary context register from the TL=1 |
* code just before switch to userspace. |
* Write ASID to secondary context register. The primary context |
* register has to be set from TL>0 so it will be filled from the |
* secondary context register from the TL=1 code just before switch to |
* userspace. |
*/ |
ctx.v = 0; |
ctx.context = as->asid; |
139,7 → 139,7 |
uintptr_t tsb = (uintptr_t) as->arch.itsb; |
if (!overlaps(tsb, 8 * PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) { |
if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) { |
/* |
* TSBs were allocated from memory not covered |
* by the locked 4M kernel DTLB entry. We need |
158,9 → 158,9 |
tsb_base.size = TSB_SIZE; |
tsb_base.split = 0; |
tsb_base.base = ((uintptr_t) as->arch.itsb) >> PAGE_WIDTH; |
tsb_base.base = ((uintptr_t) as->arch.itsb) >> MMU_PAGE_WIDTH; |
itsb_base_write(tsb_base.value); |
tsb_base.base = ((uintptr_t) as->arch.dtsb) >> PAGE_WIDTH; |
tsb_base.base = ((uintptr_t) as->arch.dtsb) >> MMU_PAGE_WIDTH; |
dtsb_base_write(tsb_base.value); |
#endif |
} |
176,10 → 176,10 |
{ |
/* |
* Note that we don't lock the address space. |
* That's correct - we can afford it here |
* because we only read members that are |
* currently read-only. |
* Note that we don't and may not lock the address space. That's ok |
* since we only read members that are currently read-only. |
* |
* Moreover, the as->asid is protected by asidlock, which is being held. |
*/ |
#ifdef CONFIG_TSB |
189,7 → 189,7 |
uintptr_t tsb = (uintptr_t) as->arch.itsb; |
if (!overlaps(tsb, 8 * PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) { |
if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) { |
/* |
* TSBs were allocated from memory not covered |
* by the locked 4M kernel DTLB entry. We need |
/branches/rcu/kernel/arch/sparc64/src/mm/tsb.c |
---|
34,6 → 34,7 |
#include <arch/mm/tsb.h> |
#include <arch/mm/tlb.h> |
#include <arch/mm/page.h> |
#include <arch/barrier.h> |
#include <mm/as.h> |
#include <arch/types.h> |
40,7 → 41,7 |
#include <macros.h> |
#include <debug.h> |
#define TSB_INDEX_MASK ((1 << (21 + 1 + TSB_SIZE - PAGE_WIDTH)) - 1) |
#define TSB_INDEX_MASK ((1 << (21 + 1 + TSB_SIZE - MMU_PAGE_WIDTH)) - 1) |
/** Invalidate portion of TSB. |
* |
59,8 → 60,11 |
ASSERT(as->arch.itsb && as->arch.dtsb); |
i0 = (page >> PAGE_WIDTH) & TSB_INDEX_MASK; |
cnt = min(pages, ITSB_ENTRY_COUNT); |
i0 = (page >> MMU_PAGE_WIDTH) & TSB_INDEX_MASK; |
if (pages == (count_t) -1 || (pages * 2) > ITSB_ENTRY_COUNT) |
cnt = ITSB_ENTRY_COUNT; |
else |
cnt = pages * 2; |
for (i = 0; i < cnt; i++) { |
as->arch.itsb[(i0 + i) & (ITSB_ENTRY_COUNT - 1)].tag.invalid = |
73,14 → 77,17 |
/** Copy software PTE to ITSB. |
* |
* @param t Software PTE. |
* @param index Zero if lower 8K-subpage, one if higher 8K subpage. |
*/ |
void itsb_pte_copy(pte_t *t) |
void itsb_pte_copy(pte_t *t, index_t index) |
{ |
as_t *as; |
tsb_entry_t *tsb; |
index_t entry; |
as = t->as; |
tsb = &as->arch.itsb[(t->page >> PAGE_WIDTH) & TSB_INDEX_MASK]; |
entry = ((t->page >> MMU_PAGE_WIDTH) + index) & TSB_INDEX_MASK; |
tsb = &as->arch.itsb[entry]; |
/* |
* We use write barriers to make sure that the TSB load |
95,10 → 102,11 |
write_barrier(); |
tsb->tag.context = as->asid; |
tsb->tag.va_tag = t->page >> VA_TAG_PAGE_SHIFT; |
tsb->tag.va_tag = (t->page + (index << MMU_PAGE_WIDTH)) >> |
VA_TAG_PAGE_SHIFT; |
tsb->data.value = 0; |
tsb->data.size = PAGESIZE_8K; |
tsb->data.pfn = t->frame >> FRAME_WIDTH; |
tsb->data.pfn = (t->frame >> MMU_FRAME_WIDTH) + index; |
tsb->data.cp = t->c; |
tsb->data.p = t->k; /* p as privileged */ |
tsb->data.v = t->p; |
111,15 → 119,18 |
/** Copy software PTE to DTSB. |
* |
* @param t Software PTE. |
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage. |
* @param ro If true, the mapping is copied read-only. |
*/ |
void dtsb_pte_copy(pte_t *t, bool ro) |
void dtsb_pte_copy(pte_t *t, index_t index, bool ro) |
{ |
as_t *as; |
tsb_entry_t *tsb; |
index_t entry; |
as = t->as; |
tsb = &as->arch.dtsb[(t->page >> PAGE_WIDTH) & TSB_INDEX_MASK]; |
entry = ((t->page >> MMU_PAGE_WIDTH) + index) & TSB_INDEX_MASK; |
tsb = &as->arch.dtsb[entry]; |
/* |
* We use write barriers to make sure that the TSB load |
134,10 → 145,11 |
write_barrier(); |
tsb->tag.context = as->asid; |
tsb->tag.va_tag = t->page >> VA_TAG_PAGE_SHIFT; |
tsb->tag.va_tag = (t->page + (index << MMU_PAGE_WIDTH)) >> |
VA_TAG_PAGE_SHIFT; |
tsb->data.value = 0; |
tsb->data.size = PAGESIZE_8K; |
tsb->data.pfn = t->frame >> FRAME_WIDTH; |
tsb->data.pfn = (t->frame >> MMU_FRAME_WIDTH) + index; |
tsb->data.cp = t->c; |
#ifdef CONFIG_VIRT_IDX_DCACHE |
tsb->data.cv = t->c; |
148,7 → 160,7 |
write_barrier(); |
tsb->tag.invalid = true; /* mark the entry as valid */ |
tsb->tag.invalid = false; /* mark the entry as valid */ |
} |
/** @} |
/branches/rcu/kernel/arch/sparc64/src/mm/page.c |
---|
108,25 → 108,25 |
count_t count; |
} sizemap[] = { |
{ PAGESIZE_8K, 0, 1 }, /* 8K */ |
{ PAGESIZE_8K, PAGE_SIZE, 2 }, /* 16K */ |
{ PAGESIZE_8K, PAGE_SIZE, 4 }, /* 32K */ |
{ PAGESIZE_8K, MMU_PAGE_SIZE, 2 }, /* 16K */ |
{ PAGESIZE_8K, MMU_PAGE_SIZE, 4 }, /* 32K */ |
{ PAGESIZE_64K, 0, 1}, /* 64K */ |
{ PAGESIZE_64K, 8 * PAGE_SIZE, 2 }, /* 128K */ |
{ PAGESIZE_64K, 8 * PAGE_SIZE, 4 }, /* 256K */ |
{ PAGESIZE_64K, 8 * MMU_PAGE_SIZE, 2 }, /* 128K */ |
{ PAGESIZE_64K, 8 * MMU_PAGE_SIZE, 4 }, /* 256K */ |
{ PAGESIZE_512K, 0, 1 }, /* 512K */ |
{ PAGESIZE_512K, 64 * PAGE_SIZE, 2 }, /* 1M */ |
{ PAGESIZE_512K, 64 * PAGE_SIZE, 4 }, /* 2M */ |
{ PAGESIZE_512K, 64 * MMU_PAGE_SIZE, 2 }, /* 1M */ |
{ PAGESIZE_512K, 64 * MMU_PAGE_SIZE, 4 }, /* 2M */ |
{ PAGESIZE_4M, 0, 1 }, /* 4M */ |
{ PAGESIZE_4M, 512 * PAGE_SIZE, 2 } /* 8M */ |
{ PAGESIZE_4M, 512 * MMU_PAGE_SIZE, 2 } /* 8M */ |
}; |
ASSERT(ALIGN_UP(physaddr, PAGE_SIZE) == physaddr); |
ASSERT(ALIGN_UP(physaddr, MMU_PAGE_SIZE) == physaddr); |
ASSERT(size <= 8 * 1024 * 1024); |
if (size <= FRAME_SIZE) |
if (size <= MMU_FRAME_SIZE) |
order = 0; |
else |
order = (fnzb64(size - 1) + 1) - FRAME_WIDTH; |
order = (fnzb64(size - 1) + 1) - MMU_FRAME_WIDTH; |
/* |
* Use virtual addresses that are beyond the limit of physical memory. |
134,8 → 134,10 |
* by frame_alloc(). |
*/ |
ASSERT(PA2KA(last_frame)); |
uintptr_t virtaddr = ALIGN_UP(PA2KA(last_frame), 1 << (order + FRAME_WIDTH)); |
last_frame = ALIGN_UP(KA2PA(virtaddr) + size, 1 << (order + FRAME_WIDTH)); |
uintptr_t virtaddr = ALIGN_UP(PA2KA(last_frame), |
1 << (order + FRAME_WIDTH)); |
last_frame = ALIGN_UP(KA2PA(virtaddr) + size, |
1 << (order + FRAME_WIDTH)); |
for (i = 0; i < sizemap[order].count; i++) { |
/* |
/branches/rcu/kernel/arch/ia64/src/mm/as.c |
---|
36,11 → 36,10 |
#include <arch/mm/asid.h> |
#include <arch/mm/page.h> |
#include <genarch/mm/as_ht.h> |
#include <genarch/mm/page_ht.h> |
#include <genarch/mm/asid_fifo.h> |
#include <mm/asid.h> |
#include <arch.h> |
#include <arch/barrier.h> |
#include <synch/spinlock.h> |
/** Architecture dependent address space init. */ |
void as_arch_init(void) |
55,13 → 54,9 |
*/ |
void as_install_arch(as_t *as) |
{ |
ipl_t ipl; |
region_register rr; |
int i; |
ipl = interrupts_disable(); |
spinlock_lock(&as->lock); |
ASSERT(as->asid != ASID_INVALID); |
/* |
80,9 → 75,6 |
} |
srlz_d(); |
srlz_i(); |
spinlock_unlock(&as->lock); |
interrupts_restore(ipl); |
} |
/** @} |
/branches/rcu/kernel/arch/ppc32/src/mm/as.c |
---|
54,12 → 54,8 |
void as_install_arch(as_t *as) |
{ |
asid_t asid; |
ipl_t ipl; |
uint32_t sr; |
ipl = interrupts_disable(); |
spinlock_lock(&as->lock); |
asid = as->asid; |
/* Lower 2 GB, user and supervisor access */ |
79,9 → 75,6 |
: "r" ((0x4000 << 16) + (asid << 4) + sr), "r" (sr << 28) |
); |
} |
spinlock_unlock(&as->lock); |
interrupts_restore(ipl); |
} |
/** @} |
/branches/rcu/kernel/arch/ppc32/src/interrupt.c |
---|
60,19 → 60,11 |
int inum; |
while ((inum = pic_get_pending()) != -1) { |
bool ack = false; |
irq_t *irq = irq_dispatch_and_lock(inum); |
if (irq) { |
/* |
* The IRQ handler was found. |
*/ |
if (irq->preack) { |
/* Acknowledge the interrupt before processing */ |
pic_ack_interrupt(inum); |
ack = true; |
} |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
83,8 → 75,6 |
printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, inum); |
#endif |
} |
if (!ack) |
pic_ack_interrupt(inum); |
} |
} |
/branches/rcu/kernel/arch/ia32xen/src/interrupt.c |
---|
176,7 → 176,6 |
ASSERT(n >= IVT_IRQBASE); |
int inum = n - IVT_IRQBASE; |
bool ack = false; |
ASSERT(inum < IRQ_COUNT); |
ASSERT((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1)); |
185,12 → 184,6 |
/* |
* The IRQ handler was found. |
*/ |
if (irq->preack) { |
/* Send EOI before processing the interrupt */ |
trap_virtual_eoi(); |
ack = true; |
} |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
201,8 → 194,6 |
printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, inum); |
#endif |
} |
if (!ack) |
trap_virtual_eoi(); |
} |
246,4 → 237,3 |
/** @} |
*/ |
/branches/rcu/kernel/arch/amd64/src/interrupt.c |
---|
156,7 → 156,6 |
ASSERT(n >= IVT_IRQBASE); |
int inum = n - IVT_IRQBASE; |
bool ack = false; |
ASSERT(inum < IRQ_COUNT); |
ASSERT((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1)); |
165,12 → 164,6 |
/* |
* The IRQ handler was found. |
*/ |
if (irq->preack) { |
/* Send EOI before processing the interrupt */ |
trap_virtual_eoi(); |
ack = true; |
} |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
181,8 → 174,6 |
printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, inum); |
#endif |
} |
if (!ack) |
trap_virtual_eoi(); |
} |
/branches/rcu/kernel/arch/ppc64/src/interrupt.c |
---|
60,19 → 60,11 |
int inum; |
while ((inum = pic_get_pending()) != -1) { |
bool ack = false; |
irq_t *irq = irq_dispatch_and_lock(inum); |
if (irq) { |
/* |
* The IRQ handler was found. |
*/ |
if (irq->preack) { |
/* Acknowledge the interrupt before processing */ |
pic_ack_interrupt(inum); |
ack = true; |
} |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
83,8 → 75,6 |
printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, inum); |
#endif |
} |
if (!ack) |
pic_ack_interrupt(inum); |
} |
} |
/branches/rcu/kernel/arch/mips32/src/mm/as.c |
---|
34,12 → 34,12 |
#include <arch/mm/as.h> |
#include <genarch/mm/as_pt.h> |
#include <genarch/mm/page_pt.h> |
#include <genarch/mm/asid_fifo.h> |
#include <arch/mm/tlb.h> |
#include <mm/tlb.h> |
#include <mm/as.h> |
#include <arch/cp0.h> |
#include <arch.h> |
/** Architecture dependent address space init. */ |
void as_arch_init(void) |
57,7 → 57,6 |
void as_install_arch(as_t *as) |
{ |
entry_hi_t hi; |
ipl_t ipl; |
/* |
* Install ASID. |
64,12 → 63,8 |
*/ |
hi.value = cp0_entry_hi_read(); |
ipl = interrupts_disable(); |
spinlock_lock(&as->lock); |
hi.asid = as->asid; |
cp0_entry_hi_write(hi.value); |
spinlock_unlock(&as->lock); |
interrupts_restore(ipl); |
} |
/** @} |
/branches/rcu/kernel/arch/ia32/src/smp/apic.c |
---|
139,14 → 139,7 |
static void l_apic_timer_irq_handler(irq_t *irq, void *arg, ...) |
{ |
/* |
* Holding a spinlock could prevent clock() from preempting |
* the current thread. In this case, we don't need to hold the |
* irq->lock so we just unlock it and then lock it again. |
*/ |
spinlock_unlock(&irq->lock); |
clock(); |
spinlock_lock(&irq->lock); |
} |
/** Initialize APIC on BSP. */ |
169,7 → 162,6 |
io_apic_disable_irqs(0xffff); |
irq_initialize(&l_apic_timer_irq); |
l_apic_timer_irq.preack = true; |
l_apic_timer_irq.devno = device_assign_devno(); |
l_apic_timer_irq.inr = IRQ_CLK; |
l_apic_timer_irq.claim = l_apic_timer_claim; |
/branches/rcu/kernel/arch/ia32/src/interrupt.c |
---|
176,7 → 176,6 |
ASSERT(n >= IVT_IRQBASE); |
int inum = n - IVT_IRQBASE; |
bool ack = false; |
ASSERT(inum < IRQ_COUNT); |
ASSERT((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1)); |
185,12 → 184,6 |
/* |
* The IRQ handler was found. |
*/ |
if (irq->preack) { |
/* Send EOI before processing the interrupt */ |
trap_virtual_eoi(); |
ack = true; |
} |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
201,8 → 194,6 |
printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, inum); |
#endif |
} |
if (!ack) |
trap_virtual_eoi(); |
} |
/branches/rcu/kernel/arch/ia32/src/drivers/i8254.c |
---|
82,7 → 82,6 |
void i8254_init(void) |
{ |
irq_initialize(&i8254_irq); |
i8254_irq.preack = true; |
i8254_irq.devno = device_assign_devno(); |
i8254_irq.inr = IRQ_CLK; |
i8254_irq.claim = i8254_claim; |
/branches/rcu/uspace/ns/ns.c |
---|
83,10 → 83,9 |
static void *clockaddr = NULL; |
static void *klogaddr = NULL; |
static void get_as_area(ipc_callid_t callid, ipc_call_t *call, char *name, char *colstr, void **addr) |
static void get_as_area(ipc_callid_t callid, ipc_call_t *call, char *name, void **addr) |
{ |
void *ph_addr; |
int ph_color; |
if (!*addr) { |
ph_addr = (void *) sysinfo_value(name); |
94,8 → 93,7 |
ipc_answer_fast(callid, ENOENT, 0, 0); |
return; |
} |
ph_color = (int) sysinfo_value(colstr); |
*addr = as_get_mappable_page(PAGE_SIZE, ph_color); |
*addr = as_get_mappable_page(PAGE_SIZE); |
physmem_map(ph_addr, *addr, 1, AS_AREA_READ | AS_AREA_CACHEABLE); |
} |
ipc_answer_fast(callid, 0, (ipcarg_t) *addr, AS_AREA_READ); |
119,11 → 117,11 |
switch (IPC_GET_ARG3(call)) { |
case SERVICE_MEM_REALTIME: |
get_as_area(callid, &call, "clock.faddr", |
"clock.fcolor", &clockaddr); |
&clockaddr); |
break; |
case SERVICE_MEM_KLOG: |
get_as_area(callid, &call, "klog.faddr", |
"klog.fcolor", &klogaddr); |
&klogaddr); |
break; |
default: |
ipc_answer_fast(callid, ENOENT, 0, 0); |
/branches/rcu/uspace/fb/main.c |
---|
43,8 → 43,7 |
{ |
void *dest; |
dest = as_get_mappable_page(IPC_GET_ARG2(*call), |
PAGE_COLOR(IPC_GET_ARG1(*call))); |
dest = as_get_mappable_page(IPC_GET_ARG2(*call)); |
if (ipc_answer_fast(callid, 0, (sysarg_t) dest, 0) == 0) { |
if (*area) |
as_area_destroy(*area); |
/branches/rcu/uspace/fb/fb.c |
---|
755,8 → 755,7 |
case IPC_M_AS_AREA_SEND: |
/* We accept one area for data interchange */ |
if (IPC_GET_ARG1(*call) == shm_id) { |
void *dest = as_get_mappable_page(IPC_GET_ARG2(*call), |
PAGE_COLOR(IPC_GET_ARG1(*call))); |
void *dest = as_get_mappable_page(IPC_GET_ARG2(*call)); |
shm_size = IPC_GET_ARG2(*call); |
if (!ipc_answer_fast(callid, 0, (sysarg_t) dest, 0)) |
shm = dest; |
1369,8 → 1368,7 |
fb_invert_colors = sysinfo_value("fb.invert-colors"); |
asz = fb_scanline * fb_height; |
fb_addr = as_get_mappable_page(asz, (int) |
sysinfo_value("fb.address.color")); |
fb_addr = as_get_mappable_page(asz); |
physmem_map(fb_ph_addr, fb_addr, ALIGN_UP(asz, PAGE_SIZE) >> |
PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE); |
/branches/rcu/uspace/fb/ega.c |
---|
315,8 → 315,7 |
iospace_enable(task_get_id(), (void *) EGA_IO_ADDRESS, 2); |
sz = scr_width * scr_height * 2; |
scr_addr = as_get_mappable_page(sz, (int) |
sysinfo_value("fb.address.color")); |
scr_addr = as_get_mappable_page(sz); |
physmem_map(ega_ph_addr, scr_addr, ALIGN_UP(sz, PAGE_SIZE) >> |
PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE); |
/branches/rcu/uspace/klog/klog.c |
---|
62,7 → 62,7 |
printf("Kernel console output.\n"); |
mapping = as_get_mappable_page(PAGE_SIZE, sysinfo_value("klog.fcolor")); |
mapping = as_get_mappable_page(PAGE_SIZE); |
res = ipc_call_sync_3(PHONE_NS, IPC_M_AS_AREA_RECV, |
(sysarg_t) mapping, PAGE_SIZE, SERVICE_MEM_KLOG, |
NULL, NULL, NULL); |
/branches/rcu/uspace/rd/rd.c |
---|
73,12 → 73,11 |
{ |
size_t rd_size = sysinfo_value("rd.size"); |
void * rd_ph_addr = (void *) sysinfo_value("rd.address.physical"); |
int rd_color = (int) sysinfo_value("rd.address.color"); |
if (rd_size == 0) |
return false; |
void * rd_addr = as_get_mappable_page(rd_size, rd_color); |
void * rd_addr = as_get_mappable_page(rd_size); |
physmem_map(rd_ph_addr, rd_addr, ALIGN_UP(rd_size, PAGE_SIZE) >> PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE); |
/branches/rcu/uspace/libc/include/as.h |
---|
40,13 → 40,11 |
#include <kernel/mm/as.h> |
#include <libarch/config.h> |
#define PAGE_COLOR(va) (((va) >> PAGE_WIDTH) & ((1 << PAGE_COLOR_BITS) - 1)) |
extern void *as_area_create(void *address, size_t size, int flags); |
extern int as_area_resize(void *address, size_t size, int flags); |
extern int as_area_destroy(void *address); |
extern void *set_maxheapsize(size_t mhs); |
extern void * as_get_mappable_page(size_t sz, int color); |
extern void * as_get_mappable_page(size_t sz); |
#endif |
/branches/rcu/uspace/libc/generic/time.c |
---|
72,12 → 72,11 |
int res; |
if (!ktime) { |
mapping = as_get_mappable_page(PAGE_SIZE, (int) |
sysinfo_value("clock.fcolor")); |
mapping = as_get_mappable_page(PAGE_SIZE); |
/* Get the mapping of kernel clock */ |
res = ipc_call_sync_3(PHONE_NS, IPC_M_AS_AREA_RECV, (sysarg_t) |
mapping, PAGE_SIZE, SERVICE_MEM_REALTIME, NULL, &rights, |
NULL); |
res = ipc_call_sync_3(PHONE_NS, IPC_M_AS_AREA_RECV, |
(sysarg_t) mapping, PAGE_SIZE, SERVICE_MEM_REALTIME, NULL, |
&rights, NULL); |
if (res) { |
printf("Failed to initialize timeofday memarea\n"); |
_exit(1); |
/branches/rcu/uspace/libc/generic/as.c |
---|
69,8 → 69,8 |
*/ |
int as_area_resize(void *address, size_t size, int flags) |
{ |
return __SYSCALL3(SYS_AS_AREA_RESIZE, (sysarg_t ) address, (sysarg_t) |
size, (sysarg_t) flags); |
return __SYSCALL3(SYS_AS_AREA_RESIZE, (sysarg_t ) address, |
(sysarg_t) size, (sysarg_t) flags); |
} |
/** Destroy address space area. |
143,7 → 143,6 |
/** Return pointer to some unmapped area, where fits new as_area |
* |
* @param sz Requested size of the allocation. |
* @param color Requested virtual color of the allocation. |
* |
* @return Pointer to the beginning |
* |
150,7 → 149,7 |
* TODO: make some first_fit/... algorithm, we are now just incrementing |
* the pointer to last area |
*/ |
void *as_get_mappable_page(size_t sz, int color) |
void *as_get_mappable_page(size_t sz) |
{ |
void *res; |
uint64_t asz; |
166,11 → 165,9 |
set_maxheapsize(MAX_HEAP_SIZE); |
/* |
* Make sure we allocate from naturally aligned address and a page of |
* appropriate color. |
* Make sure we allocate from naturally aligned address. |
*/ |
i = 0; |
do { |
if (!last_allocated) { |
last_allocated = (void *) ALIGN_UP((void *) &_heap + |
maxheapsize, asz); |
178,9 → 175,6 |
last_allocated = (void *) ALIGN_UP(((uintptr_t) |
last_allocated) + (int) (i > 0), asz); |
} |
} while ((asz < (1 << (PAGE_COLOR_BITS + PAGE_WIDTH))) && |
(PAGE_COLOR((uintptr_t) last_allocated) != color) && |
(++i < (1 << PAGE_COLOR_BITS))); |
res = last_allocated; |
last_allocated += ALIGN_UP(sz, PAGE_SIZE); |
/branches/rcu/uspace/libc/generic/mman.c |
---|
36,10 → 36,11 |
#include <as.h> |
#include <unistd.h> |
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) |
void *mmap(void *start, size_t length, int prot, int flags, int fd, |
off_t offset) |
{ |
if (!start) |
start = as_get_mappable_page(length, 0); |
start = as_get_mappable_page(length); |
// if (! ((flags & MAP_SHARED) ^ (flags & MAP_PRIVATE))) |
// return MAP_FAILED; |
/branches/rcu/uspace/libc/arch/sparc64/_link.ld.in |
---|
7,9 → 7,9 |
} |
SECTIONS { |
. = 0x2000; |
. = 0x4000; |
.init ALIGN(0x2000) : SUBALIGN(0x2000) { |
.init ALIGN(0x4000) : SUBALIGN(0x4000) { |
*(.init); |
} :text |
.text : { |
17,11 → 17,11 |
*(.rodata*); |
} :text |
.got ALIGN(0x2000) : SUBALIGN(0x2000) { |
.got ALIGN(0x4000) : SUBALIGN(0x4000) { |
_gp = .; |
*(.got*); |
} :data |
.data ALIGN(0x2000) : SUBALIGN(0x2000) { |
.data ALIGN(0x4000) : SUBALIGN(0x4000) { |
*(.data); |
*(.sdata); |
} :data |
41,7 → 41,7 |
*(.bss); |
} :data |
. = ALIGN(0x2000); |
. = ALIGN(0x4000); |
_heap = .; |
/DISCARD/ : { |
/branches/rcu/uspace/libc/arch/sparc64/include/config.h |
---|
35,9 → 35,9 |
#ifndef LIBC_sparc64_CONFIG_H_ |
#define LIBC_sparc64_CONFIG_H_ |
#define PAGE_WIDTH 13 |
#define PAGE_WIDTH 14 |
#define PAGE_SIZE (1<<PAGE_WIDTH) |
#define PAGE_COLOR_BITS 1 /**< Bit 13 is the page color. */ |
#define PAGE_COLOR_BITS 0 /**< Only one page color. */ |
#endif |
/branches/rcu/boot/arch/sparc64/loader/asm.h |
---|
33,8 → 33,8 |
#include "types.h" |
#include "main.h" |
#define PAGE_SIZE 8192 |
#define PAGE_WIDTH 13 |
#define PAGE_WIDTH 14 |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
/branches/rcu/boot/arch/sparc64/loader/Makefile |
---|
90,7 → 90,7 |
-include Makefile.depend |
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) kernel.o |
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) |
$(LD) -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) -o $@ |
depend: |
/branches/rcu/boot/arch/ppc32/loader/Makefile |
---|
87,7 → 87,7 |
-include Makefile.depend |
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) kernel.o |
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) |
$(LD) -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) -o $@ |
depend: |
/branches/rcu/boot/arch/ppc64/loader/Makefile |
---|
87,7 → 87,7 |
-include Makefile.depend |
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) kernel.o |
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) |
$(LD) -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) -o $@ |
depend: |
/branches/rcu/boot/arch/mips32/loader/Makefile |
---|
86,7 → 86,7 |
-include Makefile.depend |
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) kernel.o |
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) |
$(LD) -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) -o $@ |
depend: |