mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-11-20 15:31:22 +00:00
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:
parent
5fffe6e2cd
commit
20fcf38e30
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user