citra-emu
/
citra
Archived
1
0
Fork 0

dyncom: Switch the app and system cores into the correct mode at initialization

This commit is contained in:
Lioncash 2015-02-12 15:11:39 -05:00
parent c3211c9c80
commit b7fac494cd
5 changed files with 21 additions and 17 deletions

View File

@ -7,6 +7,7 @@
#include "core/arm/dyncom/arm_dyncom.h" #include "core/arm/dyncom/arm_dyncom.h"
#include "core/arm/dyncom/arm_dyncom_interpreter.h" #include "core/arm/dyncom/arm_dyncom_interpreter.h"
#include "core/arm/dyncom/arm_dyncom_run.h"
#include "core/core.h" #include "core/core.h"
#include "core/core_timing.h" #include "core/core_timing.h"
@ -15,7 +16,7 @@ const static cpu_config_t s_arm11_cpu_info = {
"armv6", "arm11", 0x0007b000, 0x0007f000, NONCACHE "armv6", "arm11", 0x0007b000, 0x0007f000, NONCACHE
}; };
ARM_DynCom::ARM_DynCom() { ARM_DynCom::ARM_DynCom(PrivilegeMode initial_mode) {
state = std::unique_ptr<ARMul_State>(new ARMul_State); state = std::unique_ptr<ARMul_State>(new ARMul_State);
ARMul_NewState(state.get()); ARMul_NewState(state.get());
@ -33,6 +34,9 @@ ARM_DynCom::ARM_DynCom() {
state->NextInstr = RESUME; // NOTE: This will be overwritten by LoadContext state->NextInstr = RESUME; // NOTE: This will be overwritten by LoadContext
state->Emulate = RUN; state->Emulate = RUN;
// Switch to the desired privilege mode.
switch_mode(state.get(), initial_mode);
state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack
state->Reg[15] = 0x00000000; state->Reg[15] = 0x00000000;
} }

View File

@ -13,7 +13,7 @@
class ARM_DynCom final : virtual public ARM_Interface { class ARM_DynCom final : virtual public ARM_Interface {
public: public:
ARM_DynCom(); ARM_DynCom(PrivilegeMode initial_mode);
~ARM_DynCom(); ~ARM_DynCom();
void SetPC(u32 pc) override; void SetPC(u32 pc) override;

View File

@ -2,9 +2,6 @@
// Licensed under GPLv2 or any later version // Licensed under GPLv2 or any later version
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include <assert.h>
#include "common/logging/log.h"
#include "core/arm/skyeye_common/armdefs.h" #include "core/arm/skyeye_common/armdefs.h"
void switch_mode(arm_core_t *core, uint32_t mode) { void switch_mode(arm_core_t *core, uint32_t mode) {
@ -13,6 +10,7 @@ void switch_mode(arm_core_t *core, uint32_t mode) {
if (mode != USERBANK) { if (mode != USERBANK) {
switch (core->Mode) { switch (core->Mode) {
case SYSTEM32MODE: // Shares registers with user mode
case USER32MODE: case USER32MODE:
core->Reg_usr[0] = core->Reg[13]; core->Reg_usr[0] = core->Reg[13];
core->Reg_usr[1] = core->Reg[14]; core->Reg_usr[1] = core->Reg[14];
@ -42,7 +40,6 @@ void switch_mode(arm_core_t *core, uint32_t mode) {
core->Reg_firq[1] = core->Reg[14]; core->Reg_firq[1] = core->Reg[14];
core->Spsr[FIQBANK] = core->Spsr_copy; core->Spsr[FIQBANK] = core->Spsr_copy;
break; break;
} }
switch (mode) { switch (mode) {
@ -81,11 +78,15 @@ void switch_mode(arm_core_t *core, uint32_t mode) {
core->Spsr_copy = core->Spsr[FIQBANK]; core->Spsr_copy = core->Spsr[FIQBANK];
core->Bank = FIQBANK; core->Bank = FIQBANK;
break; break;
case SYSTEM32MODE: // Shares registers with user mode.
core->Reg[13] = core->Reg_usr[0];
core->Reg[14] = core->Reg_usr[1];
core->Bank = SYSTEMBANK;
break;
} }
// Set the mode bits in the APSR
core->Cpsr = (core->Cpsr & ~core->Mode) | mode;
core->Mode = mode; core->Mode = mode;
} else {
LOG_CRITICAL(Core_ARM11, "user mode");
exit(-2);
} }
} }

View File

@ -270,7 +270,7 @@ enum {
* Mode and Bank Constants * * Mode and Bank Constants *
\***************************************************************************/ \***************************************************************************/
enum { enum PrivilegeMode {
USER32MODE = 16, USER32MODE = 16,
FIQ32MODE = 17, FIQ32MODE = 17,
IRQ32MODE = 18, IRQ32MODE = 18,
@ -288,7 +288,7 @@ enum {
ABORTBANK = 4, ABORTBANK = 4,
UNDEFBANK = 5, UNDEFBANK = 5,
DUMMYBANK = 6, DUMMYBANK = 6,
SYSTEMBANK = USERBANK SYSTEMBANK = 7
}; };
/***************************************************************************\ /***************************************************************************\

View File

@ -56,11 +56,10 @@ void Stop() {
/// Initialize the core /// Initialize the core
int Init() { int Init() {
LOG_DEBUG(Core, "initialized OK"); g_sys_core = new ARM_DynCom(USER32MODE);
g_app_core = new ARM_DynCom(USER32MODE);
g_sys_core = new ARM_DynCom();
g_app_core = new ARM_DynCom();
LOG_DEBUG(Core, "Initialized OK");
return 0; return 0;
} }
@ -68,7 +67,7 @@ void Shutdown() {
delete g_app_core; delete g_app_core;
delete g_sys_core; delete g_sys_core;
LOG_DEBUG(Core, "shutdown OK"); LOG_DEBUG(Core, "Shutdown OK");
} }
} // namespace } // namespace