Recognize Intel Compilers. Add user mode network stack with slirp from qemu.

Simply use "ether slirp" in the prefs file, no kernel module required. I
could perform up to 450 KB/sec on my DSL line.
This commit is contained in:
gbeauche 2005-05-13 09:21:21 +00:00
parent 5fffe6e2cd
commit 20fcf38e30
3 changed files with 186 additions and 22 deletions

View File

@ -19,7 +19,7 @@ CC = @CC@
CXX = @CXX@
CFLAGS = @CFLAGS@
CXXFLAGS = @CXXFLAGS@
CPPFLAGS = @CPPFLAGS@ -I../include -I. @CPUINCLUDES@
CPPFLAGS = @CPPFLAGS@ -I../include -I. @CPUINCLUDES@ -I../slirp
DEFS = @DEFS@ @DEFINES@ -D_REENTRANT -DDATADIR=\"$(datadir)/$(APP)\"
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
@ -31,6 +31,16 @@ INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ -s
INSTALL_DATA = @INSTALL_DATA@
SLIRP_CFLAGS = @SLIRP_CFLAGS@
SLIRP_SRCS = \
../slirp/bootp.c ../slirp/ip_output.c ../slirp/tcp_input.c \
../slirp/cksum.c ../slirp/mbuf.c ../slirp/tcp_output.c \
../slirp/debug.c ../slirp/misc.c ../slirp/tcp_subr.c \
../slirp/if.c ../slirp/sbuf.c ../slirp/tcp_timer.c \
../slirp/ip_icmp.c ../slirp/slirp.c ../slirp/tftp.c \
../slirp/ip_input.c ../slirp/socket.c ../slirp/udp.c
SLIRP_OBJS = $(SLIRP_SRCS:../slirp/%.c=obj/%.o)
## Files
SRCS = ../main.cpp main_unix.cpp ../prefs.cpp ../prefs_items.cpp prefs_unix.cpp \
sys_unix.cpp ../rom_patches.cpp ../slot_rom.cpp ../rsrc_patches.cpp \
@ -39,7 +49,7 @@ SRCS = ../main.cpp main_unix.cpp ../prefs.cpp ../prefs_items.cpp prefs_unix.cpp
../sony.cpp ../disk.cpp ../cdrom.cpp ../scsi.cpp ../video.cpp video_blit.cpp \
vm_alloc.cpp sigsegv.cpp ../audio.cpp ../extfs.cpp extfs_unix.cpp \
../user_strings.cpp user_strings_unix.cpp sshpty.c strlcpy.c \
$(SYSSRCS) $(CPUSRCS)
$(SYSSRCS) $(CPUSRCS) $(SLIRP_SRCS)
APP = BasiliskII
## Rules
@ -104,6 +114,8 @@ distclean: clean
depend dep:
makedepend $(CPPFLAGS) -Y. $(SRCS) 2>/dev/null
$(OBJ_DIR)/%.o : ../slirp/%.c
$(CC) $(CPPFLAGS) $(DEFS) $(SLIRP_CFLAGS) -c $< -o $@
$(OBJ_DIR)/%.o : %.c
$(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) -c $< -o $@
$(OBJ_DIR)/%.o : %.cpp

View File

@ -275,7 +275,8 @@ dnl Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS(unistd.h fcntl.h sys/types.h sys/time.h sys/mman.h mach/mach.h)
AC_CHECK_HEADERS(readline.h history.h readline/readline.h readline/history.h)
AC_CHECK_HEADERS(sys/socket.h)
AC_CHECK_HEADERS(sys/socket.h sys/ioctl.h sys/filio.h sys/bitypes.h sys/wait.h sys/select.h)
AC_CHECK_HEADERS(arpa/inet.h)
AC_CHECK_HEADERS(linux/if.h linux/if_tun.h net/if.h net/if_tun.h, [], [], [
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
@ -321,11 +322,12 @@ if [[ "x$ac_cv_type_socklen_t" != "xyes" ]]; then
fi
dnl Checks for library functions.
AC_CHECK_FUNCS(strdup cfmakeraw)
AC_CHECK_FUNCS(strdup strerror cfmakeraw)
AC_CHECK_FUNCS(clock_gettime timer_create)
AC_CHECK_FUNCS(sigaction signal)
AC_CHECK_FUNCS(mmap mprotect munmap)
AC_CHECK_FUNCS(vm_allocate vm_deallocate vm_protect)
AC_CHECK_FUNCS(inet_aton)
dnl Darwin seems to define mach_task_self() instead of task_self().
AC_CHECK_FUNCS(mach_task_self task_self)
@ -1063,6 +1065,14 @@ AC_EGREP_CPP(xyes,
#endif
], [AC_MSG_RESULT(yes); HAVE_GCC30=yes], AC_MSG_RESULT(no))
dnl Check for ICC.
AC_MSG_CHECKING(for ICC)
HAVE_ICC=no
if $CXX -V -v 2>&1 | grep -q "Intel(R) C++ Compiler"; then
HAVE_ICC=yes
fi
AC_MSG_RESULT($HAVE_ICC)
dnl Set "-fomit-frame-pointer" on i386 GCC 2.7 or higher.
dnl Also set "-fno-exceptions" for C++ because exception handling requires
dnl the frame pointer.
@ -1076,7 +1086,7 @@ dnl As of 2001/08/02, this affects the following compilers:
dnl Official: probably gcc-3.1 (mainline CVS)
dnl Mandrake: gcc-2.96 >= 0.59mdk, gcc-3.0.1 >= 0.1mdk
dnl Red Hat : gcc-2.96 >= 89, gcc-3.0 >= 1
if [[ "x$HAVE_GCC27" = "xyes" ]]; then
if [[ "x$HAVE_GCC27" = "xyes" -a "x$HAVE_ICC" = "xno" ]]; then
SAVED_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS -fno-merge-constants"
AC_CACHE_CHECK([whether GCC supports constants merging], ac_cv_gcc_constants_merging, [
@ -1092,7 +1102,7 @@ fi
dnl Store motion was introduced in 3.3-hammer branch and any gcc >= 3.4
dnl However, there are some corner cases exposed on x86-64
if [[ "x$HAVE_GCC27" = "xyes" ]]; then
if [[ "x$HAVE_GCC27" = "xyes" -a "x$HAVE_ICC" = "xno" ]]; then
SAVED_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS -fno-gcse-sm"
AC_CACHE_CHECK([whether GCC supports store motion], ac_cv_gcc_store_motion, [
@ -1106,6 +1116,19 @@ if [[ "x$HAVE_GCC27" = "xyes" ]]; then
fi
fi
dnl Add -fno-strict-aliasing for slirp sources
if [[ "x$HAVE_GCC30" = "xyes" ]]; then
SAVED_CXXFLAGS="$CXXFLAGS"
CFLAGS="$CFLAGS -fno-strict-aliasing"
AC_CACHE_CHECK([whether the compiler supports -fno-strict-aliasing],
ac_cv_gcc_no_strict_aliasing, [
AC_TRY_COMPILE([],[],
[ac_cv_gcc_no_strict_aliasing=yes; AC_SUBST(SLIRP_CFLAGS, "$CFLAGS")],
[ac_cv_gcc_no_strict_aliasing=no])
])
CFLAGS="$SAVED_CFLAGS"
fi
dnl Select appropriate CPU source and REGPARAM define.
ASM_OPTIMIZATIONS=none
CPUSRCS="cpuemu1.cpp cpuemu2.cpp cpuemu3.cpp cpuemu4.cpp cpuemu5.cpp cpuemu6.cpp cpuemu7.cpp cpuemu8.cpp"

View File

@ -45,6 +45,11 @@
#include <net/if_tun.h>
#endif
// XXX: slirp is currently not 64-bit clean
#if SIZEOF_VOID_P == 4
#define HAVE_SLIRP 1
#endif
#include "cpu_emulation.h"
#include "main.h"
#include "macos_util.h"
@ -52,6 +57,7 @@
#include "user_strings.h"
#include "ether.h"
#include "ether_defs.h"
#include "libslirp.h"
#ifndef NO_STD_NAMESPACE
using std::map;
@ -68,6 +74,7 @@ enum {
NET_IF_SHEEPNET,
NET_IF_ETHERTAP,
NET_IF_TUNTAP,
NET_IF_SLIRP
};
// Constants
@ -83,12 +90,16 @@ static bool udp_tunnel; // Flag: UDP tunnelling active, fd is the socket de
static int net_if_type = -1; // Ethernet device type
static char *net_if_name = NULL; // TUN/TAP device name
static const char *net_if_script = NULL; // Network config script
static pthread_t slirp_thread; // Slirp reception thread
static bool slirp_thread_active = false; // Flag: Slirp reception threadinstalled
static int slirp_output_fd = -1; // fd of slirp output pipe
// Attached network protocols, maps protocol type to MacOS handler address
static map<uint16, uint32> net_protocols;
// Prototypes
static void *receive_func(void *arg);
static void *slirp_receive_func(void *arg);
/*
@ -109,6 +120,16 @@ static bool start_thread(void)
return false;
}
#ifdef HAVE_SLIRP
if (net_if_type == NET_IF_SLIRP) {
slirp_thread_active = (pthread_create(&slirp_thread, NULL, slirp_receive_func, NULL) == 0);
if (!slirp_thread_active) {
printf("WARNING: Cannot start slirp reception thread\n");
return false;
}
}
#endif
return true;
}
@ -119,6 +140,14 @@ static bool start_thread(void)
static void stop_thread(void)
{
#ifdef HAVE_SLIRP
if (slirp_thread_active) {
pthread_cancel(slirp_thread);
pthread_join(slirp_thread, NULL);
slirp_thread_active = false;
}
#endif
if (thread_active) {
pthread_cancel(ether_thread);
pthread_join(ether_thread, NULL);
@ -178,10 +207,28 @@ bool ether_init(void)
#if ENABLE_TUNTAP
else if (strcmp(name, "tun") == 0)
net_if_type = NET_IF_TUNTAP;
#endif
#ifdef HAVE_SLIRP
else if (strcmp(name, "slirp") == 0)
net_if_type = NET_IF_SLIRP;
#endif
else
net_if_type = NET_IF_SHEEPNET;
#ifdef HAVE_SLIRP
// Initialize slirp library
if (net_if_type == NET_IF_SLIRP) {
slirp_init();
// Open slirp output pipe
int fds[2];
if (pipe(fds) < 0)
return false;
fd = fds[0];
slirp_output_fd = fds[1];
}
#endif
// Open sheep_net or ethertap or TUN/TAP device
char dev_name[16];
switch (net_if_type) {
@ -195,11 +242,13 @@ bool ether_init(void)
strcpy(dev_name, "/dev/sheep_net");
break;
}
fd = open(dev_name, O_RDWR);
if (fd < 0) {
sprintf(str, GetString(STR_NO_SHEEP_NET_DRIVER_WARN), dev_name, strerror(errno));
WarningAlert(str);
goto open_error;
if (net_if_type != NET_IF_SLIRP) {
fd = open(dev_name, O_RDWR);
if (fd < 0) {
sprintf(str, GetString(STR_NO_SHEEP_NET_DRIVER_WARN), dev_name, strerror(errno));
WarningAlert(str);
goto open_error;
}
}
#if ENABLE_TUNTAP
@ -257,6 +306,15 @@ bool ether_init(void)
ether_addr[3] = p >> 16;
ether_addr[4] = p >> 8;
ether_addr[5] = p;
#ifdef HAVE_SLIRP
} else if (net_if_type == NET_IF_SLIRP) {
ether_addr[0] = 0x52;
ether_addr[1] = 0x54;
ether_addr[2] = 0x00;
ether_addr[3] = 0x12;
ether_addr[4] = 0x34;
ether_addr[5] = 0x56;
#endif
} else
ioctl(fd, SIOCGIFADDR, ether_addr);
D(bug("Ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
@ -275,6 +333,10 @@ open_error:
close(fd);
fd = -1;
}
if (slirp_output_fd >= 0) {
close(slirp_output_fd);
slirp_output_fd = -1;
}
return false;
}
@ -304,6 +366,10 @@ void ether_exit(void)
// Close sheep_net device
if (fd > 0)
close(fd);
// Close slirp output buffer
if (slirp_output_fd > 0)
close(slirp_output_fd);
}
@ -323,14 +389,19 @@ void ether_reset(void)
int16 ether_add_multicast(uint32 pb)
{
if (net_if_type != NET_IF_TUNTAP && ioctl(fd, SIOCADDMULTI, Mac2HostAddr(pb + eMultiAddr)) < 0) {
D(bug("WARNING: Couldn't enable multicast address\n"));
if (net_if_type == NET_IF_ETHERTAP)
return noErr;
else
return eMultiErr;
} else
switch (net_if_type) {
case NET_IF_ETHERTAP:
case NET_IF_SHEEPNET:
if (ioctl(fd, SIOCADDMULTI, Mac2HostAddr(pb + eMultiAddr)) < 0) {
D(bug("WARNING: Couldn't enable multicast address\n"));
if (net_if_type == NET_IF_ETHERTAP)
return noErr;
else
return eMultiErr;
}
default:
return noErr;
}
}
@ -340,11 +411,16 @@ int16 ether_add_multicast(uint32 pb)
int16 ether_del_multicast(uint32 pb)
{
if (net_if_type != NET_IF_TUNTAP && ioctl(fd, SIOCDELMULTI, Mac2HostAddr(pb + eMultiAddr)) < 0) {
D(bug("WARNING: Couldn't disable multicast address\n"));
return eMultiErr;
} else
switch (net_if_type) {
case NET_IF_ETHERTAP:
case NET_IF_SHEEPNET:
if (ioctl(fd, SIOCDELMULTI, Mac2HostAddr(pb + eMultiAddr)) < 0) {
D(bug("WARNING: Couldn't disable multicast address\n"));
return eMultiErr;
}
default:
return noErr;
}
}
@ -400,6 +476,12 @@ int16 ether_write(uint32 wds)
#endif
// Transmit packet
#ifdef HAVE_SLIRP
if (net_if_type == NET_IF_SLIRP) {
slirp_input(packet, len);
return noErr;
} else
#endif
if (write(fd, packet, len) < 0) {
D(bug("WARNING: Couldn't transmit packet\n"));
return excessCollsns;
@ -431,6 +513,53 @@ void ether_stop_udp_thread(void)
}
/*
* SLIRP output buffer glue
*/
#ifdef HAVE_SLIRP
int slirp_can_output(void)
{
return 1;
}
void slirp_output(const uint8 *packet, int len)
{
write(slirp_output_fd, packet, len);
}
void *slirp_receive_func(void *arg)
{
for (;;) {
// Wait for packets to arrive
fd_set rfds, wfds, xfds;
int nfds;
struct timeval tv;
nfds = -1;
FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_ZERO(&xfds);
slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
tv.tv_sec = 0;
tv.tv_usec = 16667;
if (select(nfds + 1, &rfds, &wfds, &xfds, &tv) >= 0)
slirp_select_poll(&rfds, &wfds, &xfds);
}
return NULL;
}
#else
int slirp_can_output(void)
{
return 0;
}
void slirp_output(const uint8 *packet, int len)
{
}
#endif
/*
* Packet reception thread
*/