mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-01-17 04:30:18 +00:00
Use an alternate stack base while servicing PowerPC interrupts.
This commit is contained in:
parent
c3bb2eabf1
commit
bbde2a2054
@ -204,7 +204,9 @@ static bool ready_for_signals = false; // Handler installed, signals can be sen
|
||||
static int64 num_segv = 0; // Number of handled SEGV signals
|
||||
|
||||
static struct sigaction sigusr2_action; // Interrupt signal (of emulator thread)
|
||||
#if !EMULATED_PPC
|
||||
#if EMULATED_PPC
|
||||
static uintptr sig_stack = 0; // Stack for PowerPC interrupt routine
|
||||
#else
|
||||
static struct sigaction sigsegv_action; // Data access exception signal (of emulator thread)
|
||||
static struct sigaction sigill_action; // Illegal instruction signal (of emulator thread)
|
||||
static void *sig_stack = NULL; // Stack for signal handlers
|
||||
@ -252,6 +254,16 @@ extern void paranoia_check(void);
|
||||
|
||||
|
||||
#if EMULATED_PPC
|
||||
/*
|
||||
* Return signal stack base
|
||||
*/
|
||||
|
||||
uintptr SignalStackBase(void)
|
||||
{
|
||||
return sig_stack + SIG_STACK_SIZE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Atomic operations
|
||||
*/
|
||||
@ -1773,18 +1785,27 @@ rti:;
|
||||
|
||||
bool SheepMem::Init(void)
|
||||
{
|
||||
const int page_size = getpagesize();
|
||||
|
||||
// Allocate SheepShaver globals
|
||||
if (vm_acquire_fixed((char *)base, size) < 0)
|
||||
return false;
|
||||
|
||||
// Allocate page with all bits set to 0
|
||||
zero_page = base + size;
|
||||
|
||||
int page_size = getpagesize();
|
||||
if (vm_acquire_fixed((char *)zero_page, page_size) < 0)
|
||||
return false;
|
||||
memset((char *)zero_page, 0, page_size);
|
||||
if (vm_protect((char *)zero_page, page_size, VM_PAGE_READ) < 0)
|
||||
return false;
|
||||
|
||||
#if EMULATED_PPC
|
||||
// Allocate alternate stack for PowerPC interrupt routine
|
||||
sig_stack = zero_page + page_size;
|
||||
if (vm_acquire_fixed((char *)sig_stack, SIG_STACK_SIZE) < 0)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
top = base + size;
|
||||
return true;
|
||||
}
|
||||
@ -1792,8 +1813,18 @@ bool SheepMem::Init(void)
|
||||
void SheepMem::Exit(void)
|
||||
{
|
||||
if (top) {
|
||||
// The zero page is next to SheepShaver globals
|
||||
vm_release((void *)base, size + getpagesize());
|
||||
const int page_size = getpagesize();
|
||||
|
||||
// Delete SheepShaver globals
|
||||
vm_release((void *)base, size);
|
||||
|
||||
// Delete zero page
|
||||
vm_release((void *)zero_page, page_size);
|
||||
|
||||
#if EMULATED_PPC
|
||||
// Delete alternate stack for PowerPC interrupt routine
|
||||
vm_release((void *)sig_stack, SIG_STACK_SIZE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,6 +73,9 @@ static void enter_mon(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
// From main_*.cpp
|
||||
extern uintptr SignalStackBase();
|
||||
|
||||
// PowerPC EmulOp to exit from emulation looop
|
||||
const uint32 POWERPC_EXEC_RETURN = POWERPC_EMUL_OP | 1;
|
||||
|
||||
@ -268,8 +271,7 @@ void sheepshaver_cpu::interrupt(uint32 entry)
|
||||
#endif
|
||||
|
||||
// Initialize stack pointer to SheepShaver alternate stack base
|
||||
SheepArray<64> stack_area;
|
||||
gpr(1) = stack_area.addr();
|
||||
gpr(1) = SignalStackBase() - 64;
|
||||
|
||||
// Build trampoline to return from interrupt
|
||||
SheepVar32 trampoline = POWERPC_EXEC_RETURN;
|
||||
|
Loading…
x
Reference in New Issue
Block a user