mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-11-27 02:49:42 +00:00
Enable 33-bit memory addressing on 64-bit JIT capable platforms (e.g. x86-64).
This is useful to get rid of address offset sign extensions. It uses POSIX shared memory to create aliased regions, fallback to usual sign-extension way if shm_open et al. don't work (e.g. no /dev/shm mounted)
This commit is contained in:
parent
0ba075050c
commit
e3c5f1769d
@ -126,6 +126,7 @@ fi
|
||||
dnl Checks for libraries.
|
||||
AC_CHECK_LIB(posix4, sem_init)
|
||||
AC_CHECK_LIB(rt, timer_create)
|
||||
AC_CHECK_LIB(rt, shm_open)
|
||||
|
||||
dnl Do we need SDL?
|
||||
WANT_SDL=no
|
||||
@ -702,6 +703,56 @@ AC_CACHE_CHECK([whether we can map Low Memory area 0x0000-0x2000],
|
||||
]
|
||||
)
|
||||
|
||||
dnl Check if we have POSIX shared memory support
|
||||
AC_CACHE_CHECK([whether POSIX shared memory is working],
|
||||
ac_cv_have_posix_shm, [
|
||||
AC_LANG_SAVE
|
||||
AC_LANG_CPLUSPLUS
|
||||
AC_TRY_RUN([
|
||||
#define HAVE_POSIX_SHM
|
||||
#include "vm_alloc.cpp"
|
||||
int main(void) { /* returns 0 if we have working POSIX shm */
|
||||
if (vm_init() < 0) exit(2);
|
||||
char *m1 = (char *)vm_acquire(32768, VM_MAP_DEFAULT | VM_MAP_33BIT);
|
||||
if (m1 == VM_MAP_FAILED) exit(3);
|
||||
vm_exit(); exit(0);
|
||||
}
|
||||
], ac_cv_have_posix_shm=yes, ac_cv_have_posix_shm=no,
|
||||
dnl When cross-compiling, do not assume anything.
|
||||
ac_cv_have_posix_shm="guessing no"
|
||||
)
|
||||
AC_LANG_RESTORE
|
||||
]
|
||||
)
|
||||
AC_TRANSLATE_DEFINE(HAVE_POSIX_SHM, "$ac_cv_have_posix_shm",
|
||||
[Define if your system supports POSIX shared memory.])
|
||||
|
||||
dnl Check if we have working 33-bit memory addressing
|
||||
AC_CACHE_CHECK([whether 33-bit memory addressing is working],
|
||||
ac_cv_have_33bit_addressing, [
|
||||
AC_LANG_SAVE
|
||||
AC_LANG_CPLUSPLUS
|
||||
AC_TRY_RUN([
|
||||
#define USE_33BIT_ADDRESSING 1
|
||||
#include "vm_alloc.cpp"
|
||||
int main(void) { /* returns 0 if we have working 33-bit addressing */
|
||||
if (sizeof(void *) < 8) exit(1);
|
||||
if (vm_init() < 0) exit(2);
|
||||
char *m1 = (char *)vm_acquire(32768, VM_MAP_DEFAULT | VM_MAP_33BIT);
|
||||
if (m1 == VM_MAP_FAILED) exit(3);
|
||||
char *m2 = m1 + (1L << 32);
|
||||
m1[0] = 0x12; if (m2[0] != 0x12) exit(4);
|
||||
m2[0] = 0x34; if (m1[0] != 0x34) exit(5);
|
||||
vm_exit(); exit(0);
|
||||
}
|
||||
], ac_cv_have_33bit_addressing=yes, ac_cv_have_33bit_addressing=no,
|
||||
dnl When cross-compiling, do not assume anything.
|
||||
ac_cv_have_33bit_addressing="guessing no"
|
||||
)
|
||||
AC_LANG_RESTORE
|
||||
]
|
||||
)
|
||||
|
||||
dnl Check signal handlers need to be reinstalled
|
||||
AC_CACHE_CHECK([whether signal handlers need to be reinstalled],
|
||||
ac_cv_signal_need_reinstall, [
|
||||
@ -1028,6 +1079,7 @@ elif [[ "x$HAVE_GCC30" = "xyes" -a "x$HAVE_X86_64" = "xyes" ]]; then
|
||||
DEFINES="$DEFINES -DX86_64_ASSEMBLY -DOPTIMIZED_FLAGS"
|
||||
JITSRCS="cpuemu1_nf.cpp cpuemu2_nf.cpp cpuemu3_nf.cpp cpuemu4_nf.cpp cpuemu5_nf.cpp cpuemu6_nf.cpp cpuemu7_nf.cpp cpuemu8_nf.cpp $JITSRCS"
|
||||
CAN_JIT=yes
|
||||
WANT_33BIT_ADDRESSING=yes
|
||||
fi
|
||||
elif [[ "x$HAVE_GCC27" = "xyes" -a "x$HAVE_SPARC" = "xyes" -a "x$HAVE_GAS" = "xyes" ]]; then
|
||||
dnl SPARC CPU
|
||||
@ -1084,6 +1136,13 @@ else
|
||||
JITSRCS=""
|
||||
fi
|
||||
|
||||
dnl Use 33-bit memory addressing?
|
||||
if [[ "$ac_cv_have_33bit_addressing:$WANT_33BIT_ADDRESSING" = "yes:yes" ]]; then
|
||||
use_33bit_addressing=yes
|
||||
fi
|
||||
AC_TRANSLATE_DEFINE(USE_33BIT_ADDRESSING, "$use_33bit_addressing",
|
||||
[Define to use 33-bit memory addressing on 64-bit JIT capable systems.])
|
||||
|
||||
dnl Utility macro used by next two tests.
|
||||
dnl AC_EXAMINE_OBJECT(C source code,
|
||||
dnl commands examining object file,
|
||||
|
@ -123,6 +123,7 @@ int CPUType;
|
||||
bool CPUIs68060;
|
||||
int FPUType;
|
||||
bool TwentyFourBitAddressing;
|
||||
bool ThirtyThreeBitAddressing = false;
|
||||
|
||||
|
||||
// Global variables
|
||||
@ -218,6 +219,21 @@ char *strdup(const char *s)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Map memory that can be accessed from the Mac side
|
||||
*/
|
||||
|
||||
void *vm_acquire_mac(size_t size)
|
||||
{
|
||||
void *m = vm_acquire(size, VM_MAP_DEFAULT | VM_MAP_33BIT);
|
||||
if (m == NULL) {
|
||||
ThirtyThreeBitAddressing = false;
|
||||
m = vm_acquire(size);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SIGSEGV handler
|
||||
*/
|
||||
@ -482,8 +498,12 @@ int main(int argc, char **argv)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
RAMBaseHost = (uint8 *)vm_acquire(RAMSize);
|
||||
ROMBaseHost = (uint8 *)vm_acquire(0x100000);
|
||||
#ifdef USE_33BIT_ADDRESSING
|
||||
// Speculatively enables 33-bit addressing
|
||||
ThirtyThreeBitAddressing = true;
|
||||
#endif
|
||||
RAMBaseHost = (uint8 *)vm_acquire_mac(RAMSize);
|
||||
ROMBaseHost = (uint8 *)vm_acquire_mac(0x100000);
|
||||
if (RAMBaseHost == VM_MAP_FAILED || ROMBaseHost == VM_MAP_FAILED) {
|
||||
ErrorAlert(STR_NO_MEM_ERR);
|
||||
QuitEmulator();
|
||||
|
@ -192,6 +192,7 @@ static void *redraw_func(void *arg);
|
||||
// From main_unix.cpp
|
||||
extern char *x_display_name;
|
||||
extern Display *x_display;
|
||||
extern void *vm_acquire_mac(size_t size);
|
||||
|
||||
// From sys_unix.cpp
|
||||
extern void SysMountFirstFloppy(void);
|
||||
@ -730,7 +731,7 @@ driver_window::driver_window(X11_monitor_desc &m)
|
||||
// Allocate memory for frame buffer (SIZE is extended to page-boundary)
|
||||
the_host_buffer = the_buffer_copy;
|
||||
the_buffer_size = page_extend((aligned_height + 2) * img->bytes_per_line);
|
||||
the_buffer = (uint8 *)vm_acquire(the_buffer_size);
|
||||
the_buffer = (uint8 *)vm_acquire_mac(the_buffer_size);
|
||||
the_buffer_copy = (uint8 *)malloc(the_buffer_size);
|
||||
D(bug("the_buffer = %p, the_buffer_copy = %p, the_host_buffer = %p\n", the_buffer, the_buffer_copy, the_host_buffer));
|
||||
#else
|
||||
@ -1126,7 +1127,7 @@ driver_fbdev::driver_fbdev(X11_monitor_desc &m) : driver_dga(m)
|
||||
the_host_buffer = the_buffer;
|
||||
the_buffer_size = page_extend((height + 2) * bytes_per_row);
|
||||
the_buffer_copy = (uint8 *)malloc(the_buffer_size);
|
||||
the_buffer = (uint8 *)vm_acquire(the_buffer_size);
|
||||
the_buffer = (uint8 *)vm_acquire_mac(the_buffer_size);
|
||||
}
|
||||
#else
|
||||
use_vosf = false;
|
||||
@ -1266,7 +1267,7 @@ driver_xf86dga::driver_xf86dga(X11_monitor_desc &m)
|
||||
the_host_buffer = the_buffer;
|
||||
the_buffer_size = page_extend((height + 2) * bytes_per_row);
|
||||
the_buffer_copy = (uint8 *)malloc(the_buffer_size);
|
||||
the_buffer = (uint8 *)vm_acquire(the_buffer_size);
|
||||
the_buffer = (uint8 *)vm_acquire_mac(the_buffer_size);
|
||||
}
|
||||
#else
|
||||
use_vosf = false;
|
||||
|
@ -23,9 +23,15 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
// TODO: Win32 VMs ?
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include "vm_alloc.h"
|
||||
|
||||
#ifdef HAVE_MACH_VM
|
||||
@ -45,6 +51,12 @@
|
||||
#ifndef MAP_32BIT
|
||||
#define MAP_32BIT 0
|
||||
#endif
|
||||
#ifndef MAP_ANON
|
||||
#define MAP_ANON 0
|
||||
#endif
|
||||
#ifndef MAP_ANONYMOUS
|
||||
#define MAP_ANONYMOUS 0
|
||||
#endif
|
||||
|
||||
#define MAP_EXTRA_FLAGS (MAP_32BIT)
|
||||
|
||||
@ -66,15 +78,83 @@ static char * next_address = (char *)MAP_BASE;
|
||||
#define map_flags (MAP_ANONYMOUS | MAP_EXTRA_FLAGS)
|
||||
#define zero_fd -1
|
||||
#else
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#define map_flags (MAP_EXTRA_FLAGS)
|
||||
static int zero_fd = -1;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Utility functions for POSIX SHM handling. */
|
||||
|
||||
#ifdef USE_33BIT_ADDRESSING
|
||||
struct shm_range_t {
|
||||
const char *file;
|
||||
void *base;
|
||||
unsigned int size;
|
||||
shm_range_t *next;
|
||||
};
|
||||
|
||||
static shm_range_t *shm_ranges = NULL;
|
||||
|
||||
static bool add_shm_range(const char *file, void *base, unsigned int size)
|
||||
{
|
||||
shm_range_t *r = (shm_range_t *)malloc(sizeof(shm_range_t));
|
||||
if (r) {
|
||||
r->file = file;
|
||||
r->base = base;
|
||||
r->size = size;
|
||||
r->next = shm_ranges ? shm_ranges : NULL;
|
||||
shm_ranges = r;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static shm_range_t *find_shm_range(void *base, unsigned int size)
|
||||
{
|
||||
for (shm_range_t *r = shm_ranges; r != NULL; r = r->next)
|
||||
if (r->base == base && r->size == size)
|
||||
return r;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool remove_shm_range(shm_range_t *r)
|
||||
{
|
||||
if (r) {
|
||||
for (shm_range_t *p = shm_ranges; p != NULL; p = p->next) {
|
||||
if (p->next == r) {
|
||||
p->next = r->next;
|
||||
free(r);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool remove_shm_range(void *base, unsigned int size)
|
||||
{
|
||||
remove_shm_range(find_shm_range(base, size));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Build a POSIX SHM memory segment file descriptor name. */
|
||||
|
||||
#ifdef USE_33BIT_ADDRESSING
|
||||
static const char *build_shm_filename(void)
|
||||
{
|
||||
static int id = 0;
|
||||
static char filename[PATH_MAX];
|
||||
|
||||
int ret = snprintf(filename, sizeof(filename), "/BasiliskII-%d-shm-%d", getpid(), id);
|
||||
if (ret == -1 || ret >= sizeof(filename))
|
||||
return NULL;
|
||||
|
||||
id++;
|
||||
return filename;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Translate generic VM map flags to host values. */
|
||||
|
||||
#ifdef HAVE_MMAP_VM
|
||||
@ -136,9 +216,29 @@ void * vm_acquire(size_t size, int options)
|
||||
return VM_MAP_FAILED;
|
||||
#else
|
||||
#ifdef HAVE_MMAP_VM
|
||||
const int extra_map_flags = translate_map_flags(options);
|
||||
int fd = zero_fd;
|
||||
int the_map_flags = translate_map_flags(options) | map_flags;
|
||||
|
||||
if ((addr = mmap((caddr_t)next_address, size, VM_PAGE_DEFAULT, extra_map_flags | map_flags, zero_fd, 0)) == (void *)MAP_FAILED)
|
||||
#ifdef USE_33BIT_ADDRESSING
|
||||
const char *shm_file = NULL;
|
||||
if (sizeof(void *) == 8 && (options & VM_MAP_33BIT)) {
|
||||
the_map_flags &= ~(MAP_PRIVATE | MAP_ANON | MAP_ANONYMOUS);
|
||||
the_map_flags |= MAP_SHARED;
|
||||
|
||||
if ((shm_file = build_shm_filename()) == NULL)
|
||||
return VM_MAP_FAILED;
|
||||
|
||||
if ((fd = shm_open(shm_file, O_RDWR | O_CREAT | O_EXCL, 0644)) < 0)
|
||||
return VM_MAP_FAILED;
|
||||
|
||||
if (ftruncate(fd, size) < 0)
|
||||
return VM_MAP_FAILED;
|
||||
|
||||
the_map_flags |= MAP_SHARED;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((addr = mmap((caddr_t)next_address, size, VM_PAGE_DEFAULT, the_map_flags, fd, 0)) == (void *)MAP_FAILED)
|
||||
return VM_MAP_FAILED;
|
||||
|
||||
// Sanity checks for 64-bit platforms
|
||||
@ -150,6 +250,18 @@ void * vm_acquire(size_t size, int options)
|
||||
// Since I don't know the standard behavior of mmap(), zero-fill here
|
||||
if (memset(addr, 0, size) != addr)
|
||||
return VM_MAP_FAILED;
|
||||
|
||||
// Remap to 33-bit space
|
||||
#ifdef USE_33BIT_ADDRESSING
|
||||
if (sizeof(void *) == 8 && (options & VM_MAP_33BIT)) {
|
||||
if (!add_shm_range(strdup(shm_file), addr, size))
|
||||
return VM_MAP_FAILED;
|
||||
|
||||
if (mmap((char *)addr + (1L << 32), size, VM_PAGE_DEFAULT, the_map_flags | MAP_FIXED, fd, 0) == (void *)MAP_FAILED)
|
||||
return VM_MAP_FAILED;
|
||||
close(fd);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
if ((addr = calloc(size, 1)) == 0)
|
||||
return VM_MAP_FAILED;
|
||||
@ -220,6 +332,21 @@ int vm_release(void * addr, size_t size)
|
||||
#ifdef HAVE_MMAP_VM
|
||||
if (munmap((caddr_t)addr, size) != 0)
|
||||
return -1;
|
||||
|
||||
#ifdef USE_33BIT_ADDRESSING
|
||||
shm_range_t *r = find_shm_range(addr, size);
|
||||
if (r) {
|
||||
if (munmap((char *)r->base + (1L << 32), size) != 0)
|
||||
return -1;
|
||||
|
||||
if (shm_unlink(r->file) < 0)
|
||||
return -1;
|
||||
free((char *)r->file);
|
||||
|
||||
if (!remove_shm_range(r))
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
free(addr);
|
||||
#endif
|
||||
|
@ -52,6 +52,7 @@ extern "C" {
|
||||
#define VM_MAP_PRIVATE 0x02
|
||||
#define VM_MAP_FIXED 0x04
|
||||
#define VM_MAP_32BIT 0x08
|
||||
#define VM_MAP_33BIT 0x10
|
||||
|
||||
/* Default mapping options. */
|
||||
#define VM_MAP_DEFAULT (VM_MAP_PRIVATE)
|
||||
|
Loading…
Reference in New Issue
Block a user