| 31 |
#include "cpu/ppc/ppc-cpu.hpp" |
#include "cpu/ppc/ppc-cpu.hpp" |
| 32 |
#include "cpu/ppc/ppc-operations.hpp" |
#include "cpu/ppc/ppc-operations.hpp" |
| 33 |
#include "cpu/ppc/ppc-instructions.hpp" |
#include "cpu/ppc/ppc-instructions.hpp" |
| 34 |
|
#include "thunks.h" |
| 35 |
|
|
| 36 |
// Used for NativeOp trampolines |
// Used for NativeOp trampolines |
| 37 |
#include "video.h" |
#include "video.h" |
| 73 |
#endif |
#endif |
| 74 |
} |
} |
| 75 |
|
|
| 76 |
|
// PowerPC EmulOp to exit from emulation looop |
| 77 |
|
const uint32 POWERPC_EXEC_RETURN = POWERPC_EMUL_OP | 1; |
| 78 |
|
|
| 79 |
// Enable multicore (main/interrupts) cpu emulation? |
// Enable multicore (main/interrupts) cpu emulation? |
| 80 |
#define MULTICORE_CPU (ASYNC_IRQ ? 1 : 0) |
#define MULTICORE_CPU (ASYNC_IRQ ? 1 : 0) |
| 81 |
|
|
| 268 |
#endif |
#endif |
| 269 |
|
|
| 270 |
// Initialize stack pointer to SheepShaver alternate stack base |
// Initialize stack pointer to SheepShaver alternate stack base |
| 271 |
gpr(1) = SheepStack1Base - 64; |
SheepArray<64> stack_area; |
| 272 |
|
gpr(1) = stack_area.addr(); |
| 273 |
|
|
| 274 |
// Build trampoline to return from interrupt |
// Build trampoline to return from interrupt |
| 275 |
uint32 trampoline[] = { htonl(POWERPC_EMUL_OP | 1) }; |
SheepVar32 trampoline = POWERPC_EXEC_RETURN; |
| 276 |
|
|
| 277 |
// Prepare registers for nanokernel interrupt routine |
// Prepare registers for nanokernel interrupt routine |
| 278 |
kernel_data->v[0x004 >> 2] = htonl(gpr(1)); |
kernel_data->v[0x004 >> 2] = htonl(gpr(1)); |
| 291 |
gpr(1) = KernelDataAddr; |
gpr(1) = KernelDataAddr; |
| 292 |
gpr(7) = ntohl(kernel_data->v[0x660 >> 2]); |
gpr(7) = ntohl(kernel_data->v[0x660 >> 2]); |
| 293 |
gpr(8) = 0; |
gpr(8) = 0; |
| 294 |
gpr(10) = (uint32)trampoline; |
gpr(10) = trampoline.addr(); |
| 295 |
gpr(12) = (uint32)trampoline; |
gpr(12) = trampoline.addr(); |
| 296 |
gpr(13) = get_cr(); |
gpr(13) = get_cr(); |
| 297 |
|
|
| 298 |
// rlwimi. r7,r7,8,0,0 |
// rlwimi. r7,r7,8,0,0 |
| 429 |
uint32 saved_ctr= ctr(); |
uint32 saved_ctr= ctr(); |
| 430 |
|
|
| 431 |
// Build trampoline with EXEC_RETURN |
// Build trampoline with EXEC_RETURN |
| 432 |
uint32 trampoline[] = { htonl(POWERPC_EMUL_OP | 1) }; |
SheepVar32 trampoline = POWERPC_EXEC_RETURN; |
| 433 |
lr() = (uint32)trampoline; |
lr() = trampoline.addr(); |
| 434 |
|
|
| 435 |
gpr(1) -= 64; // Create stack frame |
gpr(1) -= 64; // Create stack frame |
| 436 |
uint32 proc = ReadMacInt32(tvect); // Get routine address |
uint32 proc = ReadMacInt32(tvect); // Get routine address |
| 474 |
// Save branch registers |
// Save branch registers |
| 475 |
uint32 saved_lr = lr(); |
uint32 saved_lr = lr(); |
| 476 |
|
|
| 477 |
const uint32 trampoline[] = { htonl(POWERPC_EMUL_OP | 1) }; |
SheepVar32 trampoline = POWERPC_EXEC_RETURN; |
| 478 |
lr() = (uint32)trampoline; |
WriteMacInt32(trampoline.addr(), POWERPC_EXEC_RETURN); |
| 479 |
|
lr() = trampoline.addr(); |
| 480 |
|
|
| 481 |
execute(entry); |
execute(entry); |
| 482 |
|
|
| 794 |
} |
} |
| 795 |
} |
} |
| 796 |
|
|
|
/* |
|
|
* Execute NATIVE_OP opcode (called by PowerPC emulator) |
|
|
*/ |
|
|
|
|
|
#define POWERPC_NATIVE_OP_INIT(LR, OP) \ |
|
|
tswap32(POWERPC_EMUL_OP | ((LR) << 11) | (((uint32)OP) << 6) | 2) |
|
|
|
|
|
// FIXME: Make sure 32-bit relocations are used |
|
|
const uint32 NativeOpTable[NATIVE_OP_MAX] = { |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_PATCH_NAME_REGISTRY), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_VIDEO_INSTALL_ACCEL), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_VIDEO_VBL), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_VIDEO_DO_DRIVER_IO), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_ETHER_IRQ), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_ETHER_INIT), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_ETHER_TERM), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_ETHER_OPEN), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_ETHER_CLOSE), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_ETHER_WPUT), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_ETHER_RSRV), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_SERIAL_NOTHING), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_SERIAL_OPEN), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_SERIAL_PRIME_IN), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_SERIAL_PRIME_OUT), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_SERIAL_CONTROL), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_SERIAL_STATUS), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_SERIAL_CLOSE), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_GET_RESOURCE), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_GET_1_RESOURCE), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_GET_IND_RESOURCE), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_GET_1_IND_RESOURCE), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_R_GET_RESOURCE), |
|
|
POWERPC_NATIVE_OP_INIT(0, NATIVE_DISABLE_INTERRUPT), |
|
|
POWERPC_NATIVE_OP_INIT(0, NATIVE_ENABLE_INTERRUPT), |
|
|
POWERPC_NATIVE_OP_INIT(1, NATIVE_MAKE_EXECUTABLE), |
|
|
}; |
|
|
|
|
| 797 |
static void get_resource(void); |
static void get_resource(void); |
| 798 |
static void get_1_resource(void); |
static void get_1_resource(void); |
| 799 |
static void get_ind_resource(void); |
static void get_ind_resource(void); |
| 913 |
|
|
| 914 |
void ExecuteNative(int selector) |
void ExecuteNative(int selector) |
| 915 |
{ |
{ |
| 916 |
uint32 tvect[2]; |
SheepRoutineDescriptor desc(0, NativeTVECT(selector)); |
|
tvect[0] = tswap32(POWERPC_NATIVE_OP_FUNC(selector)); |
|
|
tvect[1] = 0; // Fake TVECT |
|
|
RoutineDescriptor desc = BUILD_PPC_ROUTINE_DESCRIPTOR(0, tvect); |
|
| 917 |
M68kRegisters r; |
M68kRegisters r; |
| 918 |
Execute68k((uint32)&desc, &r); |
Execute68k(desc.addr(), &r); |
| 919 |
} |
} |
| 920 |
|
|
| 921 |
/* |
/* |
| 936 |
|
|
| 937 |
void Execute68kTrap(uint16 trap, M68kRegisters *r) |
void Execute68kTrap(uint16 trap, M68kRegisters *r) |
| 938 |
{ |
{ |
| 939 |
uint16 proc[2]; |
SheepVar proc_var(4); |
| 940 |
proc[0] = htons(trap); |
uint32 proc = proc_var.addr(); |
| 941 |
proc[1] = htons(M68K_RTS); |
WriteMacInt16(proc, trap); |
| 942 |
Execute68k((uint32)proc, r); |
WriteMacInt16(proc + 2, M68K_RTS); |
| 943 |
|
Execute68k(proc, r); |
| 944 |
} |
} |
| 945 |
|
|
| 946 |
/* |
/* |