2008-11-18 Joel Sherrill <joel.sherrill@oarcorp.com>
* configure: Regenerated. * configure.ac: Add test for System V shared memory and semaphore. * debug.c, debug.h: Add trace support for new devices. * hw_sem.c, hw_shm.c: New files. * Makefile.in: Add hw_sem.c and hw_shm.c.
This commit is contained in:
parent
394a666683
commit
00a0b122cf
8 changed files with 894 additions and 7 deletions
|
@ -1,3 +1,11 @@
|
|||
2008-11-18 Joel Sherrill <joel.sherrill@oarcorp.com>
|
||||
|
||||
* configure: Regenerated.
|
||||
* configure.ac: Add test for System V shared memory and semaphore.
|
||||
* debug.c, debug.h: Add trace support for new devices.
|
||||
* hw_sem.c, hw_shm.c: New files.
|
||||
* Makefile.in: Add hw_sem.c and hw_shm.c.
|
||||
|
||||
2008-07-11 Hans-Peter Nilsson <hp@axis.com>
|
||||
|
||||
* configure.ac: Add test for libz and zlib.h.
|
||||
|
|
|
@ -843,6 +843,8 @@ hw_opic.o: hw_opic.c $(DEVICE_TABLE_H)
|
|||
hw_pal.o: hw_pal.c $(DEVICE_TABLE_H) $(CPU_H)
|
||||
hw_phb.o: hw_phb.c $(DEVICE_TABLE_H) $(HW_PHB_H) $(COREFILE_H)
|
||||
hw_register.o: hw_register.c $(DEVICE_TABLE_H) $(PSIM_H)
|
||||
hw_sem.o: hw_sem.c $(DEVICE_TABLE_H) $(PSIM_H)
|
||||
hw_shm.o: hw_shm.c $(DEVICE_TABLE_H) $(PSIM_H)
|
||||
hw_trace.o: hw_trace.c $(DEVICE_TABLE_H)
|
||||
hw_vm.o: hw_vm.c $(DEVICE_TABLE_H) $(CPU_H)
|
||||
# ignore this line, it stops make from getting confused
|
||||
|
|
259
sim/ppc/configure
vendored
259
sim/ppc/configure
vendored
|
@ -2715,10 +2715,263 @@ esac
|
|||
|
||||
fi;
|
||||
|
||||
echo "$as_me:$LINENO: checking if union semun defined" >&5
|
||||
echo $ECHO_N "checking if union semun defined... $ECHO_C" >&6
|
||||
if test "${ac_cv_HAS_UNION_SEMUN+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/sem.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
union semun arg ;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
(eval $ac_compile) 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; } &&
|
||||
{ ac_try='test -s conftest.$ac_objext'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
ac_cv_has_union_semun="yes"
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_cv_has_union_semun="no"
|
||||
fi
|
||||
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
echo "$as_me:$LINENO: result: $ac_cv_has_union_semun" >&5
|
||||
echo "${ECHO_T}$ac_cv_has_union_semun" >&6
|
||||
|
||||
fi
|
||||
echo "$as_me:$LINENO: result: $ac_cv_HAS_UNION_SEMUN" >&5
|
||||
echo "${ECHO_T}$ac_cv_HAS_UNION_SEMUN" >&6
|
||||
|
||||
|
||||
if test "$ac_cv_has_union_semun" = "yes"; then
|
||||
echo "$as_me:$LINENO: checking whether System V semaphores are supported" >&5
|
||||
echo $ECHO_N "checking whether System V semaphores are supported... $ECHO_C" >&6
|
||||
if test "${ac_cv_sysv_sem+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
|
||||
if test "$cross_compiling" = yes; then
|
||||
:
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/sem.h>
|
||||
int main () {
|
||||
union semun arg ;
|
||||
|
||||
int id=semget(IPC_PRIVATE,1,IPC_CREAT|0400);
|
||||
if (id == -1)
|
||||
exit(1);
|
||||
arg.val = 0; /* avoid implicit type cast to union */
|
||||
if (semctl(id, 0, IPC_RMID, arg) == -1)
|
||||
exit(1);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
_ACEOF
|
||||
rm -f conftest$ac_exeext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||
(eval $ac_link) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && { ac_try='./conftest$ac_exeext'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
ac_cv_sysv_sem="yes"
|
||||
else
|
||||
echo "$as_me: program exited with status $ac_status" >&5
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
( exit $ac_status )
|
||||
ac_cv_sysv_sem="no"
|
||||
fi
|
||||
rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
|
||||
fi
|
||||
echo "$as_me:$LINENO: result: $ac_cv_sysv_sem" >&5
|
||||
echo "${ECHO_T}$ac_cv_sysv_sem" >&6
|
||||
else # semun is not defined
|
||||
echo "$as_me:$LINENO: checking whether System V semaphores are supported" >&5
|
||||
echo $ECHO_N "checking whether System V semaphores are supported... $ECHO_C" >&6
|
||||
if test "${ac_cv_sysv_sem+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
|
||||
if test "$cross_compiling" = yes; then
|
||||
:
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/sem.h>
|
||||
union semun {
|
||||
int val;
|
||||
struct semid_ds *buf;
|
||||
ushort *array;
|
||||
};
|
||||
int main () {
|
||||
union semun arg ;
|
||||
|
||||
int id=semget(IPC_PRIVATE,1,IPC_CREAT|0400);
|
||||
if (id == -1)
|
||||
exit(1);
|
||||
arg.val = 0; /* avoid implicit type cast to union */
|
||||
if (semctl(id, 0, IPC_RMID, arg) == -1)
|
||||
exit(1);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
_ACEOF
|
||||
rm -f conftest$ac_exeext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||
(eval $ac_link) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && { ac_try='./conftest$ac_exeext'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
ac_cv_sysv_sem="yes"
|
||||
else
|
||||
echo "$as_me: program exited with status $ac_status" >&5
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
( exit $ac_status )
|
||||
ac_cv_sysv_sem="no"
|
||||
fi
|
||||
rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
|
||||
fi
|
||||
echo "$as_me:$LINENO: result: $ac_cv_sysv_sem" >&5
|
||||
echo "${ECHO_T}$ac_cv_sysv_sem" >&6
|
||||
fi
|
||||
|
||||
echo "$as_me:$LINENO: checking whether System V shared memory is supported" >&5
|
||||
echo $ECHO_N "checking whether System V shared memory is supported... $ECHO_C" >&6
|
||||
if test "${ac_cv_sysv_shm+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
|
||||
if test "$cross_compiling" = yes; then
|
||||
:
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
int main () {
|
||||
int id=shmget(IPC_PRIVATE,1,IPC_CREAT|0400);
|
||||
if (id == -1)
|
||||
exit(1);
|
||||
if (shmctl(id, IPC_RMID, 0) == -1)
|
||||
exit(1);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
_ACEOF
|
||||
rm -f conftest$ac_exeext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||
(eval $ac_link) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && { ac_try='./conftest$ac_exeext'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
ac_cv_sysv_shm="yes"
|
||||
else
|
||||
echo "$as_me: program exited with status $ac_status" >&5
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
( exit $ac_status )
|
||||
ac_cv_sysv_shm="no"
|
||||
fi
|
||||
rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
|
||||
fi
|
||||
echo "$as_me:$LINENO: result: $ac_cv_sysv_shm" >&5
|
||||
echo "${ECHO_T}$ac_cv_sysv_shm" >&6
|
||||
|
||||
if test x"$ac_cv_sysv_shm" = x"yes" -a x"$ac_cv_sysv_sem" = x"yes" ; then
|
||||
sim_sysv_ipc_hw=",sem,shm";
|
||||
else
|
||||
sim_sysv_ipc_hw="";
|
||||
fi
|
||||
|
||||
if test x"$ac_cv_has_union_semun" = x"yes" -a x"$ac_cv_sysv_sem" = x"yes" ; then
|
||||
sim_hwflags="-DHAS_UNION_SEMUN";
|
||||
fi
|
||||
|
||||
|
||||
# Check whether --enable-sim-hardware or --disable-sim-hardware was given.
|
||||
if test "${enable_sim_hardware+set}" = set; then
|
||||
enableval="$enable_sim_hardware"
|
||||
hardware="cpu,memory,nvram,iobus,htab,disk,trace,register,vm,init,core,pal,com,eeprom,opic,glue,phb,ide"
|
||||
hardware="cpu,memory,nvram,iobus,htab,disk,trace,register,vm,init,core,pal,com,eeprom,opic,glue,phb,ide${sim_sysv_ipc_hw}"
|
||||
case "${enableval}" in
|
||||
yes) ;;
|
||||
no) { { echo "$as_me:$LINENO: error: \"List of hardware must be specified for --enable-sim-hardware\"" >&5
|
||||
|
@ -2734,14 +2987,13 @@ if test x"$silent" != x"yes" && test x"$hardware" != x""; then
|
|||
echo "Setting hardware to $sim_hw_src, $sim_hw_obj"
|
||||
fi
|
||||
else
|
||||
hardware="cpu,memory,nvram,iobus,htab,disk,trace,register,vm,init,core,pal,com,eeprom,opic,glue,phb,ide"
|
||||
hardware="cpu,memory,nvram,iobus,htab,disk,trace,register,vm,init,core,pal,com,eeprom,opic,glue,phb,ide${sim_sysv_ipc_hw}"
|
||||
sim_hw_src=`echo $hardware | sed -e 's/,/.c hw_/g' -e 's/^/hw_/' -e s'/$/.c/'`
|
||||
sim_hw_obj=`echo $sim_hw_src | sed -e 's/\.c/.o/g'`
|
||||
if test x"$silent" != x"yes"; then
|
||||
echo "Setting hardware to $sim_hw_src, $sim_hw_obj"
|
||||
fi
|
||||
fi;
|
||||
|
||||
# Check whether --enable-sim-hostbitsize or --disable-sim-hostbitsize was given.
|
||||
if test "${enable_sim_hostbitsize+set}" = set; then
|
||||
enableval="$enable_sim_hostbitsize"
|
||||
|
@ -2758,7 +3010,6 @@ else
|
|||
sim_hostbitsize=""
|
||||
fi;
|
||||
|
||||
|
||||
# Check whether --enable-sim-hostendian or --disable-sim-hostendian was given.
|
||||
if test "${enable_sim_hostendian+set}" = set; then
|
||||
enableval="$enable_sim_hostendian"
|
||||
|
|
|
@ -209,10 +209,105 @@ case "${target}" in
|
|||
esac
|
||||
])dnl
|
||||
|
||||
AC_CACHE_CHECK([if union semun defined],
|
||||
ac_cv_HAS_UNION_SEMUN,
|
||||
[AC_TRY_COMPILE([
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/sem.h>],
|
||||
[union semun arg ;],
|
||||
[ac_cv_has_union_semun="yes"],
|
||||
[ac_cv_has_union_semun="no"])
|
||||
AC_MSG_RESULT($ac_cv_has_union_semun)
|
||||
])
|
||||
|
||||
|
||||
if test "$ac_cv_has_union_semun" = "yes"; then
|
||||
AC_CACHE_CHECK(whether System V semaphores are supported,
|
||||
ac_cv_sysv_sem,
|
||||
[
|
||||
AC_TRY_RUN(
|
||||
[
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/sem.h>
|
||||
int main () {
|
||||
union semun arg ;
|
||||
|
||||
int id=semget(IPC_PRIVATE,1,IPC_CREAT|0400);
|
||||
if (id == -1)
|
||||
exit(1);
|
||||
arg.val = 0; /* avoid implicit type cast to union */
|
||||
if (semctl(id, 0, IPC_RMID, arg) == -1)
|
||||
exit(1);
|
||||
exit(0);
|
||||
}
|
||||
],
|
||||
ac_cv_sysv_sem="yes", ac_cv_sysv_sem="no", :)
|
||||
])
|
||||
else # semun is not defined
|
||||
AC_CACHE_CHECK(whether System V semaphores are supported,
|
||||
ac_cv_sysv_sem,
|
||||
[
|
||||
AC_TRY_RUN(
|
||||
[
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/sem.h>
|
||||
union semun {
|
||||
int val;
|
||||
struct semid_ds *buf;
|
||||
ushort *array;
|
||||
};
|
||||
int main () {
|
||||
union semun arg ;
|
||||
|
||||
int id=semget(IPC_PRIVATE,1,IPC_CREAT|0400);
|
||||
if (id == -1)
|
||||
exit(1);
|
||||
arg.val = 0; /* avoid implicit type cast to union */
|
||||
if (semctl(id, 0, IPC_RMID, arg) == -1)
|
||||
exit(1);
|
||||
exit(0);
|
||||
}
|
||||
],
|
||||
ac_cv_sysv_sem="yes", ac_cv_sysv_sem="no", :)
|
||||
])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK(whether System V shared memory is supported,
|
||||
ac_cv_sysv_shm,
|
||||
[
|
||||
AC_TRY_RUN([
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
int main () {
|
||||
int id=shmget(IPC_PRIVATE,1,IPC_CREAT|0400);
|
||||
if (id == -1)
|
||||
exit(1);
|
||||
if (shmctl(id, IPC_RMID, 0) == -1)
|
||||
exit(1);
|
||||
exit(0);
|
||||
}
|
||||
],
|
||||
ac_cv_sysv_shm="yes", ac_cv_sysv_shm="no", :)
|
||||
])
|
||||
|
||||
if test x"$ac_cv_sysv_shm" = x"yes" -a x"$ac_cv_sysv_sem" = x"yes" ; then
|
||||
sim_sysv_ipc_hw=",sem,shm";
|
||||
else
|
||||
sim_sysv_ipc_hw="";
|
||||
fi
|
||||
|
||||
if test x"$ac_cv_has_union_semun" = x"yes" -a x"$ac_cv_sysv_sem" = x"yes" ; then
|
||||
sim_hwflags="-DHAS_UNION_SEMUN";
|
||||
fi
|
||||
|
||||
|
||||
AC_ARG_ENABLE(sim-hardware,
|
||||
[ --enable-sim-hardware=list Specify the hardware to be included in the build.],
|
||||
[hardware="cpu,memory,nvram,iobus,htab,disk,trace,register,vm,init,core,pal,com,eeprom,opic,glue,phb,ide"
|
||||
[hardware="cpu,memory,nvram,iobus,htab,disk,trace,register,vm,init,core,pal,com,eeprom,opic,glue,phb,ide${sim_sysv_ipc_hw}"
|
||||
case "${enableval}" in
|
||||
yes) ;;
|
||||
no) AC_MSG_ERROR("List of hardware must be specified for --enable-sim-hardware"); hardware="";;
|
||||
|
@ -224,14 +319,13 @@ sim_hw_src=`echo $hardware | sed -e 's/,/.c hw_/g' -e 's/^/hw_/' -e s'/$/.c/'`
|
|||
sim_hw_obj=`echo $sim_hw_src | sed -e 's/\.c/.o/g'`
|
||||
if test x"$silent" != x"yes" && test x"$hardware" != x""; then
|
||||
echo "Setting hardware to $sim_hw_src, $sim_hw_obj"
|
||||
fi],[hardware="cpu,memory,nvram,iobus,htab,disk,trace,register,vm,init,core,pal,com,eeprom,opic,glue,phb,ide"
|
||||
fi],[hardware="cpu,memory,nvram,iobus,htab,disk,trace,register,vm,init,core,pal,com,eeprom,opic,glue,phb,ide${sim_sysv_ipc_hw}"
|
||||
sim_hw_src=`echo $hardware | sed -e 's/,/.c hw_/g' -e 's/^/hw_/' -e s'/$/.c/'`
|
||||
sim_hw_obj=`echo $sim_hw_src | sed -e 's/\.c/.o/g'`
|
||||
if test x"$silent" != x"yes"; then
|
||||
echo "Setting hardware to $sim_hw_src, $sim_hw_obj"
|
||||
fi])dnl
|
||||
|
||||
|
||||
AC_ARG_ENABLE(sim-hostbitsize,
|
||||
[ --enable-sim-hostbitsize=32|64 Specify host bitsize (32 or 64).],
|
||||
[case "${enableval}" in
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
int ppc_trace[nr_trace_options];
|
||||
|
||||
|
@ -70,6 +73,8 @@ static trace_option_descriptor trace_description[] = {
|
|||
{ trace_pass_device, "pass-device" },
|
||||
{ trace_phb_device, "phb-device" },
|
||||
{ trace_register_device, "register-device", "Device initializing registers" },
|
||||
{ trace_sem_device, "sem-device" },
|
||||
{ trace_shm_device, "shm-device" },
|
||||
{ trace_stack_device, "stack-device" },
|
||||
{ trace_vm_device, "vm-device" },
|
||||
/* packages */
|
||||
|
|
|
@ -51,6 +51,8 @@ typedef enum {
|
|||
trace_pal_device,
|
||||
trace_pass_device,
|
||||
trace_phb_device,
|
||||
trace_sem_device,
|
||||
trace_shm_device,
|
||||
trace_stack_device,
|
||||
trace_register_device,
|
||||
trace_vm_device,
|
||||
|
|
289
sim/ppc/hw_sem.c
Normal file
289
sim/ppc/hw_sem.c
Normal file
|
@ -0,0 +1,289 @@
|
|||
/* This file is part of the program psim.
|
||||
|
||||
Copyright (C) 1997,2008, Joel Sherrill <joel@OARcorp.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _HW_SEM_C_
|
||||
#define _HW_SEM_C_
|
||||
|
||||
#include "device_table.h"
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#else
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/sem.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
/* DEVICE
|
||||
|
||||
|
||||
sem - provide access to a unix semaphore
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
|
||||
This device implements an interface to a unix semaphore.
|
||||
|
||||
|
||||
PROPERTIES
|
||||
|
||||
|
||||
reg = <address> <size> (required)
|
||||
|
||||
Determine where the memory lives in the parents address space.
|
||||
|
||||
key = <integer> (required)
|
||||
|
||||
This is the key of the unix semaphore.
|
||||
|
||||
EXAMPLES
|
||||
|
||||
|
||||
Enable tracing of the sem:
|
||||
|
||||
| bash$ psim -t sem-device \
|
||||
|
||||
|
||||
Configure a UNIX semaphore using key 0x12345678 mapped into psim
|
||||
address space at 0xfff00000:
|
||||
|
||||
| -o '/sem@0xfff00000/reg 0xfff00000 0x80000' \
|
||||
| -o '/sem@0xfff00000/key 0x12345678' \
|
||||
|
||||
sim/ppc/run -o '/#address-cells 1' \
|
||||
-o '/sem@0xfff00000/reg 0xfff00000 12' \
|
||||
-o '/sem@0xfff00000/key 0x12345678' ../psim-hello/hello
|
||||
|
||||
REGISTERS
|
||||
|
||||
offset 0 - lock count
|
||||
offset 4 - lock operation
|
||||
offset 8 - unlock operation
|
||||
|
||||
All reads return the current or resulting count.
|
||||
|
||||
BUGS
|
||||
|
||||
None known.
|
||||
|
||||
*/
|
||||
|
||||
typedef struct _hw_sem_device {
|
||||
unsigned_word physical_address;
|
||||
key_t key;
|
||||
int id;
|
||||
int initial;
|
||||
int count;
|
||||
} hw_sem_device;
|
||||
|
||||
#if !HAS_UNION_SEMUN
|
||||
union semun {
|
||||
int val;
|
||||
struct semid_ds *buf;
|
||||
unsigned short int *array;
|
||||
#if defined(__linux__)
|
||||
struct seminfo *__buf;
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
static void
|
||||
hw_sem_init_data(device *me)
|
||||
{
|
||||
hw_sem_device *sem = (hw_sem_device*)device_data(me);
|
||||
const device_unit *d;
|
||||
int status;
|
||||
union semun help;
|
||||
|
||||
/* initialize the properties of the sem */
|
||||
|
||||
if (device_find_property(me, "key") == NULL)
|
||||
error("sem_init_data() required key property is missing\n");
|
||||
|
||||
if (device_find_property(me, "value") == NULL)
|
||||
error("sem_init_data() required value property is missing\n");
|
||||
|
||||
sem->key = (key_t) device_find_integer_property(me, "key");
|
||||
DTRACE(sem, ("semaphore key (%d)\n", sem->key) );
|
||||
|
||||
sem->initial = (int) device_find_integer_property(me, "value");
|
||||
DTRACE(sem, ("semaphore initial value (%d)\n", sem->initial) );
|
||||
|
||||
d = device_unit_address(me);
|
||||
sem->physical_address = d->cells[ d->nr_cells-1 ];
|
||||
DTRACE(sem, ("semaphore physical_address=0x%x\n", sem->physical_address));
|
||||
|
||||
/* Now to initialize the semaphore */
|
||||
|
||||
if ( sem->initial != -1 ) {
|
||||
|
||||
sem->id = semget(sem->key, 1, IPC_CREAT | 0660);
|
||||
if (sem->id == -1)
|
||||
error("hw_sem_init_data() semget failed\n");
|
||||
|
||||
help.val = sem->initial;
|
||||
status = semctl( sem->id, 0, SETVAL, help );
|
||||
if (status == -1)
|
||||
error("hw_sem_init_data() semctl -- set value failed\n");
|
||||
|
||||
} else {
|
||||
sem->id = semget(sem->key, 1, 0660);
|
||||
if (sem->id == -1)
|
||||
error("hw_sem_init_data() semget failed\n");
|
||||
}
|
||||
|
||||
sem->count = semctl( sem->id, 0, GETVAL, help );
|
||||
if (sem->count == -1)
|
||||
error("hw_sem_init_data() semctl -- get value failed\n");
|
||||
DTRACE(sem, ("semaphore OS value (%d)\n", sem->count) );
|
||||
}
|
||||
|
||||
static void
|
||||
hw_sem_attach_address_callback(device *me,
|
||||
attach_type attach,
|
||||
int space,
|
||||
unsigned_word addr,
|
||||
unsigned nr_bytes,
|
||||
access_type access,
|
||||
device *client) /*callback/default*/
|
||||
{
|
||||
hw_sem_device *sem = (hw_sem_device*)device_data(me);
|
||||
|
||||
if (space != 0)
|
||||
error("sem_attach_address_callback() invalid address space\n");
|
||||
|
||||
if (nr_bytes == 12)
|
||||
error("sem_attach_address_callback() invalid size\n");
|
||||
|
||||
sem->physical_address = addr;
|
||||
DTRACE(sem, ("semaphore physical_address=0x%x\n", addr));
|
||||
}
|
||||
|
||||
static unsigned
|
||||
hw_sem_io_read_buffer(device *me,
|
||||
void *dest,
|
||||
int space,
|
||||
unsigned_word addr,
|
||||
unsigned nr_bytes,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
hw_sem_device *sem = (hw_sem_device*)device_data(me);
|
||||
struct sembuf sb;
|
||||
int status;
|
||||
unsigned32 u32;
|
||||
union semun help;
|
||||
|
||||
/* do we need to worry about out of range addresses? */
|
||||
|
||||
DTRACE(sem, ("semaphore read addr=0x%x length=%d\n", addr, nr_bytes));
|
||||
|
||||
if (!(addr >= sem->physical_address && addr <= sem->physical_address + 11))
|
||||
error("hw_sem_io_read_buffer() invalid address - out of range\n");
|
||||
|
||||
if ((addr % 4) != 0)
|
||||
error("hw_sem_io_read_buffer() invalid address - alignment\n");
|
||||
|
||||
if (nr_bytes != 4)
|
||||
error("hw_sem_io_read_buffer() invalid length\n");
|
||||
|
||||
switch ( (addr - sem->physical_address) / 4 ) {
|
||||
|
||||
case 0: /* OBTAIN CURRENT VALUE */
|
||||
break;
|
||||
|
||||
case 1: /* LOCK */
|
||||
sb.sem_num = 0;
|
||||
sb.sem_op = -1;
|
||||
sb.sem_flg = 0;
|
||||
|
||||
status = semop(sem->id, &sb, 1);
|
||||
if (status == -1) {
|
||||
perror( "hw_sem.c: lock" );
|
||||
error("hw_sem_io_read_buffer() sem lock\n");
|
||||
}
|
||||
|
||||
DTRACE(sem, ("semaphore lock %d\n", sem->count));
|
||||
break;
|
||||
|
||||
case 2: /* UNLOCK */
|
||||
sb.sem_num = 0;
|
||||
sb.sem_op = 1;
|
||||
sb.sem_flg = 0;
|
||||
|
||||
status = semop(sem->id, &sb, 1);
|
||||
if (status == -1) {
|
||||
perror( "hw_sem.c: unlock" );
|
||||
error("hw_sem_io_read_buffer() sem unlock\n");
|
||||
}
|
||||
DTRACE(sem, ("semaphore unlock %d\n", sem->count));
|
||||
break;
|
||||
|
||||
default:
|
||||
error("hw_sem_io_read_buffer() invalid address - unknown error\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* assume target is big endian */
|
||||
u32 = H2T_4(semctl( sem->id, 0, GETVAL, help ));
|
||||
|
||||
DTRACE(sem, ("semaphore OS value (%d)\n", u32) );
|
||||
if (u32 == 0xffffffff) {
|
||||
perror( "hw_sem.c: getval" );
|
||||
error("hw_sem_io_read_buffer() semctl -- get value failed\n");
|
||||
}
|
||||
|
||||
memcpy(dest, &u32, nr_bytes);
|
||||
return nr_bytes;
|
||||
|
||||
}
|
||||
|
||||
static device_callbacks const hw_sem_callbacks = {
|
||||
{ generic_device_init_address, hw_sem_init_data },
|
||||
{ hw_sem_attach_address_callback, }, /* address */
|
||||
{ hw_sem_io_read_buffer, NULL }, /* IO */
|
||||
{ NULL, }, /* DMA */
|
||||
{ NULL, }, /* interrupt */
|
||||
{ NULL, }, /* unit */
|
||||
NULL,
|
||||
};
|
||||
|
||||
static void *
|
||||
hw_sem_create(const char *name,
|
||||
const device_unit *unit_address,
|
||||
const char *args)
|
||||
{
|
||||
hw_sem_device *sem = ZALLOC(hw_sem_device);
|
||||
return sem;
|
||||
}
|
||||
|
||||
const device_descriptor hw_sem_device_descriptor[] = {
|
||||
{ "sem", hw_sem_create, &hw_sem_callbacks },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
#endif /* _HW_SEM_C_ */
|
236
sim/ppc/hw_shm.c
Normal file
236
sim/ppc/hw_shm.c
Normal file
|
@ -0,0 +1,236 @@
|
|||
/* This file is part of the program psim.
|
||||
|
||||
Copyright (C) 1997,2008, Joel Sherrill <joel@OARcorp.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _HW_SHM_C_
|
||||
#define _HW_SHM_C_
|
||||
|
||||
#include "device_table.h"
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#else
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
|
||||
|
||||
/* DEVICE
|
||||
|
||||
|
||||
shm - map unix shared memory into psim address space
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
|
||||
This device implements an area of memory which is mapped into UNIX
|
||||
shared memory.
|
||||
|
||||
|
||||
PROPERTIES
|
||||
|
||||
|
||||
reg = <address> <size> (required)
|
||||
|
||||
Determine where the memory lives in the parents address space.
|
||||
The SHM area is assumed to be of the same length.
|
||||
|
||||
key = <integer> (required)
|
||||
|
||||
This is the key of the unix shared memory area.
|
||||
|
||||
EXAMPLES
|
||||
|
||||
|
||||
Enable tracing of the shm:
|
||||
|
||||
| bash$ psim -t shm-device \
|
||||
|
||||
|
||||
Configure a 512 kilobytes of UNIX shared memory with the key 0x12345678
|
||||
mapped into psim address space at 0x0c000000.
|
||||
|
||||
| -o '/shm@0x0c000000/reg 0x0c000000 0x80000' \
|
||||
| -o '/shm@0x0c000000/key 0x12345678' \
|
||||
|
||||
sim/ppc/run -o '/#address-cells 1' \
|
||||
-o '/shm@0x0c000000/reg 0x0c000000 0x80000' \
|
||||
-o '/shm@0x0c000000/key 0x12345678' ../psim-hello/hello
|
||||
|
||||
BUGS
|
||||
|
||||
None known.
|
||||
|
||||
*/
|
||||
|
||||
typedef struct _hw_shm_device {
|
||||
unsigned_word physical_address;
|
||||
char *shm_address;
|
||||
unsigned sizeof_memory;
|
||||
key_t key;
|
||||
int id;
|
||||
} hw_shm_device;
|
||||
|
||||
static void
|
||||
hw_shm_init_data(device *me)
|
||||
{
|
||||
hw_shm_device *shm = (hw_shm_device*)device_data(me);
|
||||
const device_unit *d;
|
||||
reg_property_spec reg;
|
||||
int i;
|
||||
|
||||
/* Obtain the Key Value */
|
||||
if (device_find_property(me, "key") == NULL)
|
||||
error("shm_init_data() required key property is missing\n");
|
||||
|
||||
shm->key = (key_t) device_find_integer_property(me, "key");
|
||||
DTRACE(shm, ("shm key (0x%08x)\n", shm->key) );
|
||||
|
||||
/* Figure out where this memory is in address space and how long it is */
|
||||
if ( !device_find_reg_array_property(me, "reg", 0, ®) )
|
||||
error("hw_shm_init_data() no address registered\n");
|
||||
|
||||
/* Determine the address and length being as paranoid as possible */
|
||||
shm->physical_address = 0xffffffff;
|
||||
shm->sizeof_memory = 0xffffffff;
|
||||
|
||||
for ( i=0 ; i<reg.address.nr_cells; i++ ) {
|
||||
if (reg.address.cells[0] == 0 && reg.size.cells[0] == 0)
|
||||
continue;
|
||||
|
||||
if ( shm->physical_address != 0xffffffff )
|
||||
device_error(me, "Only single celled address ranges supported\n");
|
||||
|
||||
shm->physical_address = reg.address.cells[i];
|
||||
DTRACE(shm, ("shm physical_address=0x%x\n", shm->physical_address));
|
||||
|
||||
shm->sizeof_memory = reg.size.cells[i];
|
||||
DTRACE(shm, ("shm length=0x%x\n", shm->sizeof_memory));
|
||||
}
|
||||
|
||||
if ( shm->physical_address == 0xffffffff )
|
||||
device_error(me, "Address not specified\n" );
|
||||
|
||||
if ( shm->sizeof_memory == 0xffffffff )
|
||||
device_error(me, "Length not specified\n" );
|
||||
|
||||
/* Now actually attach to or create the shared memory area */
|
||||
shm->id = shmget(shm->key, shm->sizeof_memory, IPC_CREAT | 0660);
|
||||
if (shm->id == -1)
|
||||
error("hw_shm_init_data() shmget failed\n");
|
||||
|
||||
shm->shm_address = shmat(shm->id, (char *)0, SHM_RND);
|
||||
if (shm->shm_address == (void *)-1)
|
||||
error("hw_shm_init_data() shmat failed\n");
|
||||
}
|
||||
|
||||
static void
|
||||
hw_shm_attach_address_callback(device *me,
|
||||
attach_type attach,
|
||||
int space,
|
||||
unsigned_word addr,
|
||||
unsigned nr_bytes,
|
||||
access_type access,
|
||||
device *client) /*callback/default*/
|
||||
{
|
||||
hw_shm_device *shm = (hw_shm_device*)device_data(me);
|
||||
|
||||
if (space != 0)
|
||||
error("shm_attach_address_callback() invalid address space\n");
|
||||
|
||||
if (nr_bytes == 0)
|
||||
error("shm_attach_address_callback() invalid size\n");
|
||||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
hw_shm_io_read_buffer(device *me,
|
||||
void *dest,
|
||||
int space,
|
||||
unsigned_word addr,
|
||||
unsigned nr_bytes,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
hw_shm_device *shm = (hw_shm_device*)device_data(me);
|
||||
|
||||
/* do we need to worry about out of range addresses? */
|
||||
|
||||
DTRACE(shm, ("read %p %x %x %x\n", \
|
||||
shm->shm_address, shm->physical_address, addr, nr_bytes) );
|
||||
|
||||
memcpy(dest, &shm->shm_address[addr - shm->physical_address], nr_bytes);
|
||||
return nr_bytes;
|
||||
}
|
||||
|
||||
|
||||
static unsigned
|
||||
hw_shm_io_write_buffer(device *me,
|
||||
const void *source,
|
||||
int space,
|
||||
unsigned_word addr,
|
||||
unsigned nr_bytes,
|
||||
cpu *processor,
|
||||
unsigned_word cia)
|
||||
{
|
||||
hw_shm_device *shm = (hw_shm_device*)device_data(me);
|
||||
|
||||
/* do we need to worry about out of range addresses? */
|
||||
|
||||
DTRACE(shm, ("write %p %x %x %x\n", \
|
||||
shm->shm_address, shm->physical_address, addr, nr_bytes) );
|
||||
|
||||
memcpy(&shm->shm_address[addr - shm->physical_address], source, nr_bytes);
|
||||
return nr_bytes;
|
||||
}
|
||||
|
||||
static device_callbacks const hw_shm_callbacks = {
|
||||
{ generic_device_init_address, hw_shm_init_data },
|
||||
{ hw_shm_attach_address_callback, }, /* address */
|
||||
{ hw_shm_io_read_buffer,
|
||||
hw_shm_io_write_buffer }, /* IO */
|
||||
{ NULL, }, /* DMA */
|
||||
{ NULL, }, /* interrupt */
|
||||
{ NULL, }, /* unit */
|
||||
NULL,
|
||||
};
|
||||
|
||||
static void *
|
||||
hw_shm_create(const char *name,
|
||||
const device_unit *unit_address,
|
||||
const char *args)
|
||||
{
|
||||
hw_shm_device *shm = ZALLOC(hw_shm_device);
|
||||
return shm;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const device_descriptor hw_shm_device_descriptor[] = {
|
||||
{ "shm", hw_shm_create, &hw_shm_callbacks },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
#endif /* _HW_SHM_C_ */
|
Loading…
Reference in a new issue